diff --git a/src/blocks/scratch3_looks.js b/src/blocks/scratch3_looks.js index 94d70ea5..a6da97f3 100644 --- a/src/blocks/scratch3_looks.js +++ b/src/blocks/scratch3_looks.js @@ -76,6 +76,14 @@ class Scratch3LooksBlocks { return {min: 0, max: 100}; } + /** + * Limit for brightness effect + * @const {object} + */ + static get EFFECT_BRIGHTNESS_LIMIT (){ + return {min: -100, max: 100}; + } + /** * @param {Target} target - collect bubble state for this target. Probably, but not necessarily, a RenderedTarget. * @returns {BubbleState} the mutable bubble state associated with that target. This will be created if necessary. @@ -484,27 +492,36 @@ class Scratch3LooksBlocks { ); } + clampEffect (effect, value) { + let clampedValue = value; + switch (effect) { + case 'ghost': + clampedValue = MathUtil.clamp(value, + Scratch3LooksBlocks.EFFECT_GHOST_LIMIT.min, + Scratch3LooksBlocks.EFFECT_GHOST_LIMIT.max); + break; + case 'brightness': + clampedValue = MathUtil.clamp(value, + Scratch3LooksBlocks.EFFECT_BRIGHTNESS_LIMIT.min, + Scratch3LooksBlocks.EFFECT_BRIGHTNESS_LIMIT.max); + break; + } + return clampedValue; + } + changeEffect (args, util) { const effect = Cast.toString(args.EFFECT).toLowerCase(); const change = Cast.toNumber(args.CHANGE); if (!util.target.effects.hasOwnProperty(effect)) return; let newValue = change + util.target.effects[effect]; - if (effect === 'ghost') { - newValue = MathUtil.clamp(newValue, - Scratch3LooksBlocks.EFFECT_GHOST_LIMIT.min, - Scratch3LooksBlocks.EFFECT_GHOST_LIMIT.max); - } + newValue = this.clampEffect(effect, newValue); util.target.setEffect(effect, newValue); } setEffect (args, util) { const effect = Cast.toString(args.EFFECT).toLowerCase(); let value = Cast.toNumber(args.VALUE); - if (effect === 'ghost') { - value = MathUtil.clamp(value, - Scratch3LooksBlocks.EFFECT_GHOST_LIMIT.min, - Scratch3LooksBlocks.EFFECT_GHOST_LIMIT.max); - } + value = this.clampEffect(effect, value); util.target.setEffect(effect, value); } diff --git a/test/unit/blocks_looks.js b/test/unit/blocks_looks.js index 61b6ddd5..599e7e49 100644 --- a/test/unit/blocks_looks.js +++ b/test/unit/blocks_looks.js @@ -211,3 +211,48 @@ test('numbers should be rounded to two decimals in say', t => { looks.say(args, util); }); + +test('clamp graphic effects', t => { + const rt = new Runtime(); + const looks = new Looks(rt); + const expectedValues = { + brightness: {high: 100, low: -100}, + ghost: {high: 100, low: 0}, + color: {high: 500, low: -500}, + fisheye: {high: 500, low: -500}, + whirl: {high: 500, low: -500}, + pixelate: {high: 500, low: -500}, + mosaic: {high: 500, low: -500} + }; + const args = [ + {EFFECT: 'brightness', VALUE: 500, CLAMP: 'high'}, + {EFFECT: 'brightness', VALUE: -500, CLAMP: 'low'}, + {EFFECT: 'ghost', VALUE: 500, CLAMP: 'high'}, + {EFFECT: 'ghost', VALUE: -500, CLAMP: 'low'}, + {EFFECT: 'color', VALUE: 500, CLAMP: 'high'}, + {EFFECT: 'color', VALUE: -500, CLAMP: 'low'}, + {EFFECT: 'fisheye', VALUE: 500, CLAMP: 'high'}, + {EFFECT: 'fisheye', VALUE: -500, CLAMP: 'low'}, + {EFFECT: 'whirl', VALUE: 500, CLAMP: 'high'}, + {EFFECT: 'whirl', VALUE: -500, CLAMP: 'low'}, + {EFFECT: 'pixelate', VALUE: 500, CLAMP: 'high'}, + {EFFECT: 'pixelate', VALUE: -500, CLAMP: 'low'}, + {EFFECT: 'mosaic', VALUE: 500, CLAMP: 'high'}, + {EFFECT: 'mosaic', VALUE: -500, CLAMP: 'low'} + ]; + + util.target.setEffect = function (effectName, actualValue) { + const clamp = actualValue > 0 ? 'high' : 'low'; + rt.emit(effectName + clamp, effectName, actualValue); + }; + + for (const arg of args) { + rt.addListener(arg.EFFECT + arg.CLAMP, (effectName, actualValue) => { + const expected = expectedValues[arg.EFFECT][arg.CLAMP]; + t.strictEqual(actualValue, expected); + }); + + looks.setEffect(arg, util); + } + t.end(); +});