From 378f3e9605514f76eab7a2177bdb222b2990aa1d Mon Sep 17 00:00:00 2001 From: TheShovel <68913917+TheShovel@users.noreply.github.com> Date: Mon, 24 Jul 2023 01:10:33 +0300 Subject: [PATCH] TheShovel/CanvasEffects: add more effects (#747) - Sepia - Transparency - Scale - SkewX - SkewY - Offset X - Offset Y - Rotation - Border radius --- extensions/TheShovel/CanvasEffects.js | 74 +++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/extensions/TheShovel/CanvasEffects.js b/extensions/TheShovel/CanvasEffects.js index 4d53b09cc2..ed9c7552e0 100644 --- a/extensions/TheShovel/CanvasEffects.js +++ b/extensions/TheShovel/CanvasEffects.js @@ -7,21 +7,40 @@ const canvas = Scratch.renderer.canvas; const updateStyle = () => { - const filter = `blur(${blur}px) contrast(${contrast / 100}) saturate(${saturation}%) hue-rotate(${color}deg) brightness(${brightness}%) invert(${invert}%)`; + // Gotta keep the translation to % because of the stage size, window size and so on + const transform = `rotate(${rotation}deg) scale(${scale}%) skew(${skewX}deg, ${skewY}deg) translate(${offsetX}%, ${0 - offsetY}%)`; + if (canvas.style.transform !== transform) { + canvas.style.transform = transform; + } + const filter = `blur(${blur}px) contrast(${contrast / 100}) saturate(${saturation}%) hue-rotate(${color}deg) brightness(${brightness}%) invert(${invert}%) sepia(${sepia}%) opacity(${100 - transparency}%)`; if (canvas.style.filter !== filter) { canvas.style.filter = filter; } + const cssBorderRadius = borderRadius === 0 ? '' : `${borderRadius}%`; + if (canvas.style.borderRadius !== cssBorderRadius) { + canvas.style.borderRadius = cssBorderRadius; + } const imageRendering = resizeMode === 'pixelated' ? 'pixelated' : ''; if (canvas.style.imageRendering !== imageRendering) { canvas.style.imageRendering = imageRendering; } }; - // scratch-gui will sometimes reset the cursor when resizing the window or going in/out of fullscreen + // scratch-gui may reset canvas styles when resizing the window or going in/out of fullscreen new MutationObserver(updateStyle).observe(canvas, { attributeFilter: ['style'], attributes: true }); + let borderRadius = 0; + let rotation = 0; + let offsetY = 0; + let offsetX = 0; + let skewY = 0; + let skewX = 0; + let scale = 100; + // Thanks SharkPool for telling me about these + let transparency = 0; + let sepia = 0; let blur = 0; let contrast = 100; let saturation = 100; @@ -96,7 +115,7 @@ menus: { EFFECTMENU: { acceptReporters: true, - items: ['blur', 'contrast', 'saturation', 'color shift', 'brightness', 'invert'] + items: ['blur', 'contrast', 'saturation', 'color shift', 'brightness', 'invert', 'sepia', 'transparency', 'scale', 'skew X', 'skew Y', 'offset X', 'offset Y', 'rotation', 'border radius'] }, RENDERMODE: { acceptReporters: true, @@ -104,7 +123,8 @@ }, EFFECTGETMENU: { acceptReporters: true, - items: ['blur', 'contrast', 'saturation', 'color shift', 'brightness', 'invert', 'resize rendering mode'] + // this contains 'resize rendering mode', EFFECTMENU does not + items: ['blur', 'contrast', 'saturation', 'color shift', 'brightness', 'invert', 'resize rendering mode', 'sepia', 'transparency', 'scale', 'skew X', 'skew Y', 'offset X', 'offset Y', 'rotation', 'border radius'] } } }; @@ -124,10 +144,29 @@ return invert; } else if (EFFECT === 'resize rendering mode') { return resizeMode; + } else if (EFFECT === 'sepia') { + return sepia; + } else if (EFFECT === 'transparency') { + return transparency; + } else if (EFFECT === 'scale') { + return scale; + } else if (EFFECT === 'skew X') { + return skewX; + } else if (EFFECT === 'skew Y') { + return skewY; + } else if (EFFECT === 'offset X') { + return offsetX; + } else if (EFFECT === 'offset Y') { + return offsetY; + } else if (EFFECT === 'rotation') { + return rotation; + } else if (EFFECT === 'border radius') { + return borderRadius; } return ''; } seteffect({EFFECT, NUMBER}) { + NUMBER = Scratch.Cast.toNumber(NUMBER); if (EFFECT === 'blur') { blur = NUMBER; } else if (EFFECT === 'contrast') { @@ -140,10 +179,37 @@ brightness = NUMBER; } else if (EFFECT === 'invert') { invert = NUMBER; + } else if (EFFECT === 'sepia') { + sepia = NUMBER; + } else if (EFFECT === 'transparency') { + transparency = NUMBER; + } else if (EFFECT === 'scale') { + scale = NUMBER; + } else if (EFFECT === 'skew X') { + skewX = NUMBER; + } else if (EFFECT === 'skew Y') { + skewY = NUMBER; + } else if (EFFECT === 'offset X') { + offsetX = NUMBER; + } else if (EFFECT === 'offset Y') { + offsetY = NUMBER; + } else if (EFFECT === 'rotation') { + rotation = NUMBER; + } else if (EFFECT === 'border radius') { + borderRadius = NUMBER; } updateStyle(); } cleareffects() { + borderRadius = 0; + rotation = 0; + offsetY = 0; + offsetX = 0; + skewY = 0; + skewX = 0; + scale = 100; + transparency = 0; + sepia = 0; blur = 0; contrast = 100; saturation = 100;