From e1b97b98df9219865d08566bb10309603a9b12fe Mon Sep 17 00:00:00 2001 From: yuan Date: Tue, 27 May 2014 00:57:19 -0700 Subject: added graphics effects that work for all redraws; incorporated most recent updates to Snap! --- blocks.js | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index 69ae610..da5e929 100644 --- a/blocks.js +++ b/blocks.js @@ -913,16 +913,12 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { part = new InputSlotMorph( null, false, - { - /* - color : 'color', - fisheye : 'fisheye', - whirl : 'whirl', - pixelate : 'pixelate', - mosaic : 'mosaic', - brightness : 'brightness', - */ - ghost : ['ghost'] + { brightness : ['brightness'], + ghost : ['ghost'], + negative : ['negative'], + comic: ['comic'], + duplicate: ['duplicate'], + confetti: ['confetti'], }, true ); -- cgit v1.3.1 From e7f9ff5dcbac3459c9ab111aea3e4096467d5ea5 Mon Sep 17 00:00:00 2001 From: yuan Date: Mon, 2 Jun 2014 00:07:00 -0700 Subject: JSLinted --- blocks.js | 4 +- objects.js | 183 ++++++++++++++++++++++++++++++++----------------------------- 2 files changed, 97 insertions(+), 90 deletions(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index da5e929..65ab90b 100644 --- a/blocks.js +++ b/blocks.js @@ -918,8 +918,8 @@ SyntaxElementMorph.prototype.labelPart = function (spec) { negative : ['negative'], comic: ['comic'], duplicate: ['duplicate'], - confetti: ['confetti'], - }, + confetti: ['confetti'] + }, true ); part.setContents(['ghost']); diff --git a/objects.js b/objects.js index 7d6ce14..81ce072 100644 --- a/objects.js +++ b/objects.js @@ -1292,11 +1292,11 @@ SpriteMorph.prototype.init = function (globals) { this.idx = 0; // not to be serialized (!) - used for de-serialization this.wasWarped = false; // not to be serialized, used for fast-tracking - this.graphicsValues = { 'negative': 0, //dictionary of all the orignal values - 'fisheye': 0, - 'whirl': 0, - 'pixelate': 0, - 'mosaic': 0, + this.graphicsValues = { 'negative': 0, + 'fisheye': 0, + 'whirl': 0, + 'pixelate': 0, + 'mosaic': 0, 'brightness': 0, 'color': 0, 'comic': 0, @@ -1431,7 +1431,7 @@ SpriteMorph.prototype.drawNew = function () { ctx.scale(this.scale * stageScale, this.scale * stageScale); ctx.translate(shift.x, shift.y); ctx.rotate(radians(facing - 90)); - ctx.drawImage(pic.contents, 0, 0); + ctx.drawImage(pic.contents, 0, 0); // apply graphics effects to image this.image = this.applyGraphicsEffects(this.image); @@ -2847,13 +2847,14 @@ SpriteMorph.prototype.changeScale = function (delta) { this.setScale(this.getScale() + (+delta || 0)); }; -// Spritemorph graphics effects +// Spritemorph graphic effects SpriteMorph.prototype.graphicsChanged = function () { var myself = this; return Object.keys(this.graphicsValues).some( - function(any) { - return myself.graphicsValues[any] < 0 || myself.graphicsValues[any] > 0; + function (any) { + return myself.graphicsValues[any] < 0 || + myself.graphicsValues[any] > 0; } ); }; @@ -2861,103 +2862,106 @@ SpriteMorph.prototype.graphicsChanged = function () { SpriteMorph.prototype.applyGraphicsEffects = function (canvas) { // For every effect: apply transform of that effect(canvas, stored value) // The future: write more effects here + var ctx, imagedata, pixels, newimagedata; function transform_negative(p, value) { + var i, rcom, gcom, bcom; if (value !== 0) { - for (i = 0; i < p.length; i = i + 4) { - var rcom = 255 - p[i + 0] - var gcom = 255 - p[i + 1] - var bcom = 255 - p[i + 2] - - if (p[i + 0] < rcom) { //check if current number less than the complement. if so, then - p[i + 0] = p[i + 0] + value - } else if (p[i + 0] > rcom) { - p[i + 0] = p[i + 0] - value //or else decrease towards it + for (i = 0; i < p.length; i += 4) { + rcom = 255 - p[i]; + gcom = 255 - p[i + 1]; + bcom = 255 - p[i + 2]; + + if (p[i] < rcom) { //compare to the complement + p[i] += value; + } else if (p[i] > rcom) { + p[i] -= value; } if (p[i + 1] < gcom) { - p[i + 1] = p[i + 1] + value + p[i + 1] += value; } else if (p[i + 1] > gcom) { - p[i + 1] = p[i + 1] - value + p[i + 1] -= value; } if (p[i + 2] < bcom) { - p[i + 2] = p[i + 2] + value + p[i + 2] += value; } else if (p[i + 2] > bcom) { - p[i + 2] = p[i + 2] - value - }; - }; - }; + p[i + 2] -= value; + } + } + } return p; - }; + } function transform_brightness(p, value) { + var i; if (value !== 0) { for (i = 0; i < p.length; i += 4) { - p[i+0] = p[i+0] + value; //255 = 100% of this color. 255 everything = white. - p[i+1] = p[i+1] + value; //if value is negative, add more value to p. if value is positive, subtract value from p - p[i+2] = p[i+2] + value; - p[i+3] = p[i+3]; - }; - }; + p[i] += value; //255 = 100% of this color + p[i + 1] += value; + p[i + 2] += value; + } + } return p; - }; + } function transform_comic(p, value) { + var i; if (value !== 0) { for (i = 0; i < p.length; i += 4) { - var frequency = value; - p[i + 0] = p[i + 0] + Math.sin(i * frequency) * 127 + 128 - p[i + 1] = p[i + 1] + Math.sin(i * frequency) * 127 + 128 - p[i + 2] = p[i + 2] + Math.sin(i * frequency) * 127 + 128 - p[i + 3] = p[i + 3]; - }; - }; - return p; - }; + p[i] += Math.sin(i * value) * 127 + 128; + p[i + 1] += Math.sin(i * value) * 127 + 128; + p[i + 2] += Math.sin(i * value) * 127 + 128; + } + } + return p; + } function transform_duplicate(p, value) { + var i; if (value !== 0) { for (i = 0; i < p.length; i += 4) { - p[i + 0] = p[i * value + 0] - p[i + 1] = p[i * value + 1] - p[i + 2] = p[i * value + 2] + p[i] = p[i * value]; + p[i + 1] = p[i * value + 1]; + p[i + 2] = p[i * value + 2]; p[i + 3] = p[i * value + 3]; - }; - }; + } + } return p; - }; + } function transform_confetti(p, value) { + var i; if (value !== 0) { - for (i = 0; i < p.length; i++) { - p[i] = Math.sin(value * p[i]) * 127 + p[i] - }; - }; + for (i = 0; i < p.length; i += 1) { + p[i] = Math.sin(value * p[i]) * 127 + p[i]; + } + } return p; - }; + } - if (this.graphicsChanged()) { //operates image pixel manipulation if graphicschanged = true. - ctx = canvas.getContext("2d"); + if (this.graphicsChanged()) { + ctx = canvas.getContext("2d"); imagedata = ctx.getImageData(0, 0, canvas.width, canvas.height); pixels = imagedata.data; - // for each effect, do a transform. at any given time, a sprite should wear all 7 effects - /*pixels = transform_whirl(pixels, this.graphicsValues['whirl']);*/ - pixels = transform_negative(pixels, this.graphicsValues['negative']); - pixels = transform_brightness(pixels, this.graphicsValues['brightness']); - pixels = transform_comic(pixels, this.graphicsValues['comic']); - /*pixels = transform_pixelate(pixels, this.graphicsValues['pixelate']);*/ - pixels = transform_duplicate(pixels, this.graphicsValues['duplicate']); - /*pixels = transform_color(pixels, this.graphicsValues['color']);*/ - /*pixels = transform_fisheye(pixels, this.graphicsValues['fisheye']);*/ - pixels = transform_confetti(pixels, this.graphicsValues['confetti']); - + //A sprite should wear all 7 effects at once + /*pixels = transform_whirl(pixels, this.graphicsValues.whirl);*/ + pixels = transform_negative(pixels, this.graphicsValues.negative); + pixels = transform_brightness(pixels, this.graphicsValues.brightness); + pixels = transform_comic(pixels, this.graphicsValues.comic); + /*pixels = transform_pixelate(pixels, this.graphicsValues.pixelate);*/ + pixels = transform_duplicate(pixels, this.graphicsValues.duplicate); + /*pixels = transform_color(pixels, this.graphicsValues.color);*/ + /*pixels = transform_fisheye(pixels, this.graphicsValues.fisheye);*/ + pixels = transform_confetti(pixels, this.graphicsValues.confetti); + //the last object will have all the transformations done on it - newimagedata = ctx.createImageData(imagedata); //make new imgdata object - newimagedata.data.set(pixels); //add transformed pixels + newimagedata = ctx.createImageData(imagedata); //make imgdata object + newimagedata.data.set(pixels); //add transformed pixels ctx.putImageData(newimagedata, 0, 0); - }; + } - return canvas; //for each effect, apply the transformation on the image we receive + return canvas; }; SpriteMorph.prototype.setEffect = function (effect, value) { @@ -2965,8 +2969,8 @@ SpriteMorph.prototype.setEffect = function (effect, value) { if (eff === 'ghost') { this.alpha = 1 - Math.min(Math.max(+value || 0, 0), 100) / 100; } else { - this.graphicsValues[eff] = value; //changes the value of the dictionary - }; + this.graphicsValues[eff] = value; + } this.drawNew(); this.changed(); }; @@ -2978,16 +2982,19 @@ SpriteMorph.prototype.getGhostEffect = function () { SpriteMorph.prototype.changeEffect = function (effect, value) { var eff = effect instanceof Array ? effect[0] : null; if (eff === 'ghost') { - this.setEffect(effect, this.getGhostEffect() + (+value || 0)); //special for ghost because of alpha value + this.setEffect(effect, this.getGhostEffect() + (+value || 0)); } else { this.setEffect(effect, this.graphicsValues[eff] + value); - }; + } }; SpriteMorph.prototype.clearEffects = function () { - for (var effect in this.graphicsValues) { - this.setEffect([effect], 0); - }; + var effect; + for (effect in this.graphicsValues) { + if (this.graphicsValues.hasOwnProperty(effect)) { + this.setEffect([effect], 0); + } + } this.setEffect(['ghost'], 0); }; @@ -4141,17 +4148,17 @@ StageMorph.prototype.init = function (globals) { this.trailsCanvas = null; this.isThreadSafe = false; - this.graphicsValues = { 'negative': 0, //dictionary of all the original values - 'fisheye': 0, - 'whirl': 0, - 'pixelate': 0, - 'mosaic': 0, + this.graphicsValues = { 'negative': 0, + 'fisheye': 0, + 'whirl': 0, + 'pixelate': 0, + 'mosaic': 0, 'brightness': 0, 'color': 0, 'comic': 0, 'duplicate': 0, 'confetti': 0 - }; + }; StageMorph.uber.init.call(this); @@ -4209,15 +4216,15 @@ StageMorph.prototype.setScale = function (number) { StageMorph.prototype.drawNew = function () { var ctx; StageMorph.uber.drawNew.call(this); - if (this.costume) { + if (this.costume) { ctx = this.image.getContext('2d'); ctx.scale(this.scale, this.scale); - ctx.drawImage( - this.costume.contents, + ctx.drawImage( + this.costume.contents, (this.width() / this.scale - this.costume.width()) / 2, - (this.height() / this.scale - this.costume.height()) / 2 + (this.height() / this.scale - this.costume.height()) / 2 ); - this.image = this.applyGraphicsEffects(this.image) //apply graphics effects to this image. + this.image = this.applyGraphicsEffects(this.image); } }; -- cgit v1.3.1 From ef3997cccf833aebd3d5d3fbecfdc2c13dab9631 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Wed, 4 Jun 2014 12:39:28 +0200 Subject: Blocks: refactor “script pics” feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blocks.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index 69ae610..3e8aa60 100644 --- a/blocks.js +++ b/blocks.js @@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-May-02'; +modules.blocks = '2014-June-04'; var SyntaxElementMorph; @@ -4957,6 +4957,14 @@ ScriptsMorph.prototype.cleanUp = function () { }; ScriptsMorph.prototype.exportScriptsPicture = function () { + var pic = this.scriptsPicture(); + if (pic) { + window.open(pic.toDataURL()); + } +}; + +ScriptsMorph.prototype.scriptsPicture = function () { + // private - answer a canvas containing the pictures of all scripts var boundingBox, pic, ctx; if (this.children.length === 0) {return; } boundingBox = this.children[0].fullBounds(); @@ -4977,7 +4985,7 @@ ScriptsMorph.prototype.exportScriptsPicture = function () { ); } }); - window.open(pic.toDataURL()); + return pic; }; ScriptsMorph.prototype.addComment = function () { -- cgit v1.3.1 From 9bbe9b2e0af9afd5d94d65d0f7399126c235384b Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 11:45:41 +0200 Subject: enable relabelling blocks with C-Slots --- blocks.js | 12 ++++++++++-- history.txt | 1 + objects.js | 4 ++++ 3 files changed, 15 insertions(+), 2 deletions(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index b2955e9..4890fa1 100644 --- a/blocks.js +++ b/blocks.js @@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/ // Global stuff //////////////////////////////////////////////////////// -modules.blocks = '2014-June-04'; +modules.blocks = '2014-June-06'; var SyntaxElementMorph; @@ -2295,6 +2295,7 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) { // try to restore my previous inputs when my spec has been changed var i = 0, old, + nb, myself = this; this.inputs().forEach(function (inp) { @@ -2305,7 +2306,14 @@ BlockMorph.prototype.restoreInputs = function (oldInputs) { // original - turns empty numberslots to 0: // inp.setContents(old.evaluate()); // "fix" may be wrong b/c constants - inp.setContents(old.contents().text); + if (old.contents) { + inp.setContents(old.contents().text); + } + } else if (old instanceof CSlotMorph && inp instanceof CSlotMorph) { + nb = old.nestedBlock(); + if (nb) { + inp.nestedBlock(nb.fullCopy()); + } } i += 1; }); diff --git a/history.txt b/history.txt index 127e01b..9a1ec59 100755 --- a/history.txt +++ b/history.txt @@ -2162,3 +2162,4 @@ ______ * Objects: gracefully hide & show the stage, fixed #281 * Objects: add hide and show blocks to the stage’s “looks” category * Objects: added more relabelling options to SAY and THINK variants +* Blocks, objects: enable relabelling blocks with C-Slots diff --git a/objects.js b/objects.js index 1d027c2..5aac197 100644 --- a/objects.js +++ b/objects.js @@ -1233,6 +1233,10 @@ SpriteMorph.prototype.blockAlternatives = { receiveClick: ['receiveGo'], doBroadcast: ['doBroadcastAndWait'], doBroadcastAndWait: ['doBroadcast'], + doIf: ['doIfElse', 'doUntil'], + doIfElse: ['doIf', 'doUntil'], + doRepeat: ['doUntil'], + doUntil: ['doRepeat', 'doIf'], // sensing: getLastAnswer: ['getTimer'], -- cgit v1.3.1 From dcd7fb92546d6e9d9b4bd7eeb7d15417cdba3d50 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 11:56:47 +0200 Subject: enable relabelling blocks across categories --- blocks.js | 1 + history.txt | 1 + 2 files changed, 2 insertions(+) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index 4890fa1..d5730b6 100644 --- a/blocks.js +++ b/blocks.js @@ -2268,6 +2268,7 @@ BlockMorph.prototype.relabel = function (alternativeSelectors) { menu.addItem( block, function () { + myself.setCategory(SpriteMorph.prototype.blocks[sel].category); myself.setSelector(sel); } ); diff --git a/history.txt b/history.txt index 9a1ec59..72268f6 100755 --- a/history.txt +++ b/history.txt @@ -2163,3 +2163,4 @@ ______ * Objects: add hide and show blocks to the stage’s “looks” category * Objects: added more relabelling options to SAY and THINK variants * Blocks, objects: enable relabelling blocks with C-Slots +* Blocks: enable relabelling blocks across categories -- cgit v1.3.1 From 0b80976c9c2fc688663c521f4eb9a583b36949c4 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 12:12:19 +0200 Subject: tweaks --- blocks.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index d5730b6..4d14351 100644 --- a/blocks.js +++ b/blocks.js @@ -2268,7 +2268,6 @@ BlockMorph.prototype.relabel = function (alternativeSelectors) { menu.addItem( block, function () { - myself.setCategory(SpriteMorph.prototype.blocks[sel].category); myself.setSelector(sel); } ); @@ -2284,7 +2283,7 @@ BlockMorph.prototype.setSelector = function (aSelector) { var oldInputs = this.inputs(), info; info = SpriteMorph.prototype.blocks[aSelector]; - this.category = info.category; + this.setCategory(info.category); this.selector = aSelector; this.setSpec(localize(info.spec)); this.restoreInputs(oldInputs); -- cgit v1.3.1 From a5eace927aae19f8141eb525a72b18b757f57261 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 13:04:46 +0200 Subject: show zebra-coloring when previewing cross-category relabels --- blocks.js | 1 + 1 file changed, 1 insertion(+) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index 4d14351..af5542f 100644 --- a/blocks.js +++ b/blocks.js @@ -2264,6 +2264,7 @@ BlockMorph.prototype.relabel = function (alternativeSelectors) { alternativeSelectors.forEach(function (sel) { var block = SpriteMorph.prototype.blockForSelector(sel); block.restoreInputs(oldInputs); + block.fixBlockColor(null, true); block.addShadow(new Point(3, 3)); menu.addItem( block, -- cgit v1.3.1 From 7f8d5a3d1eacdc78f61da8e82ac481bbbb825938 Mon Sep 17 00:00:00 2001 From: jmoenig Date: Fri, 6 Jun 2014 13:57:45 +0200 Subject: relabelling custom blocks (experimental) --- blocks.js | 9 +++++++++ byob.js | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- history.txt | 1 + 3 files changed, 58 insertions(+), 1 deletion(-) (limited to 'blocks.js') diff --git a/blocks.js b/blocks.js index af5542f..159d1a2 100644 --- a/blocks.js +++ b/blocks.js @@ -2009,6 +2009,7 @@ BlockMorph.prototype.userMenu = function () { var menu = new MenuMorph(this), world = this.world(), myself = this, + alternatives, blck; menu.addItem( @@ -2066,6 +2067,14 @@ BlockMorph.prototype.userMenu = function () { ); } ); + } else if (this.definition && this.alternatives) { // custom block + alternatives = this.alternatives(); + if (alternatives.length > 0) { + menu.addItem( + 'relabel...', + function () {myself.relabel(alternatives); } + ); + } } menu.addItem( diff --git a/byob.js b/byob.js index 0f79acf..a17f976 100644 --- a/byob.js +++ b/byob.js @@ -106,7 +106,7 @@ SymbolMorph, isNil*/ // Global stuff //////////////////////////////////////////////////////// -modules.byob = '2014-Jun-04'; +modules.byob = '2014-Jun-06'; // Declarations @@ -745,6 +745,7 @@ CustomCommandBlockMorph.prototype.userMenu = function () { } else { menu.addLine(); } + // menu.addItem("export definition...", 'exportBlockDefinition'); menu.addItem("delete block definition...", 'deleteBlockDefinition'); } @@ -846,6 +847,44 @@ CustomCommandBlockMorph.prototype.popUpbubbleHelp = function ( ).popUp(this.world(), this.rightCenter().add(new Point(-8, 0))); }; +// CustomCommandBlockMorph relabelling + +CustomCommandBlockMorph.prototype.relabel = function (alternatives) { + var menu = new MenuMorph(this), + oldInputs = this.inputs().map( + function (each) {return each.fullCopy(); } + ), + myself = this; + alternatives.forEach(function (def) { + var block = def.blockInstance(); + block.restoreInputs(oldInputs); + block.fixBlockColor(null, true); + block.addShadow(new Point(3, 3)); + menu.addItem( + block, + function () { + myself.definition = def; + myself.refresh(); + } + ); + }); + menu.popup(this.world(), this.bottomLeft().subtract(new Point( + 8, + this instanceof CommandBlockMorph ? this.corner : 0 + ))); +}; + +CustomCommandBlockMorph.prototype.alternatives = function () { + var rcvr = this.receiver(), + stage = rcvr.parentThatIsA(StageMorph), + allDefs = rcvr.customBlocks.concat(stage.globalBlocks), + myself = this; + return allDefs.filter(function (each) { + return each !== myself.definition && + each.type === myself.definition.type; + }); +}; + // CustomReporterBlockMorph //////////////////////////////////////////// // CustomReporterBlockMorph inherits from ReporterBlockMorph: @@ -961,6 +1000,14 @@ CustomReporterBlockMorph.prototype.bubbleHelp CustomReporterBlockMorph.prototype.popUpbubbleHelp = CustomCommandBlockMorph.prototype.popUpbubbleHelp; +// CustomReporterBlockMorph relabelling + +CustomReporterBlockMorph.prototype.relabel + = CustomCommandBlockMorph.prototype.relabel; + +CustomReporterBlockMorph.prototype.alternatives + = CustomCommandBlockMorph.prototype.alternatives; + // JaggedBlockMorph //////////////////////////////////////////////////// /* diff --git a/history.txt b/history.txt index 97b487e..02fc2a0 100755 --- a/history.txt +++ b/history.txt @@ -2165,3 +2165,4 @@ ______ * Blocks, objects: enable relabelling blocks with C-Slots * Blocks: enable relabelling blocks across categories * Objects: more relabelling options for SAY, THINK, ASK +* BYOB, Blocks: relabelling custom blocks (experimental) -- cgit v1.3.1