diff --git a/src/App.vue b/src/App.vue index 7d45436..709fffd 100644 --- a/src/App.vue +++ b/src/App.vue @@ -7,6 +7,11 @@ enum Filter { Gray = "Gray", Sepia = "Sepia", Invert = "Invert", + Blur = "Blur", + Brightness = "Brightness", + Contrast = "Contrast", + HueShift = "Hue shift", + Saturate = "Saturate" } enum PAPosition { None = "None", @@ -29,6 +34,7 @@ const centerX = ref(0.5); const centerY = ref(0.5); const zoom = ref(1); const filter = ref(Filter.None); +const filterValue = ref(1); const paPos = ref(PAPosition.BR); const paScale = ref(0.2); const paMargin = ref(0.05); @@ -65,6 +71,7 @@ function randomize() { centerY.value = 0.25 + Math.random() * 0.5; zoom.value = 1 + Math.random(); filter.value = randomElement(Object.values(Filter)); + filterValue.value = 0.5 + Math.random() * 2; paPos.value = randomElement(Object.values(PAPosition)); paScale.value = 0.1 + Math.random() * 0.2; paMargin.value = Math.random() * 0.1; @@ -76,6 +83,7 @@ function reset() { centerY.value = 0.5; zoom.value = 1; filter.value = Filter.None; + filterValue.value = 1; paPos.value = PAPosition.BR; paScale.value = 0.2; paMargin.value = 0.05; @@ -97,28 +105,6 @@ function download() { link.click(); } -function applyFilter( - f: Filter, - r: number, - g: number, - b: number, -): [number, number, number] { - switch (f) { - case Filter.Gray: - const gray = 0.21 * r + 0.72 * g + 0.07 * b; - return [gray, gray, gray]; - case Filter.Invert: - return [255 - r, 255 - g, 255 - b]; - case Filter.Sepia: - return [ - Math.min(255, Math.round(r * 0.393 + g * 0.769 + b * 0.189)), - Math.min(255, Math.round(r * 0.349 + g * 0.686 + b * 0.168)), - Math.min(255, Math.round(r * 0.272 + g * 0.534 + b * 0.131)), - ]; - } - return [r, g, b]; -} - const drawTimeout = ref(undefined); function asyncDraw() { @@ -144,25 +130,38 @@ function draw(size = PREVIEW_SIZE) { const imgHeight = size * (widthFirst ? imgRatio : 1) * zoom.value; const dx = (size - imgWidth) * centerX.value; const dy = (size - imgHeight) * centerY.value; + + switch(filter.value) { + case Filter.Gray: + ctx.filter = `grayscale(${(filterValue.value * 100).toFixed(2)}%)` + break + case Filter.Sepia: + ctx.filter = `sepia(${(filterValue.value * 100).toFixed(2)}%)` + break + case Filter.Invert: + ctx.filter = `invert(${(filterValue.value * 100).toFixed(2)}%)` + break + case Filter.Blur: + ctx.filter = `blur(${(filterValue.value * 2 * size / PREVIEW_SIZE).toFixed(2)}px)` + break + case Filter.Brightness: + ctx.filter = `brightness(${(filterValue.value * 100).toFixed(2)}%)` + break + case Filter.Contrast: + ctx.filter = `contrast(${(filterValue.value * 100).toFixed(2)}%)` + break + case Filter.HueShift: + ctx.filter = `hue-rotate(${(filterValue.value * 360).toFixed(2)}deg)` + break + case Filter.Saturate: + ctx.filter = `saturate(${(filterValue.value * 100).toFixed(2)}%)` + break + + } + ctx.drawImage(image.value, dx, dy, imgWidth, imgHeight); - if (filter.value !== Filter.None) { - const imageData = ctx.getImageData(0, 0, size, size); - const pixelData = imageData.data; - for (let i = 0; i < pixelData.length; i += 4) { - const r1 = pixelData[i] ?? 0; - const g1 = pixelData[i + 1] ?? 0; - const b1 = pixelData[i + 2] ?? 0; - - const [r2, g2, b2] = applyFilter(filter.value, r1, g1, b1); - - pixelData[i] = r2; - pixelData[i + 1] = g2; - pixelData[i + 2] = b2; - pixelData[i + 3] = 255; - } - ctx.putImageData(imageData, 0, 0); - } + ctx.filter = "none" if (paPos.value !== PAPosition.None && parentalAdvisory.value) { const paWidth = size * paScale.value; @@ -313,6 +312,21 @@ onMounted(() => { + + + + + + {{ (filterValue * 100).toFixed(0) }}% +