bharvey wrote:
xly wrote:
I don't know if that is worth of interest or not ? I've installed on a Windows XP PC a server , xampp, which allows to use Snap! locally. It works pretty well, better with Firefox than Chrome. Snap! projects can be loaded and saved as usual.
Yes, that's awesome! Does that mean you keep a local copy of the Snap! source code, or does it automatically download the latest version when you have net access?
(It's especially awesome because it's platform-independent!)
Yes it works locally ( It is checked by deconnecting the Ethernet cable).
Snap! applications are saved "somewhere" (I can find out where ??)
Snap! is more instable with Chrome than with Firefox (opposedly to the "remote" Snap!)
To load existing applications I use Import or "drag-and-drop" .
Import feature does not work well with larger applis.
I have been inspired by the "instant.js" solution a Javascript development tool to create javascriptHtml5 games.
Installation of xampp takes time, but is straightforward.
Very precious, installation is portable, ie all files are placed in one directory (no register parameters, hidden files split away in all the directory treeof the OS - that is Windows).
Snap! files are installed in the directory "htdocs" ie one launcher Snap!.htm file + one directory containing the Snap! *.js files (morphic, block,objects ..etc)
For Snap! only the Apache service is used, but it provides other services like Mysql and Ftp which for Snap! could be either removed from the package to have a lighter package, or exploited to achieve transfer/saving/sharing features.
Last edited by xly (2012-12-12 03:50:51)
Offline
The only foolproof way I can think of for the HTTP block is to use a proxy, unless there's a JS procedure that reads a webpage without any security issues...
Offline
Can we have some kind of dictionary/object data type in Snap!? And a JSON parser and encoder built-in? I understand it's not too tough to make your own using lambda (I might do that as a project right now; I'm bored), but this way would be uniform across all projects. You could use the ([] of []) block to get properties of an object, and have a system similar to lists for constructors:
(new dictionary with key: [color] value: [green] >) => {"color":"green"}
(set [color] of (car) to [red]) => {"color":"red"}
(delete attrib [] of ())
...
Offline
<project name="Dictionary" app="Snap! 4.0, http://snap.berkeley.edu" version="1"><notes></notes><thumbnail>data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKAAAAB4CAYAAAB1ovlvAAADIUlEQVR4Ae3WwUlkARRE0d/DxKFoRrozIyMxARfmonm4dVQQBodmoCgokPM32q3vPTxcaE9v78/hITAS+DW66yyBTwEBCmEqIMApv+MC1MBUQIBTfscFqIGpgACn/I4LUANTAQFO+R0XoAamAgKc8jsuQA1MBQQ45XdcgBqYCghwyu+4ADUwFRDglN9xAWpgKiDAKb/jAtTAVECAU37HBaiBqYAAp/yOC1ADUwEBTvkdF6AGpgICnPI7LkANTAUEOOV3XIAamAoIcMrvuAA1MBUQ4JTfcQFqYCogwCm/4wLUwFRAgFN+xwWogamAAKf8jgtQA1MBAU75HRegBqYCApzyOy5ADUwFBDjld1yAGpgKCHDK77gANTAVEOCU33EBamAqIMApv+MC1MBUQIBTfscFqIGpgACn/I4LUANTAQGe4b+4uDgeHh7O/NTbLYHT2/vTWvbT9tze3h5fPM/Pz8fj4+NxfX390/7M6d8jwP/w39zc/PMbp9PpeH19PZ6eno6P7z25gI/g0E54Idy3sd/fXnv5l8DHR/DX8/Ly8vkRfHV19fWWrwUBAZ5BvLy8PO7v74+7u7szv+HthoD/ARuKdsQC/geM6Qw2BATYULQjFhBgTGewISDAhqIdsYAAYzqDDQEBNhTtiAUEGNMZbAgIsKFoRywgwJjOYENAgA1FO2IBAcZ0BhsCAmwo2hELCDCmM9gQEGBD0Y5YQIAxncGGgAAbinbEAgKM6Qw2BATYULQjFhBgTGewISDAhqIdsYAAYzqDDQEBNhTtiAUEGNMZbAgIsKFoRywgwJjOYENAgA1FO2IBAcZ0BhsCAmwo2hELCDCmM9gQEGBD0Y5YQIAxncGGgAAbinbEAgKM6Qw2BATYULQjFhBgTGewISDAhqIdsYAAYzqDDQEBNhTtiAUEGNMZbAgIsKFoRywgwJjOYENAgA1FO2IBAcZ0BhsCAmwo2hELCDCmM9gQEGBD0Y5YQIAxncGGgAAbinbEAgKM6Qw2BATYULQjFhBgTGewISDAhqIdsYAAYzqDDQEBNhTtiAUEGNMZbAgIsKFoRyzwB9UYKzMr6RmVAAAAAElFTkSuQmCC</thumbnail><stage name="Stage" costume="0" tempo="60" threadsafe="false" id="1"><pentrails>data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAeAAAAFoCAYAAACPNyggAAAOiklEQVR4Ae3VwQkAIAwEQbX/niM24X4mDRwMgd0zsxwBAgQIECDwV+D8nbNGgAABAgQIPAEB9gcECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBAQYD9AgAABAgQCAQEO0E0SIECAAAEB9gMECBAgQCAQEOAA3SQBAgQIEBBgP0CAAAECBAIBAQ7QTRIgQIAAAQH2AwQIECBAIBAQ4ADdJAECBAgQEGA/QIAAAQIEAgEBDtBNEiBAgAABAfYDBAgQIEAgEBDgAN0kAQIECBC4qcoFzaZQGfQAAAAASUVORK5CYII=</pentrails><costumes><list id="2"></list></costumes><sounds><list id="3"></list></sounds><variables></variables><blocks></blocks><scripts></scripts><sprites><sprite name="Sprite" idx="1" x="0" y="0" heading="90" scale="1" rotation="1" draggable="true" costume="0" color="80,80,80" id="8"><costumes><list id="9"></list></costumes><sounds><list id="10"></list></sounds><variables></variables><blocks></blocks><scripts><script x="80" y="192"><custom-block s="get keys %s"><custom-block s="add pair key: %txt value: %s to %s"><l>color</l><l>red</l><custom-block s="Object"></custom-block></custom-block></custom-block></script></scripts></sprite></sprites></stage><blocks><block-definition s="Object" type="reporter" category="other"><inputs></inputs><script><block s="doReport"><block s="reifyScript"><script><block s="doIfElse"><block var="keys?"/><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script><script><block s="doReport"><block s="reportNewList"><list></list></block></block></script></block></script><list><l>keys?</l></list></block></block></script></block-definition><block-definition s="get keys %'obj'" type="reporter" category="other"><inputs><input type="%s"></input></inputs><script><block s="doReport"><block s="evaluate"><custom-block s="Object"></custom-block><list><block s="reportTrue"></block></list></block></block></script></block-definition><block-definition s="get values %'obj'" type="reporter" category="other"><inputs><input type="%s"></input></inputs><script><block s="doReport"><block s="evaluate"><custom-block s="Object"></custom-block><list><block s="reportFalse"></block></list></block></block></script></block-definition><block-definition s="add pair key: %'k' value: %'v' to %'obj'" type="reporter" category="other"><inputs><input type="%txt"></input><input type="%s"></input><input type="%s"></input></inputs><script><block s="doDeclareVariables"><list><l>keys</l><l>values</l></list></block><block s="doSetVar"><l>keys</l><custom-block s="get keys %s"><block var="obj"/></custom-block></block><block s="doAddToList"><block var="k"/><block var="keys"/></block><block s="doSetVar"><l>values</l><custom-block s="get values %s"><block var="obj"/></custom-block></block><block s="doAddToList"><block var="v"/><block var="values"/></block><block s="doReport"><block s="reifyScript"><script><block s="doIfElse"><block var="keys?"/><script><block s="doReport"><block var="keys"/></block></script><script><block s="doReport"><block var="values"/></block></script></block></script><list><l>keys?</l></list></block></block></script></block-definition></blocks><variables></variables></project>
What's wrong here?
Offline
Hardmath123 wrote:
What's wrong here?
![]()
Should "add pair key" be returning a block thing?
screenshot
Offline
Isn't it already?
EDIT: Nice job with letting us drop XML files in on Snap, Jens! I wish I had that for other apps.
Last edited by Hardmath123 (2012-12-14 13:24:41)
Offline
Hardmath123 wrote:
Isn't it already?
It is. Clearly I don't understand how it's supposed to work
Offline
Well, Object returns a lambda with an input, and the input dictates whether it returns the list of keys or list of values.
Add pair basically gets the keys and values, tacks on your pair, and then spits out a new lambda with the new lists.
Except, it doesn't.
Offline
Hardmath123 wrote:
I understand it's not too tough to make your own using lambda
Why not just a list of length-2 lists?
ADD (LIST (color) (red)) TO (mydict)
(I might do that as a project right now; I'm bored)
Implement one of the missing graphic sprite effects for Snap!!
PS I think your project doesn't work b/c of a Snap! bug, but I'm not sure yet.
Offline
Implement one of the missing graphic sprite effects for Snap!!
![]()
Alrighty! I just finished two USAMTS problems, so I'm going to try to do something actually fun for the rest of the day.
Offline
Where do you define the list of options in the %eff dropdown?
Offline
Offline
And here's another way
Offline
*facepalm* it's moments like these that I realize how insanely stupid I am past 11:30PM.
So it works.
Offline
Hardmath123 wrote:
Where do you define the list of options in the %eff dropdown?
Can't find it... hey Jens, do you know a good way to search a set of multiple files? I use Xcode to write my code, and normally I like to have all my code in the same file, all my styles in the same file, and all my HTML in the same file for web apps, for simplicity in editing.
Offline
Sorry about the triple-post, but I wanted to point out that you already have some sort of function to add color filters. Are you using that for the graphic effect? If so, that just leaves the mosaic, whirl and fisheye effects. I'll try to implement mosaic.
Offline
Thanks! And no problem, you're crystal clear compared to say my history teacher, who sounds more like the train you're on.
Offline
One changeset for mosaic:
SpriteMorph.prototype.mosaicAmt = 1; SpriteMorph.prototype.setEffect = function (effect, value) { var eff = effect instanceof Array ? effect[0] : null; if (eff === 'ghost') { this.alpha = 1 - Math.min(Math.max(parseFloat(value), 0), 100) / 100; this.changed(); } if (eff === 'mosaic') { this.mosaicAmt = Number(value)>0 ? Number(value) : 1; this.changed(); this.drawNew(); } }; SpriteMorph.prototype.changeEffect = function (effect, value) { var eff = effect instanceof Array ? effect[0] : null; if (eff === 'ghost') { this.setEffect(effect, this.getGhostEffect() + parseFloat(value)); } if (eff === 'mosaic') { this.setEffect(effect, this.mosaicAmt + parseFloat(value)); } }; SpriteMorph.prototype.clearEffects = function () { this.setEffect(['ghost'], 0); this.setEffect(['mosaic'], 1); }; SpriteMorph.prototype.drawNew = function () { var myself = this, currentCenter = this.center(), facing, // actual costume heading based on my rotation style isFlipped, pic, // (flipped copy of) actual costume based on my rotation style stageScale = this.parent instanceof StageMorph ? this.parent.scale : 1, newX, corners = [], origin, shift, corner, costumeExtent, ctx; facing = this.rotationStyle ? this.heading : 90; if (this.rotationStyle === 2) { facing = 90; if ((this.heading > 180 && (this.heading < 360)) || (this.heading < 0 && (this.heading > -180))) { isFlipped = true; } } if (this.costume) { console.log(this.mosaicAmt); pic = isFlipped ? this.costume.flipped() : this.costume; // determine the rotated costume's bounding box corners = pic.bounds().corners().map(function (point) { return point.rotateBy( radians(facing - 90), myself.costume.center() ); }); origin = corners[0]; corner = corners[0]; corners.forEach(function (point) { origin = origin.min(point); corner = corner.max(point); }); costumeExtent = origin.corner(corner) .extent().multiplyBy(this.scale * stageScale); // determine the new relative origin of the rotated shape shift = new Point(0, 0).rotateBy( radians(-(facing - 90)), pic.center() ).subtract(origin); // create a new, adequately dimensioned canvas // and draw the costume on it this.image = newCanvas(costumeExtent); this.silentSetExtent(costumeExtent); ctx = this.image.getContext('2d'); ctx.scale(this.scale * stageScale, this.scale * stageScale); ctx.translate(shift.x, shift.y); ctx.rotate(radians(facing - 90)); for (var xpic = 0; xpic < this.mosaicAmt; xpic++) { for (var ypic = 0; ypic < this.mosaicAmt; ypic++) { ctx.drawImage(pic.contents, xpic*pic.contents.width/this.mosaicAmt, ypic*pic.contents.height/this.mosaicAmt, pic.contents.width/this.mosaicAmt, pic.contents.height/this.mosaicAmt); } } // adjust my position to the rotation this.setCenter(currentCenter); // determine my rotation offset this.rotationOffset = shift .translateBy(pic.rotationCenter) .rotateBy(radians(-(facing - 90)), shift) .scaleBy(this.scale * stageScale); } else { facing = isFlipped ? -90 : facing; newX = Math.min( Math.max( this.normalExtent.x * this.scale * stageScale, 5 ), 1000 ); this.silentSetExtent(new Point(newX, newX)); this.image = newCanvas(this.extent()); this.setCenter(currentCenter); SpriteMorph.uber.drawNew.call(this, facing); this.rotationOffset = this.extent().divideBy(2); } this.version = Date.now(); };
I love your code, it's so organized.
Offline
Hardmath123 wrote:
Can't find it... hey Jens, do you know a good way to search a set of multiple files? I use Xcode to write my code, and normally I like to have all my code in the same file, all my styles in the same file, and all my HTML in the same file for web apps, for simplicity in editing.
1) Isn't Xcode's JavaScript formatting really messed up? I couldn't find a way to disable it…
EDIT: Oh, or you could just leave it on, I guess…
2) Click the third tab in the navigator area; it's a search utility.
Hardmath123 wrote:
One changeset for mosaic:
Code:
SpriteMorph.prototype.mosaicAmt = 1; SpriteMorph.prototype.setEffect = function (effect, value) { var eff = effect instanceof Array ? effect[0] : null; if (eff === 'ghost') { this.alpha = 1 - Math.min(Math.max(parseFloat(value), 0), 100) / 100; this.changed(); } if (eff === 'mosaic') { this.mosaicAmt = Number(value)>0 ? Number(value) : 1; this.changed(); this.drawNew(); } }; SpriteMorph.prototype.changeEffect = function (effect, value) { var eff = effect instanceof Array ? effect[0] : null; if (eff === 'ghost') { this.setEffect(effect, this.getGhostEffect() + parseFloat(value)); } if (eff === 'mosaic') { this.setEffect(effect, this.mosaicAmt + parseFloat(value)); } }; SpriteMorph.prototype.clearEffects = function () { this.setEffect(['ghost'], 0); this.setEffect(['mosaic'], 1); }; SpriteMorph.prototype.drawNew = function () { var myself = this, currentCenter = this.center(), facing, // actual costume heading based on my rotation style isFlipped, pic, // (flipped copy of) actual costume based on my rotation style stageScale = this.parent instanceof StageMorph ? this.parent.scale : 1, newX, corners = [], origin, shift, corner, costumeExtent, ctx; facing = this.rotationStyle ? this.heading : 90; if (this.rotationStyle === 2) { facing = 90; if ((this.heading > 180 && (this.heading < 360)) || (this.heading < 0 && (this.heading > -180))) { isFlipped = true; } } if (this.costume) { console.log(this.mosaicAmt); pic = isFlipped ? this.costume.flipped() : this.costume; // determine the rotated costume's bounding box corners = pic.bounds().corners().map(function (point) { return point.rotateBy( radians(facing - 90), myself.costume.center() ); }); origin = corners[0]; corner = corners[0]; corners.forEach(function (point) { origin = origin.min(point); corner = corner.max(point); }); costumeExtent = origin.corner(corner) .extent().multiplyBy(this.scale * stageScale); // determine the new relative origin of the rotated shape shift = new Point(0, 0).rotateBy( radians(-(facing - 90)), pic.center() ).subtract(origin); // create a new, adequately dimensioned canvas // and draw the costume on it this.image = newCanvas(costumeExtent); this.silentSetExtent(costumeExtent); ctx = this.image.getContext('2d'); ctx.scale(this.scale * stageScale, this.scale * stageScale); ctx.translate(shift.x, shift.y); ctx.rotate(radians(facing - 90)); for (var xpic = 0; xpic < this.mosaicAmt; xpic++) { for (var ypic = 0; ypic < this.mosaicAmt; ypic++) { ctx.drawImage(pic.contents, xpic*pic.contents.width/this.mosaicAmt, ypic*pic.contents.height/this.mosaicAmt, pic.contents.width/this.mosaicAmt, pic.contents.height/this.mosaicAmt); } } // adjust my position to the rotation this.setCenter(currentCenter); // determine my rotation offset this.rotationOffset = shift .translateBy(pic.rotationCenter) .rotateBy(radians(-(facing - 90)), shift) .scaleBy(this.scale * stageScale); } else { facing = isFlipped ? -90 : facing; newX = Math.min( Math.max( this.normalExtent.x * this.scale * stageScale, 5 ), 1000 ); this.silentSetExtent(new Point(newX, newX)); this.image = newCanvas(this.extent()); this.setCenter(currentCenter); SpriteMorph.uber.drawNew.call(this, facing); this.rotationOffset = this.extent().divideBy(2); } this.version = Date.now(); };
I love your code, it's so organized.
Use (+value || 0) for casting a user value a number; it defaults to zero and avoids using the named Number function.
Last edited by nXIII (2012-12-15 10:32:24)
Offline
Just got accepted into the Scratch 2.0 Alpha and I've got to say- the vector-based paint editing is pretty fantastic. It'd be a good model for Snap- well, once its ready for a paint editor anyway.
Offline
Hardmath123 wrote:
hey Jens, do you know a good way to search a set of multiple files?
IANJ, but what you want is Emacs, God's text editor. No problem with multiple files. And you can split your window in half and play ASCII Space Invaders in the other half while watching your code compiling.
(If you're using a Mac, get Aquamacs.)
Offline