Convert remaining modules

This commit is contained in:
Tim Mickel 2016-01-21 15:32:41 -05:00
parent bf07d98ccd
commit 1c32ecf0a5
9 changed files with 4628 additions and 4507 deletions

View file

@ -1,4 +1,10 @@
var Block = function (spec, isPalette, scale) { import BlockSpecs from './BlockSpecs';
import BlockArg from './BlockArg';
import ScratchJr from '../ScratchJr';
import {setProps, setCanvasSize, scaleMultiplier} from '../../utils/lib';
export default class Block {
constructor (spec, isPalette, scale) {
this.div = document.createElement('div'); this.div = document.createElement('div');
// Top-level block parent shouldn't accept pointer events // Top-level block parent shouldn't accept pointer events
@ -17,7 +23,8 @@ var Block = function (spec, isPalette, scale) {
position: 'absolute', position: 'absolute',
left: '0px', left: '0px',
top: '0px', top: '0px',
webkitTransform: 'translate(' + (-this.blockshape.width / 2) + 'px, ' + (-this.blockshape.height / 2) + 'px) ' + webkitTransform: 'translate(' + (-this.blockshape.width / 2) + 'px, ' +
(-this.blockshape.height / 2) + 'px) ' +
'scale(' + (1 / window.devicePixelRatio) + ') ' + 'scale(' + (1 / window.devicePixelRatio) + ') ' +
'translate(' + (this.blockshape.width / 2) + 'px, ' + (this.blockshape.height / 2) + 'px)', 'translate(' + (this.blockshape.width / 2) + 'px, ' + (this.blockshape.height / 2) + 'px)',
pointerEvents: 'all' pointerEvents: 'all'
@ -31,9 +38,9 @@ var Block = function (spec, isPalette, scale) {
} }
this.createArgument(); this.createArgument();
this.div.owner = this; this.div.owner = this;
}; }
Block.prototype.getWidth = function () { getWidth () {
if (this.blocktype == 'repeat') { if (this.blocktype == 'repeat') {
return 176; return 176;
} }
@ -44,16 +51,16 @@ Block.prototype.getWidth = function () {
return 84; return 84;
} }
return 76; return 76;
}; }
Block.prototype.getHeight = function () { getHeight () {
if (this.blocktype == 'repeat') { if (this.blocktype == 'repeat') {
return 82; return 82;
} }
return 66; return 66;
}; }
Block.prototype.setBlockshapeFromSpecs = function (spec, isPalette, scale) { setBlockshapeFromSpecs (spec, isPalette, scale) {
this.spec = spec; this.spec = spec;
this.isReporter = (spec[1] == 'reporter'); this.isReporter = (spec[1] == 'reporter');
this.blocktype = spec[0]; this.blocktype = spec[0];
@ -83,9 +90,9 @@ Block.prototype.setBlockshapeFromSpecs = function (spec, isPalette, scale) {
this.hrubberband = 0; this.hrubberband = 0;
this.vrubberband = 0; this.vrubberband = 0;
this.done = false; this.done = false;
}; }
Block.prototype.addShadow = function () { addShadow () {
this.shadow = document.createElement('canvas'); this.shadow = document.createElement('canvas');
this.div.appendChild(this.shadow); this.div.appendChild(this.shadow);
setProps(this.shadow.style, { setProps(this.shadow.style, {
@ -94,7 +101,8 @@ Block.prototype.addShadow = function () {
top: '4px', top: '4px',
opacity: this.inpalette ? Settings.paletteBlockShadowOpacity : 1, opacity: this.inpalette ? Settings.paletteBlockShadowOpacity : 1,
visibility: 'hidden', visibility: 'hidden',
webkitTransform: 'translate(' + (-this.blockshape.width / 2) + 'px, ' + (-this.blockshape.height / 2) + 'px) ' + webkitTransform: 'translate(' + (-this.blockshape.width / 2) + 'px, ' +
(-this.blockshape.height / 2) + 'px) ' +
'scale(' + (1 / window.devicePixelRatio) + ') ' + 'scale(' + (1 / window.devicePixelRatio) + ') ' +
'translate(' + (this.blockshape.width / 2) + 'px, ' + (this.blockshape.height / 2) + 'px)', 'translate(' + (this.blockshape.width / 2) + 'px, ' + (this.blockshape.height / 2) + 'px)',
pointerEvents: 'all' pointerEvents: 'all'
@ -108,23 +116,24 @@ Block.prototype.addShadow = function () {
if (!img.complete) { if (!img.complete) {
img.onload = function () { img.onload = function () {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0,
img.width * this.scale * window.devicePixelRatio, img.height * this.scale * window.devicePixelRatio); img.width * this.scale * window.devicePixelRatio,
img.height * this.scale * window.devicePixelRatio);
}; };
} else { } else {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0,
img.width * this.scale * window.devicePixelRatio, img.height * this.scale * window.devicePixelRatio); img.width * this.scale * window.devicePixelRatio, img.height * this.scale * window.devicePixelRatio);
} }
}; }
Block.prototype.lift = function () { lift () {
this.shadow.style.visibility = 'visible'; this.shadow.style.visibility = 'visible';
}; }
Block.prototype.drop = function () { drop () {
this.shadow.style.visibility = 'hidden'; this.shadow.style.visibility = 'hidden';
}; }
Block.prototype.addHighlight = function () { addHighlight () {
var img = this.spec[5]; var img = this.spec[5];
if (!img) { if (!img) {
return; return;
@ -137,7 +146,8 @@ Block.prototype.addHighlight = function () {
left: '0px', left: '0px',
top: '0px', top: '0px',
visibility: 'hidden', visibility: 'hidden',
webkitTransform: 'translate(' + (-this.blockshape.width / 2) + 'px, ' + (-this.blockshape.height / 2) + 'px) ' + webkitTransform: 'translate(' + (-this.blockshape.width / 2) +
'px, ' + (-this.blockshape.height / 2) + 'px) ' +
'scale(' + (1 / window.devicePixelRatio) + ') ' + 'scale(' + (1 / window.devicePixelRatio) + ') ' +
'translate(' + (this.blockshape.width / 2) + 'px, ' + (this.blockshape.height / 2) + 'px)', 'translate(' + (this.blockshape.width / 2) + 'px, ' + (this.blockshape.height / 2) + 'px)',
pointerEvents: 'all' pointerEvents: 'all'
@ -146,15 +156,16 @@ Block.prototype.addHighlight = function () {
if (!img.complete) { if (!img.complete) {
img.onload = function () { img.onload = function () {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0,
img.width * this.scale * window.devicePixelRatio, img.height * this.scale * window.devicePixelRatio); img.width * this.scale * window.devicePixelRatio,
img.height * this.scale * window.devicePixelRatio);
}; };
} else { } else {
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0,
img.width * this.scale * window.devicePixelRatio, img.height * this.scale * window.devicePixelRatio); img.width * this.scale * window.devicePixelRatio, img.height * this.scale * window.devicePixelRatio);
} }
}; }
Block.prototype.drawBlock = function () { drawBlock () {
var cnv = this.blockshape; var cnv = this.blockshape;
var ctx = this.blockshape.getContext('2d'); var ctx = this.blockshape.getContext('2d');
ctx.clearRect(0, 0, cnv.width, cnv.height); ctx.clearRect(0, 0, cnv.width, cnv.height);
@ -166,9 +177,9 @@ Block.prototype.drawBlock = function () {
} else { } else {
this.drawBlockType(); this.drawBlockType();
} }
}; }
Block.prototype.drawBlockType = function () { drawBlockType () {
var ctx = this.blockshape.getContext('2d'); var ctx = this.blockshape.getContext('2d');
ctx.drawImage(this.image, 0, 0, this.image.width, this.image.height, 0, 0, ctx.drawImage(this.image, 0, 0, this.image.width, this.image.height, 0, 0,
this.image.width * this.scale * window.devicePixelRatio, this.image.width * this.scale * window.devicePixelRatio,
@ -181,7 +192,8 @@ Block.prototype.drawBlockType = function () {
position: 'absolute', position: 'absolute',
left: '0px', left: '0px',
top: '0px', top: '0px',
webkitTransform: 'translate(' + (-this.blockshape.width / 2) + 'px, ' + (-this.blockshape.height / 2) + 'px) ' + webkitTransform: 'translate(' + (-this.blockshape.width / 2) + 'px, ' +
(-this.blockshape.height / 2) + 'px) ' +
'scale(' + (1 / window.devicePixelRatio) + ') ' + 'scale(' + (1 / window.devicePixelRatio) + ') ' +
'translate(' + (this.blockshape.width / 2) + 'px, ' + (this.blockshape.height / 2) + 'px)', 'translate(' + (this.blockshape.width / 2) + 'px, ' + (this.blockshape.height / 2) + 'px)',
pointerEvents: 'all' pointerEvents: 'all'
@ -190,15 +202,15 @@ Block.prototype.drawBlockType = function () {
this.drawIcon(); this.drawIcon();
} }
this.done = true; this.done = true;
}; }
Block.prototype.updateBlock = function () { updateBlock () {
if (this.arg && this.arg.argType == 'p') { if (this.arg && this.arg.argType == 'p') {
this.arg.updateIcon(); this.arg.updateIcon();
} }
}; }
Block.prototype.highlight = function () { highlight () {
if (this.blocktype.indexOf('caret') > -1) { if (this.blocktype.indexOf('caret') > -1) {
return; return;
} }
@ -209,16 +221,16 @@ Block.prototype.highlight = function () {
return; return;
} }
this.shine.style.visibility = 'visible'; this.shine.style.visibility = 'visible';
}; }
Block.prototype.unhighlight = function () { unhighlight () {
if (this.blocktype.indexOf('caret') > -1) { if (this.blocktype.indexOf('caret') > -1) {
return; return;
} }
this.shine.style.visibility = 'hidden'; this.shine.style.visibility = 'hidden';
}; }
Block.prototype.drawIcon = function () { drawIcon () {
var dx = 0; var dx = 0;
var dy = 0; var dy = 0;
var ctx = this.blockicon.getContext('2d'); var ctx = this.blockicon.getContext('2d');
@ -240,9 +252,9 @@ Block.prototype.drawIcon = function () {
break; break;
} }
this.drawMyIcon(ctx, dx, dy); this.drawMyIcon(ctx, dx, dy);
}; }
Block.prototype.drawMyIcon = function (ctx, dx, dy) { drawMyIcon (ctx, dx, dy) {
var me = this; var me = this;
var icon = this.icon; var icon = this.icon;
if (!icon.complete) { if (!icon.complete) {
@ -256,23 +268,23 @@ Block.prototype.drawMyIcon = function (ctx, dx, dy) {
icon.width * me.scale * window.devicePixelRatio, icon.width * me.scale * window.devicePixelRatio,
icon.height * me.scale * window.devicePixelRatio); icon.height * me.scale * window.devicePixelRatio);
} }
}; }
Block.prototype.createArgument = function () { createArgument () {
if (this.spec[4] == null) { if (this.spec[4] == null) {
return; return;
} }
this.arg = new BlockArg(this); this.arg = new BlockArg(this);
}; }
Block.prototype.getArgValue = function () { getArgValue () {
if (this.arg == null) { if (this.arg == null) {
return null; return null;
} }
return this.arg.argValue; return this.arg.argValue;
}; }
Block.prototype.getSoundName = function (list) { getSoundName (list) {
var val = this.arg.argValue; var val = this.arg.argValue;
if (Number(val).toString() == 'NaN') { if (Number(val).toString() == 'NaN') {
return val; return val;
@ -281,15 +293,15 @@ Block.prototype.getSoundName = function (list) {
return list[0]; return list[0];
} }
return list[val]; return list[val];
}; }
Block.prototype.update = function (spr) { update (spr) {
if (this.arg) { if (this.arg) {
this.arg.update(spr); this.arg.update(spr);
} }
}; }
Block.prototype.setSound = function (bt) { setSound (bt) {
var p = this.arg.div; var p = this.arg.div;
p.parentNode.removeChild(p); p.parentNode.removeChild(p);
var icon = this.blockicon; var icon = this.blockicon;
@ -299,9 +311,9 @@ Block.prototype.setSound = function (bt) {
this.setBlockshapeFromSpecs(specs); this.setBlockshapeFromSpecs(specs);
this.drawBlock(); this.drawBlock();
this.createArgument(); this.createArgument();
}; }
Block.prototype.duplicateBlock = function (dx, dy, spr) { duplicateBlock (dx, dy, spr) {
var op = this.blocktype; var op = this.blocktype;
var specs = BlockSpecs.defs[op]; var specs = BlockSpecs.defs[op];
specs[4] = this.getArgValue(); specs[4] = this.getArgValue();
@ -314,9 +326,9 @@ Block.prototype.duplicateBlock = function (dx, dy, spr) {
bbx.moveBlock(dx, dy); bbx.moveBlock(dx, dy);
bbx.update(spr); bbx.update(spr);
return bbx; return bbx;
}; }
Block.prototype.resolveDocks = function () { resolveDocks () {
var w = this.getWidth(); var w = this.getWidth();
var h = this.getHeight(); var h = this.getHeight();
if (this.aStart) { if (this.aStart) {
@ -336,17 +348,17 @@ Block.prototype.resolveDocks = function () {
} else { } else {
return [['flow', true, 0, h / 2], ['flow', false, w - this.notchSize(), h / 2]]; return [['flow', true, 0, h / 2], ['flow', false, w - this.notchSize(), h / 2]];
} }
}; }
Block.prototype.notchSize = function () { notchSize () {
return 11; return 11;
}; }
////////////////////////////////////////// //////////////////////////////////////////
// Connect / Disconnect // Connect / Disconnect
///////////////////////////////////////// /////////////////////////////////////////
Block.prototype.connectBlock = function (myn, you, yourn) { connectBlock (myn, you, yourn) {
if (this.isConnectedAfterFirst(myn, you, yourn)) { if (this.isConnectedAfterFirst(myn, you, yourn)) {
return; return;
} }
@ -360,24 +372,24 @@ Block.prototype.connectBlock = function (myn, you, yourn) {
last.next = theend; last.next = theend;
theend.prev = last; theend.prev = last;
} }
}; }
Block.prototype.getMyDock = function (dockn) { getMyDock (dockn) {
var myprops = this.cShape ? ['prev', 'inside', 'next'] : ['prev', 'next']; var myprops = this.cShape ? ['prev', 'inside', 'next'] : ['prev', 'next'];
return this[myprops[dockn]]; return this[myprops[dockn]];
}; }
Block.prototype.setMyDock = function (dockn, you) { setMyDock (dockn, you) {
var myprops = this.cShape ? ['prev', 'inside', 'next'] : ['prev', 'next']; var myprops = this.cShape ? ['prev', 'inside', 'next'] : ['prev', 'next'];
this[myprops[dockn]] = you; this[myprops[dockn]] = you;
}; }
Block.prototype.getMyDockNum = function (you) { getMyDockNum (you) {
var connections = this.cShape ? [this.prev, this.inside, this.next] : [this.prev, this.next]; var connections = this.cShape ? [this.prev, this.inside, this.next] : [this.prev, this.next];
return connections.indexOf(you); return connections.indexOf(you);
}; }
Block.prototype.isConnectedAfterFirst = function (myn, you) { isConnectedAfterFirst (myn, you) {
if (myn == 0) { if (myn == 0) {
return false; return false;
} }
@ -392,23 +404,23 @@ Block.prototype.isConnectedAfterFirst = function (myn, you) {
var thefirst = this.findFirst(); var thefirst = this.findFirst();
thefirst.connectBlock(0, prev, n); thefirst.connectBlock(0, prev, n);
return true; return true;
}; }
Block.prototype.findLast = function () { findLast () {
if (this.next == null) { if (this.next == null) {
return this; return this;
} }
return this.next.findLast(); return this.next.findLast();
}; }
Block.prototype.findFirst = function () { findFirst () {
if (this.prev == null) { if (this.prev == null) {
return this; return this;
} }
return this.prev.findFirst(); return this.prev.findFirst();
}; }
Block.prototype.connectLast = function (myn, you, yourn) { connectLast (myn, you, yourn) {
if (myn != 0) { if (myn != 0) {
return; return;
} }
@ -436,9 +448,9 @@ Block.prototype.connectLast = function (myn, you, yourn) {
} }
yourtail.prev = mylast; yourtail.prev = mylast;
} }
}; }
Block.prototype.detachBlock = function () { detachBlock () {
var you = this.prev; var you = this.prev;
if (you == null) { if (you == null) {
return; return;
@ -449,26 +461,26 @@ Block.prototype.detachBlock = function () {
} else { } else {
you.next = null; you.next = null;
} }
}; }
////////////////////////////////////////// //////////////////////////////////////////
// Move // Move
///////////////////////////////////////// /////////////////////////////////////////
Block.prototype.moveBlock = function (dx, dy) { moveBlock (dx, dy) {
this.div.top = dy; this.div.top = dy;
this.div.left = dx; this.div.left = dx;
this.div.style.webkitTransform = 'translate3d(' + this.div.left + 'px,' + this.div.top + 'px, 0)'; this.div.style.webkitTransform = 'translate3d(' + this.div.left + 'px,' + this.div.top + 'px, 0)';
}; }
///////////////////////////////// /////////////////////////////////
// Forever and Repeat // Forever and Repeat
//////////////////////////////// ////////////////////////////////
// Repeat size 176 by 82 // Repeat size 176 by 82
Block.prototype.redrawRepeat = function () { redrawRepeat () {
this.redrawShape(this.blockshape, this.image); this.redrawShape(this.blockshape, this.image);
if (this.blocktype.indexOf('caret') < 0) { if (this.blocktype.indexOf('caret') < 0) {
this.redrawShape(this.shadow, this.shadowimg); this.redrawShape(this.shadow, this.shadowimg);
@ -483,9 +495,9 @@ Block.prototype.redrawRepeat = function () {
this.arg.div.style.left = (this.blockshape.width / window.devicePixelRatio - 66 * this.scale) + 'px'; this.arg.div.style.left = (this.blockshape.width / window.devicePixelRatio - 66 * this.scale) + 'px';
this.blockicon.style.top = dy + 'px'; this.blockicon.style.top = dy + 'px';
this.arg.div.style.top = (this.blockshape.height / window.devicePixelRatio - 11 * this.scale) + 'px'; this.arg.div.style.top = (this.blockshape.height / window.devicePixelRatio - 11 * this.scale) + 'px';
}; }
Block.prototype.redrawShape = function (cnv, img) { redrawShape (cnv, img) {
setCanvasSize(this.div, setCanvasSize(this.div,
(92 + this.hrubberband + 84) * this.scale, (92 + this.hrubberband + 84) * this.scale,
(100 + this.vrubberband) * this.scale); (100 + this.vrubberband) * this.scale);
@ -516,4 +528,5 @@ Block.prototype.redrawShape = function (cnv, img) {
45 * scaleAndRatio, 53 * scaleAndRatio); 45 * scaleAndRatio, 53 * scaleAndRatio);
ctx.drawImage(img, 93, 29, img.width - 93, 53, 92 * scaleAndRatio + this.hrubberband * scaleAndRatio, ctx.drawImage(img, 93, 29, img.width - 93, 53, 92 * scaleAndRatio + this.hrubberband * scaleAndRatio,
29 * scaleAndRatio + this.vrubberband * scaleAndRatio, 83 * scaleAndRatio, 53 * scaleAndRatio); 29 * scaleAndRatio + this.vrubberband * scaleAndRatio, 83 * scaleAndRatio, 53 * scaleAndRatio);
}; }
}

View file

@ -1,3 +1,12 @@
import ScratchJr from '../ScratchJr';
import BlockSpecs from './BlockSpecs';
import Menu from './Menu';
import Undo from '../ui/Undo';
import {setCanvasSize, setProps, writeText, scaleMultiplier,
newHTML, newDiv, newCanvas, getStringSize, isTablet,
newP, globalx, globaly} from '../../utils/lib';
import Localization from '../../utils/Localization';
/* /*
Argument types Argument types
@ -9,7 +18,8 @@ r: number for recorded sound block
p: page icons p: page icons
*/ */
var BlockArg = function (block) { export default class BlockArg {
constructor (block) {
this.daddy = block; this.daddy = block;
this.type = 'blockarg'; this.type = 'blockarg';
this.argType = block.spec[3]; this.argType = block.spec[3];
@ -69,43 +79,43 @@ var BlockArg = function (block) {
default: default:
break; break;
} }
}; }
BlockArg.prototype.update = function () { update () {
if (this.argType == 'r') { if (this.argType == 'r') {
this.div.childNodes[0].textContent = this.argValue; this.div.childNodes[0].textContent = this.argValue;
} }
if (this.arg && (this.argType == 'p')) { if (this.arg && (this.argType == 'p')) {
this.arg.updateIcon(); this.arg.updateIcon();
} }
}; }
BlockArg.prototype.getScreenPt = function () { getScreenPt () {
return { return {
x: globalx(this.daddy.div), x: globalx(this.daddy.div),
y: globaly(this.daddy.div) y: globaly(this.daddy.div)
}; };
}; }
BlockArg.prototype.addNumArg = function () { addNumArg () {
var str = this.argValue.toString(); var str = this.argValue.toString();
if (this.daddy.inpalette) { if (this.daddy.inpalette) {
return this.addLabel(str, false); return this.addLabel(str, false);
} else { } else {
return this.addNumArgument(str); return this.addNumArgument(str);
} }
}; }
BlockArg.prototype.addTextArg = function () { addTextArg () {
var str = this.argValue.toString(); var str = this.argValue.toString();
if (this.daddy.inpalette) { if (this.daddy.inpalette) {
return this.addLabel(str, true); return this.addLabel(str, true);
} else { } else {
return this.addTextArgument(str, true); return this.addTextArgument(str, true);
} }
}; }
BlockArg.prototype.addLabel = function (str, isText) { addLabel (str, isText) {
var scale = this.daddy.scale; var scale = this.daddy.scale;
var dx = isText ? 8 : 16; var dx = isText ? 8 : 16;
var dy = 57; var dy = 57;
@ -153,9 +163,9 @@ BlockArg.prototype.addLabel = function (str, isText) {
writeText(ctx, font, '#77787b', str, h * window.devicePixelRatio - 3, writeText(ctx, font, '#77787b', str, h * window.devicePixelRatio - 3,
Math.round((w * window.devicePixelRatio - lsize) / 2)); Math.round((w * window.devicePixelRatio - lsize) / 2));
return div; return div;
}; }
BlockArg.prototype.addNumArgument = function (str) { addNumArgument (str) {
var div = newHTML('div', 'numfield', this.daddy.div); var div = newHTML('div', 'numfield', this.daddy.div);
if (this.daddy.blocktype == 'repeat') { if (this.daddy.blocktype == 'repeat') {
setProps(div.style, { setProps(div.style, {
@ -168,53 +178,55 @@ BlockArg.prototype.addNumArgument = function (str) {
ti.owner = this; ti.owner = this;
ti.textContent = str; ti.textContent = str;
this.arg = div; this.arg = div;
// Expand the parent div to incorporate the size of the button, else on Android 4.2 the bottom part of the button // Expand the parent div to incorporate the size of the button,
// else on Android 4.2 the bottom part of the button
// will not be clickable. // will not be clickable.
div.parentNode.height += 10 * window.devicePixelRatio; div.parentNode.height += 10 * window.devicePixelRatio;
setCanvasSize(div.parentNode, div.parentNode.width, div.parentNode.height); setCanvasSize(div.parentNode, div.parentNode.width, div.parentNode.height);
return div; return div;
}; }
BlockArg.prototype.addTextArgument = function (str) { addTextArgument (str) {
var div = newHTML('div', 'textfield', this.daddy.div); var div = newHTML('div', 'textfield', this.daddy.div);
var ti = newHTML('h3', undefined, div); var ti = newHTML('h3', undefined, div);
this.input = ti; this.input = ti;
ti.owner = this; ti.owner = this;
ti.textContent = str; ti.textContent = str;
this.arg = div; this.arg = div;
// Expand the parent div to incorporate the size of the button, else on Android 4.2 the bottom part of the button // Expand the parent div to incorporate the size of the button,
// else on Android 4.2 the bottom part of the button
// will not be clickable. // will not be clickable.
div.parentNode.height += 10 * window.devicePixelRatio; div.parentNode.height += 10 * window.devicePixelRatio;
setCanvasSize(div.parentNode, div.parentNode.width, div.parentNode.height); setCanvasSize(div.parentNode, div.parentNode.width, div.parentNode.height);
return div; return div;
}; }
BlockArg.prototype.setValue = function (val) { setValue (val) {
if (!this.input) { if (!this.input) {
return; return;
} }
this.argValue = val; this.argValue = val;
this.input.textContent = val; this.input.textContent = val;
}; }
BlockArg.prototype.isText = function () { isText () {
return (this.argType != 'n'); return (this.argType != 'n');
}; }
///////////////////////////////// /////////////////////////////////
// Menu drop downs // Menu drop downs
////////////////////////////// //////////////////////////////
BlockArg.prototype.getIconFrom = function (key, list) { getIconFrom (key, list) {
for (var i = 0; i < list.length; i++) { for (var i = 0; i < list.length; i++) {
if (list[i].indexOf(key) > -1) { if (list[i].indexOf(key) > -1) {
return list[i]; return list[i];
} }
} }
return list[0]; return list[0];
}; }
BlockArg.prototype.addImageMenu = function (fcn) { addImageMenu (fcn) {
this.drawChoice(this.daddy.blockicon); this.drawChoice(this.daddy.blockicon);
this.button = this.addPressButton(); this.button = this.addPressButton();
if (!this.daddy.inpalette) { if (!this.daddy.inpalette) {
@ -235,9 +247,9 @@ BlockArg.prototype.addImageMenu = function (fcn) {
setCanvasSize(this.button.parentNode, this.button.parentNode.width, this.button.parentNode.height); setCanvasSize(this.button.parentNode, this.button.parentNode.width, this.button.parentNode.height);
} }
return this.daddy.blockicon; return this.daddy.blockicon;
}; }
BlockArg.prototype.drawChoice = function (cnv) { drawChoice (cnv) {
var ctx = cnv.getContext('2d'); var ctx = cnv.getContext('2d');
ctx.clearRect(0, 0, cnv.width, cnv.height); ctx.clearRect(0, 0, cnv.width, cnv.height);
var icon = BlockSpecs.getImageFrom('assets/blockicons/' + this.icon, 'svg'); var icon = BlockSpecs.getImageFrom('assets/blockicons/' + this.icon, 'svg');
@ -254,9 +266,9 @@ BlockArg.prototype.drawChoice = function (cnv) {
icon.height * scale * window.devicePixelRatio); icon.height * scale * window.devicePixelRatio);
} }
return cnv; return cnv;
}; }
BlockArg.prototype.addPressButton = function () { addPressButton () {
var scale = this.daddy.scale; var scale = this.daddy.scale;
var dx; var dx;
if (this.daddy.inpalette) { if (this.daddy.inpalette) {
@ -283,9 +295,9 @@ BlockArg.prototype.addPressButton = function () {
ctx.drawImage(img, 0, 0); ctx.drawImage(img, 0, 0);
} }
return field; return field;
}; }
BlockArg.prototype.pressDropDown = function (e, fcn) { pressDropDown (e, fcn) {
if (isTablet && e.touches && (e.touches.length > 1)) { if (isTablet && e.touches && (e.touches.length > 1)) {
return; return;
} }
@ -299,15 +311,16 @@ BlockArg.prototype.pressDropDown = function (e, fcn) {
return; return;
} }
Menu.openDropDown(this.daddy.div, fcn); Menu.openDropDown(this.daddy.div, fcn);
}; }
BlockArg.prototype.closePictureMenu = function (e, mu, b, c) { closePictureMenu (e, mu, b, c) {
e.preventDefault(); e.preventDefault();
var value = b.owner.arg.argValue; var value = b.owner.arg.argValue;
b.owner.arg.argValue = c.substring(c.indexOf('_') + 1, c.length); b.owner.arg.argValue = c.substring(c.indexOf('_') + 1, c.length);
var ctx = b.owner.blockicon.getContext('2d'); var ctx = b.owner.blockicon.getContext('2d');
b.icon = BlockSpecs.getImageFrom('assets/blockicons/' + c, 'svg'); b.icon = BlockSpecs.getImageFrom('assets/blockicons/' + c, 'svg');
ctx.clearRect(0, 0, 85 * scaleMultiplier * window.devicePixelRatio, 66 * scaleMultiplier * window.devicePixelRatio); ctx.clearRect(0, 0, 85 * scaleMultiplier * window.devicePixelRatio,
66 * scaleMultiplier * window.devicePixelRatio);
if (!b.icon.complete) { if (!b.icon.complete) {
b.icon.onload = function () { b.icon.onload = function () {
var w = b.icon.width; var w = b.icon.width;
@ -337,15 +350,16 @@ BlockArg.prototype.closePictureMenu = function (e, mu, b, c) {
ScratchJr.storyStart('BlockArg.prototype.closePictureMenu'); ScratchJr.storyStart('BlockArg.prototype.closePictureMenu');
} }
Menu.openMenu = undefined; Menu.openMenu = undefined;
}; }
BlockArg.prototype.menuCloseSpeeds = function (e, mu, b, c) { menuCloseSpeeds (e, mu, b, c) {
e.preventDefault(); e.preventDefault();
var value = b.owner.arg.argValue; var value = b.owner.arg.argValue;
b.owner.arg.argValue = BlockSpecs.speeds.indexOf(c); b.owner.arg.argValue = BlockSpecs.speeds.indexOf(c);
var ctx = b.owner.blockicon.getContext('2d'); var ctx = b.owner.blockicon.getContext('2d');
b.icon = BlockSpecs.getImageFrom('assets/blockicons/' + c, 'svg'); b.icon = BlockSpecs.getImageFrom('assets/blockicons/' + c, 'svg');
ctx.clearRect(0, 0, 64 * scaleMultiplier * window.devicePixelRatio, 64 * scaleMultiplier * window.devicePixelRatio); ctx.clearRect(0, 0, 64 * scaleMultiplier * window.devicePixelRatio,
64 * scaleMultiplier * window.devicePixelRatio);
// On Android 4.2, clearRect does not work right away. Need to tickle the DOM // On Android 4.2, clearRect does not work right away. Need to tickle the DOM
b.owner.blockicon.style.display = 'none'; b.owner.blockicon.style.display = 'none';
b.owner.blockicon.offsetHeight; b.owner.blockicon.offsetHeight;
@ -377,13 +391,13 @@ BlockArg.prototype.menuCloseSpeeds = function (e, mu, b, c) {
ScratchJr.storyStart('BlockArg.prototype.menuCloseSpeeds'); ScratchJr.storyStart('BlockArg.prototype.menuCloseSpeeds');
} }
Menu.openMenu = undefined; Menu.openMenu = undefined;
}; }
////////////////////////// //////////////////////////
// Page Icon // Page Icon
////////////////////////// //////////////////////////
BlockArg.prototype.pageIcon = function (num) { pageIcon (num) {
var dpr = window.devicePixelRatio; var dpr = window.devicePixelRatio;
var page = ScratchJr.stage.pages[num - 1]; var page = ScratchJr.stage.pages[num - 1];
var icon = document.createElement('canvas'); var icon = document.createElement('canvas');
@ -436,9 +450,9 @@ BlockArg.prototype.pageIcon = function (num) {
ictx.fill(); ictx.fill();
writeText(ictx, 'bold ' + (12 * dpr) + 'px ' + Settings.blockArgFont, 'white', page.num, 26 * dpr, 58 * dpr); writeText(ictx, 'bold ' + (12 * dpr) + 'px ' + Settings.blockArgFont, 'white', page.num, 26 * dpr, 58 * dpr);
return icon; return icon;
}; }
BlockArg.prototype.updateIcon = function () { updateIcon () {
var num = this.argValue; var num = this.argValue;
var page = ScratchJr.stage.pages[num - 1]; var page = ScratchJr.stage.pages[num - 1];
page.num = num; page.num = num;
@ -447,4 +461,5 @@ BlockArg.prototype.updateIcon = function () {
var ctx = block.blockshape.getContext('2d'); var ctx = block.blockshape.getContext('2d');
ctx.drawImage(this.div, 0, 0, this.div.width, this.div.height, 0, 0, ctx.drawImage(this.div, 0, 0, this.div.width, this.div.height, 0, 0,
this.div.width * block.scale, this.div.height * block.scale); this.div.width * block.scale, this.div.height * block.scale);
}; }
}

View file

@ -1,4 +1,21 @@
var Page = function (id, data, fcn) { import ScratchJr from '../ScratchJr';
import Project from '../../ui/Project';
import Thumbs from '../../ui/Thumbs';
import UI from '../../ui/UI';
import Sprite from './Sprite';
import Palette from './Palette';
import BlockSpecs from '../blocks/BlockSpecs';
import iOS from '../../iPad/iOS';
import IO from '../../iPad/IO';
import Undo from '../ui/Undo';
import Matrix from '../geom/Matrix';
import Vector from '../geom/Vector';
import {newHTML, newDiv, gn,
setCanvasSizeScaledToWindowDocumentHeight,
DEGTOR, getIdFor, setProps, isTablet} from '../../utils/lib';
export default class Page {
constructor (id, data, fcn) {
var container = ScratchJr.stage.pagesdiv; var container = ScratchJr.stage.pagesdiv;
this.div = newHTML('div', 'stagepage', container); // newDiv(container,0,0, 480, 360, {position: 'absolute'}); this.div = newHTML('div', 'stagepage', container); // newDiv(container,0,0, 480, 360, {position: 'absolute'});
this.div.owner = this; this.div.owner = this;
@ -19,9 +36,9 @@ var Page = function (id, data, fcn) {
} else { } else {
this.loadPageData(data, fcn); this.loadPageData(data, fcn);
} }
}; }
Page.prototype.loadPageData = function (data, fcn) { loadPageData (data, fcn) {
this.currentSpriteName = data.lastSprite; this.currentSpriteName = data.lastSprite;
if (data.textstartat) { if (data.textstartat) {
this.textstartat = Number(data.textstartat); this.textstartat = Number(data.textstartat);
@ -60,14 +77,14 @@ Page.prototype.loadPageData = function (data, fcn) {
fcn(); fcn();
} }
} }
}; }
Page.prototype.emptyPage = function () { emptyPage () {
this.clearBackground(); this.clearBackground();
this.createCat(); this.createCat();
}; }
Page.prototype.setCurrentSprite = function (spr) { // set the sprite and toggles UI if no sprite is available setCurrentSprite (spr) { // set the sprite and toggles UI if no sprite is available
if (ScratchJr.getSprite()) { if (ScratchJr.getSprite()) {
ScratchJr.getSprite().unselect(); ScratchJr.getSprite().unselect();
} }
@ -82,15 +99,15 @@ Page.prototype.setCurrentSprite = function (spr) { // set the sprite and toggles
Palette.hide(); Palette.hide();
gn('scripts').style.display = 'none'; gn('scripts').style.display = 'none';
} }
}; }
Page.prototype.clearBackground = function () { clearBackground () {
while (this.bkg.childElementCount > 0) { while (this.bkg.childElementCount > 0) {
this.bkg.removeChild(this.bkg.childNodes[0]); this.bkg.removeChild(this.bkg.childNodes[0]);
} }
}; }
Page.prototype.setBackground = function (name, fcn) { setBackground (name, fcn) {
if (name == 'undefined') { if (name == 'undefined') {
return; return;
} }
@ -136,18 +153,18 @@ Page.prototype.setBackground = function (name, fcn) {
}); });
} }
} }
}; }
Page.prototype.setSVG = function (str) { setSVG (str) {
var xmlDoc = new DOMParser().parseFromString(str, 'text/xml'); var xmlDoc = new DOMParser().parseFromString(str, 'text/xml');
var extxml = document.importNode(xmlDoc.documentElement, true); var extxml = document.importNode(xmlDoc.documentElement, true);
if (extxml.childNodes[0].nodeName == '#comment') { if (extxml.childNodes[0].nodeName == '#comment') {
extxml.removeChild(extxml.childNodes[0]); extxml.removeChild(extxml.childNodes[0]);
} }
this.svg = extxml; this.svg = extxml;
}; }
Page.prototype.setBackgroundImage = function (url, fcn) { setBackgroundImage (url, fcn) {
var img = document.createElement('img'); var img = document.createElement('img');
img.src = url; img.src = url;
this.bkg.originalImg = img.cloneNode(false); this.bkg.originalImg = img.cloneNode(false);
@ -177,35 +194,35 @@ Page.prototype.setBackgroundImage = function (url, fcn) {
fcn(); fcn();
} }
} }
}; }
Page.prototype.setPageSprites = function (showstate) { setPageSprites (showstate) {
var list = JSON.parse(this.sprites); var list = JSON.parse(this.sprites);
for (var i = 0; i < list.length; i++) { for (var i = 0; i < list.length; i++) {
gn(list[i]).style.visibility = showstate; gn(list[i]).style.visibility = showstate;
} }
}; }
Page.prototype.redoChangeBkg = function (data) { redoChangeBkg (data) {
var me = this; var me = this;
var md5 = data[this.id].md5 ? data[this.id].md5 : 'none'; var md5 = data[this.id].md5 ? data[this.id].md5 : 'none';
this.setBackground(md5, me.updateThumb); this.setBackground(md5, me.updateThumb);
}; }
////////////////////////////////////// //////////////////////////////////////
// page thumbnail // page thumbnail
///////////////////////////////////// /////////////////////////////////////
Page.prototype.updateThumb = function (page) { updateThumb (page) {
var me = page ? page : ScratchJr.stage.currentPage; var me = page ? page : ScratchJr.stage.currentPage;
if (!me.thumbnail) { if (!me.thumbnail) {
return; return;
} }
var c = me.thumbnail.childNodes[0].childNodes[0]; var c = me.thumbnail.childNodes[0].childNodes[0];
me.setPageThumb(c); me.setPageThumb(c);
}; }
Page.prototype.pageThumbnail = function (p) { pageThumbnail (p) {
var tb = newHTML('div', 'pagethumb', p); var tb = newHTML('div', 'pagethumb', p);
tb.setAttribute('id', getIdFor('pagethumb')); tb.setAttribute('id', getIdFor('pagethumb'));
tb.owner = this.id; tb.owner = this.id;
@ -228,9 +245,9 @@ Page.prototype.pageThumbnail = function (p) {
} }
this.thumbnail = tb; this.thumbnail = tb;
return tb; return tb;
}; }
Page.prototype.setPageThumb = function (c) { setPageThumb (c) {
var w0, h0; var w0, h0;
if (Settings.edition == 'PBS') { if (Settings.edition == 'PBS') {
w0 = 136; w0 = 136;
@ -272,17 +289,17 @@ Page.prototype.setPageThumb = function (c) {
ctx.drawImage(BlockSpecs.canvasMask, 0, 0, w, h); ctx.drawImage(BlockSpecs.canvasMask, 0, 0, w, h);
ctx.restore(); ctx.restore();
} }
}; }
Page.prototype.stampSpriteAt = function (ctx, spr, scale) { stampSpriteAt (ctx, spr, scale) {
if (!spr.shown) { if (!spr.shown) {
return; return;
} }
var img = (spr.type == 'sprite') ? spr.originalImg : spr.outline; var img = (spr.type == 'sprite') ? spr.originalImg : spr.outline;
this.drawSpriteImage(ctx, img, spr, scale); this.drawSpriteImage(ctx, img, spr, scale);
}; }
Page.prototype.drawSpriteImage = function (ctx, img, spr, scale) { drawSpriteImage (ctx, img, spr, scale) {
if (!spr.shown) { if (!spr.shown) {
return; return;
} }
@ -312,9 +329,9 @@ Page.prototype.drawSpriteImage = function (ctx, img, spr, scale) {
})); }));
ctx.drawImage(img, 0, 0, imgw, imgh, pos.x, pos.y, Math.floor(sw * scale), Math.floor(sh * scale)); ctx.drawImage(img, 0, 0, imgw, imgh, pos.x, pos.y, Math.floor(sw * scale), Math.floor(sh * scale));
ctx.restore(); ctx.restore();
}; }
Page.prototype.getMatrixFor = function (spr) { getMatrixFor (spr) {
var sx = new Matrix(); var sx = new Matrix();
var angle = spr.angle ? -spr.angle : 0; var angle = spr.angle ? -spr.angle : 0;
if (spr.flip) { if (spr.flip) {
@ -324,13 +341,13 @@ Page.prototype.getMatrixFor = function (spr) {
var rx = new Matrix(); var rx = new Matrix();
rx.rotate(angle); rx.rotate(angle);
return sx.multiply(rx); return sx.multiply(rx);
}; }
///////////////////// /////////////////////
// Saving // Saving
///////////////////// /////////////////////
Page.prototype.encodePage = function () { encodePage () {
var p = this.div; var p = this.div;
var spritelist = JSON.parse(this.sprites); var spritelist = JSON.parse(this.sprites);
var data = {}; var data = {};
@ -342,7 +359,8 @@ Page.prototype.encodePage = function () {
} }
data.num = this.num; data.num = this.num;
this.currentSpriteName = !this.currentSpriteName ? this.currentSpriteName = !this.currentSpriteName ?
undefined : (gn(this.currentSpriteName).owner.type == 'sprite') ? this.currentSpriteName : this.getSprites()[0]; undefined : (gn(this.currentSpriteName).owner.type == 'sprite') ?
this.currentSpriteName : this.getSprites()[0];
data.lastSprite = this.currentSpriteName; data.lastSprite = this.currentSpriteName;
for (var j = 0; j < spritelist.length; j++) { for (var j = 0; j < spritelist.length; j++) {
data[spritelist[j]] = Project.encodeSprite(spritelist[j]); data[spritelist[j]] = Project.encodeSprite(spritelist[j]);
@ -356,9 +374,9 @@ Page.prototype.encodePage = function () {
} }
data.layers = layers; data.layers = layers;
return data; return data;
}; }
Page.prototype.getSprites = function () { getSprites () {
var spritelist = JSON.parse(this.sprites); var spritelist = JSON.parse(this.sprites);
var res = []; var res = [];
for (var i = 0; i < spritelist.length; i++) { for (var i = 0; i < spritelist.length; i++) {
@ -367,14 +385,14 @@ Page.prototype.getSprites = function () {
} }
} }
return res; return res;
}; }
///////////////////////////// /////////////////////////////
// Object creation // Object creation
///////////////////////////// /////////////////////////////
Page.prototype.createText = function () { createText () {
var textAttr = { var textAttr = {
shown: true, shown: true,
type: 'text', type: 'text',
@ -399,16 +417,16 @@ Page.prototype.createText = function () {
textAttr.page = this; textAttr.page = this;
textAttr.id = getIdFor('Text'); textAttr.id = getIdFor('Text');
new Sprite(textAttr); new Sprite(textAttr);
}; }
Page.prototype.createCat = function () { createCat () {
var sprAttr = UI.mascotData(ScratchJr.stage.currentPage); var sprAttr = UI.mascotData(ScratchJr.stage.currentPage);
Project.mediaCount++; Project.mediaCount++;
var me = this; var me = this;
new Sprite(sprAttr, me.pageAdded); new Sprite(sprAttr, me.pageAdded);
}; }
Page.prototype.update = function (spr) { update (spr) {
if (spr) { if (spr) {
Undo.record({ Undo.record({
action: 'modify', action: 'modify',
@ -428,9 +446,9 @@ Page.prototype.update = function (spr) {
Thumbs.updateSprites(); Thumbs.updateSprites();
} }
Thumbs.updatePages(); Thumbs.updatePages();
}; }
Page.prototype.updateBkg = function () { updateBkg () {
var me = ScratchJr.stage.currentPage; var me = ScratchJr.stage.currentPage;
ScratchJr.storyStart('Page.prototype.updateBkg'); ScratchJr.storyStart('Page.prototype.updateBkg');
Undo.record({ Undo.record({
@ -439,17 +457,17 @@ Page.prototype.updateBkg = function () {
who: me.id who: me.id
}); });
Thumbs.updatePages(); Thumbs.updatePages();
}; }
Page.prototype.spriteAdded = function (spr) { spriteAdded (spr) {
var me = spr.div.parentNode.owner; var me = spr.div.parentNode.owner;
me.setCurrentSprite(spr); me.setCurrentSprite(spr);
me.update(spr); me.update(spr);
UI.spriteInView(spr); UI.spriteInView(spr);
ScratchJr.onHold = false; ScratchJr.onHold = false;
}; }
Page.prototype.pageAdded = function (spr) { pageAdded (spr) {
var me = spr.div.parentNode.owner; var me = spr.div.parentNode.owner;
Project.mediaCount--; Project.mediaCount--;
me.setCurrentSprite(spr); me.setCurrentSprite(spr);
@ -463,9 +481,9 @@ Page.prototype.pageAdded = function (spr) {
} }
Thumbs.updateSprites(); Thumbs.updateSprites();
Thumbs.updatePages(); Thumbs.updatePages();
}; }
Page.prototype.addSprite = function (scale, md5, cname) { addSprite (scale, md5, cname) {
ScratchJr.onHold = true; ScratchJr.onHold = true;
var sprAttr = { var sprAttr = {
flip: false, flip: false,
@ -490,13 +508,13 @@ Page.prototype.addSprite = function (scale, md5, cname) {
sprAttr.name = cname; sprAttr.name = cname;
sprAttr.md5 = md5; sprAttr.md5 = md5;
new Sprite(sprAttr, this.spriteAdded); new Sprite(sprAttr, this.spriteAdded);
}; }
Page.prototype.createSprite = function (data) { createSprite (data) {
new Sprite(data, this.spriteAdded); new Sprite(data, this.spriteAdded);
}; }
Page.prototype.modifySprite = function (md5, cid, sid) { modifySprite (md5, cid, sid) {
var sprite = gn(unescape(sid)).owner; var sprite = gn(unescape(sid)).owner;
if (!sprite) { if (!sprite) {
sprite = ScratchJr.getSprite(); sprite = ScratchJr.getSprite();
@ -508,9 +526,9 @@ Page.prototype.modifySprite = function (md5, cid, sid) {
function gotImage (dataurl) { function gotImage (dataurl) {
sprite.setCostume(dataurl, me.spriteAdded); sprite.setCostume(dataurl, me.spriteAdded);
} }
}; }
Page.prototype.modifySpriteName = function (cid, sid) { modifySpriteName (cid, sid) {
var sprite = gn(unescape(sid)).owner; var sprite = gn(unescape(sid)).owner;
if (!sprite) { if (!sprite) {
sprite = ScratchJr.getSprite(); sprite = ScratchJr.getSprite();
@ -523,4 +541,5 @@ Page.prototype.modifySpriteName = function (cid, sid) {
who: sprite.id who: sprite.id
}); });
ScratchJr.storyStart('Page.prototype.modifySpriteName'); ScratchJr.storyStart('Page.prototype.modifySpriteName');
}; }
}

View file

@ -1,11 +1,17 @@
var Runtime = function () { import ScratchJr from '../ScratchJr';
import Project from '../../ui/Project';
import Prims from './Prims';
import Thread from './Thread';
export default class Runtime {
constructor () {
this.threadsRunning = []; this.threadsRunning = [];
this.thread = undefined; this.thread = undefined;
this.intervalId = undefined; this.intervalId = undefined;
this.yield = false; this.yield = false;
}; }
Runtime.prototype.beginTimer = function () { beginTimer () {
if (this.intervalId != null) { if (this.intervalId != null) {
window.clearInterval(this.intervalId); window.clearInterval(this.intervalId);
} }
@ -16,9 +22,9 @@ Runtime.prototype.beginTimer = function () {
Project.saving = false; Project.saving = false;
// Prims.time = (new Date() - 0); // Prims.time = (new Date() - 0);
this.threadsRunning = []; this.threadsRunning = [];
}; }
Runtime.prototype.tickTask = function () { tickTask () {
ScratchJr.updateRunStopButtons(); ScratchJr.updateRunStopButtons();
if (this.threadsRunning.length < 1) { if (this.threadsRunning.length < 1) {
return; return;
@ -33,9 +39,9 @@ Runtime.prototype.tickTask = function () {
for (var j = 0; j < this.threadsRunning.length; j++) { for (var j = 0; j < this.threadsRunning.length; j++) {
this.step(j); this.step(j);
} }
}; }
Runtime.prototype.inactive = function () { inactive () {
if (this.threadsRunning.length < 1) { if (this.threadsRunning.length < 1) {
return true; return true;
} }
@ -48,14 +54,15 @@ Runtime.prototype.inactive = function () {
if (t.isRunning && (t.firstBlock.blocktype != 'ontouch')) { if (t.isRunning && (t.firstBlock.blocktype != 'ontouch')) {
inactive = false; inactive = false;
} }
if ((t.firstBlock.blocktype == 'ontouch') && (t.thisblock != null) && (t.thisblock.blocktype != 'ontouch')) { if ((t.firstBlock.blocktype == 'ontouch') && (t.thisblock != null)
&& (t.thisblock.blocktype != 'ontouch')) {
inactive = false; inactive = false;
} }
} }
return inactive; return inactive;
}; }
Runtime.prototype.step = function (n) { step (n) {
this.yield = false; this.yield = false;
this.thread = this.threadsRunning[n]; this.thread = this.threadsRunning[n];
while (true) { // eslint-disable-line no-constant-condition while (true) { // eslint-disable-line no-constant-condition
@ -77,36 +84,36 @@ Runtime.prototype.step = function (n) {
this.runPrim(); this.runPrim();
} }
} }
}; }
Runtime.prototype.addRunScript = function (spr, b) { addRunScript (spr, b) {
this.restartThread(spr, b); this.restartThread(spr, b);
}; }
Runtime.prototype.stopThreads = function () { stopThreads () {
for (var i in this.threadsRunning) { for (var i in this.threadsRunning) {
this.threadsRunning[i].stop(); this.threadsRunning[i].stop();
} }
this.threadsRunning = []; this.threadsRunning = [];
}; }
Runtime.prototype.stopThreadBlock = function (b) { stopThreadBlock (b) {
for (var i in this.threadsRunning) { for (var i in this.threadsRunning) {
if (this.threadsRunning[i].firstBlock == b) { if (this.threadsRunning[i].firstBlock == b) {
this.threadsRunning[i].stop(); this.threadsRunning[i].stop();
} }
} }
}; }
Runtime.prototype.stopThreadSprite = function (spr) { stopThreadSprite (spr) {
for (var i in this.threadsRunning) { for (var i in this.threadsRunning) {
if (this.threadsRunning[i].spr == spr) { if (this.threadsRunning[i].spr == spr) {
this.threadsRunning[i].stop(); this.threadsRunning[i].stop();
} }
} }
}; }
Runtime.prototype.removeRunScript = function (spr) { removeRunScript (spr) {
var res = []; var res = [];
for (var i in this.threadsRunning) { for (var i in this.threadsRunning) {
if (this.threadsRunning[i].spr == spr) { if (this.threadsRunning[i].spr == spr) {
@ -123,9 +130,9 @@ Runtime.prototype.removeRunScript = function (spr) {
} }
} }
return res; return res;
}; }
Runtime.prototype.runPrim = function () { runPrim () {
if (this.thread.oldblock != null) { if (this.thread.oldblock != null) {
this.thread.oldblock.unhighlight(); this.thread.oldblock.unhighlight();
} }
@ -142,9 +149,9 @@ Runtime.prototype.runPrim = function () {
Prims.time = (new Date() - 0); Prims.time = (new Date() - 0);
token(this.thread); token(this.thread);
} }
}; }
Runtime.prototype.endCase = function () { endCase () {
if (this.thread.oldblock != null) { if (this.thread.oldblock != null) {
this.thread.oldblock.unhighlight(); this.thread.oldblock.unhighlight();
} }
@ -155,9 +162,9 @@ Runtime.prototype.endCase = function () {
this.thread.thisblock = thing; this.thread.thisblock = thing;
this.runPrim(); this.runPrim();
} }
}; }
Runtime.prototype.restartThread = function (spr, b, active) { restartThread (spr, b, active) {
var newThread = new Thread(spr, b); var newThread = new Thread(spr, b);
var wasRunning = false; var wasRunning = false;
for (var i = 0; i < this.threadsRunning.length; i++) { for (var i = 0; i < this.threadsRunning.length; i++) {
@ -176,4 +183,5 @@ Runtime.prototype.restartThread = function (spr, b, active) {
this.threadsRunning.push(newThread); this.threadsRunning.push(newThread);
} }
return newThread; return newThread;
}; }
}

View file

@ -7,15 +7,38 @@
// d. Create Mask for pixel detection and cache it on the browser // d. Create Mask for pixel detection and cache it on the browser
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
var Sprite = function (attr, whenDone) { import ScratchJr from '../ScratchJr';
import Project from '../../ui/Project';
import Thumbs from '../../ui/Thumbs';
import UI from '../../ui/UI';
import BlockSpecs from '../blocks/BlockSpecs';
import iOS from '../../iPad/iOS';
import IO from '../../iPad/IO';
import Undo from '../ui/Undo';
import ScriptsPane from '../ui/ScriptsPane';
import SVG2Canvas from '../../utils/SVG2Canvas';
import SVGTools from '../../painteditor/SVGTools';
import Rectangle from '../../geom/Rectangle';
import Events from '../../utils/Events';
import Localization from '../../utils/Localization';
import ScratchAudio from '../../utils/ScratchAudio';
import Scripts from '../ui/Scripts';
import {newHTML, newDiv, newP, gn,
setCanvasSizeScaledToWindowDocumentHeight,
DEGTOR, getIdFor, setProps, isTablet, isiOS,
isAndroid, fitInRect, scaleMultiplier, setCanvasSize,
globaly, globalx, rgbToHex} from '../../utils/lib';
export default class Sprite {
constructor (attr, whenDone) {
if (attr.type == 'sprite') { if (attr.type == 'sprite') {
this.createSprite(attr.page, attr.md5, attr.id, attr, whenDone); this.createSprite(attr.page, attr.md5, attr.id, attr, whenDone);
} else { } else {
this.createText(attr, whenDone); this.createText(attr, whenDone);
} }
}; }
Sprite.prototype.createSprite = function (page, md5, id, attr, fcn) { createSprite (page, md5, id, attr, fcn) {
ScratchJr.storyStart('Sprite.prototype.createSprite'); ScratchJr.storyStart('Sprite.prototype.createSprite');
this.div = document.createElement('div'); this.div = document.createElement('div');
setProps(this.div.style, { setProps(this.div.style, {
@ -48,9 +71,9 @@ Sprite.prototype.createSprite = function (page, md5, id, attr, fcn) {
function gotImage (dataurl) { function gotImage (dataurl) {
me.setCostume(dataurl, fcn); me.setCostume(dataurl, fcn);
} }
}; }
Sprite.prototype.getAsset = function (whenDone) { getAsset (whenDone) {
var md5 = this.md5; var md5 = this.md5;
var spr = this; var spr = this;
var url = (MediaLib.keys[md5]) ? MediaLib.path + md5 : (md5.indexOf('/') < 0) ? iOS.path + md5 : md5; var url = (MediaLib.keys[md5]) ? MediaLib.path + md5 : (md5.indexOf('/') < 0) ? iOS.path + md5 : md5;
@ -66,7 +89,7 @@ Sprite.prototype.getAsset = function (whenDone) {
function doNext (str) { function doNext (str) {
str = str.replace(/>\s*</g, '><'); str = str.replace(/>\s*</g, '><');
spr.setSVG(str); spr.setSVG(str);
if ((str.indexOf('xlink:href') < 0) && iOS.path { if ((str.indexOf('xlink:href') < 0) && iOS.path) {
whenDone(url); // does not have embedded images whenDone(url); // does not have embedded images
} else { } else {
var base64 = IO.getImageDataURL(spr.md5, btoa(str)); var base64 = IO.getImageDataURL(spr.md5, btoa(str));
@ -75,18 +98,18 @@ Sprite.prototype.getAsset = function (whenDone) {
}); });
} }
} }
}; }
Sprite.prototype.setSVG = function (str) { setSVG (str) {
var xmlDoc = new DOMParser().parseFromString(str, 'text/xml'); var xmlDoc = new DOMParser().parseFromString(str, 'text/xml');
var extxml = document.importNode(xmlDoc.documentElement, true); var extxml = document.importNode(xmlDoc.documentElement, true);
if (extxml.childNodes[0].nodeName == '#comment') { if (extxml.childNodes[0].nodeName == '#comment') {
extxml.removeChild(extxml.childNodes[0]); extxml.removeChild(extxml.childNodes[0]);
} }
this.svg = extxml; this.svg = extxml;
}; }
Sprite.prototype.setCostume = function (dataurl, fcn) { setCostume (dataurl, fcn) {
var img = document.createElement('img'); var img = document.createElement('img');
img.src = dataurl; img.src = dataurl;
this.img = img; this.img = img;
@ -106,9 +129,9 @@ Sprite.prototype.setCostume = function (dataurl, fcn) {
} else { } else {
sprite.displaySprite(fcn); sprite.displaySprite(fcn);
} }
}; }
Sprite.prototype.displaySprite = function (whenDone) { displaySprite (whenDone) {
var w = this.img.width; var w = this.img.width;
var h = this.img.height; var h = this.img.height;
this.div.style.width = this.img.width + 'px'; this.div.style.width = this.img.width + 'px';
@ -119,9 +142,9 @@ Sprite.prototype.displaySprite = function (whenDone) {
this.h = h; this.h = h;
this.setPos(this.xcoor, this.ycoor); this.setPos(this.xcoor, this.ycoor);
this.doRender(whenDone); this.doRender(whenDone);
}; }
Sprite.prototype.doRender = function (whenDone) { doRender (whenDone) {
this.drawBorder(); // canvas draw border this.drawBorder(); // canvas draw border
this.render(); this.render();
SVG2Canvas.drawInCanvas(this); // canvas draws mask for pixel detection SVG2Canvas.drawInCanvas(this); // canvas draws mask for pixel detection
@ -130,9 +153,9 @@ Sprite.prototype.doRender = function (whenDone) {
if (whenDone) { if (whenDone) {
whenDone(this); whenDone(this);
} }
}; }
Sprite.prototype.drawBorder = function () { drawBorder () {
// TODO: Merge these to get better thumbnail rendering on iOS // TODO: Merge these to get better thumbnail rendering on iOS
var w, h, extxml; var w, h, extxml;
if (isAndroid) { if (isAndroid) {
@ -153,13 +176,13 @@ Sprite.prototype.drawBorder = function () {
setCanvasSize(this.border, w, h); setCanvasSize(this.border, w, h);
SVG2Canvas.drawBorder(extxml, this.border.getContext('2d')); SVG2Canvas.drawBorder(extxml, this.border.getContext('2d'));
} }
}; }
////////////////////////////////////// //////////////////////////////////////
// sprite thumbnail // sprite thumbnail
///////////////////////////////////// /////////////////////////////////////
Sprite.prototype.spriteThumbnail = function (p) { spriteThumbnail (p) {
var tb = newHTML('div', 'spritethumb off', p); var tb = newHTML('div', 'spritethumb off', p);
tb.setAttribute('id', getIdFor('spritethumb')); tb.setAttribute('id', getIdFor('spritethumb'));
tb.type = 'spritethumb'; tb.type = 'spritethumb';
@ -179,9 +202,9 @@ Sprite.prototype.spriteThumbnail = function (p) {
newHTML('div', 'brush', tb); newHTML('div', 'brush', tb);
this.thumbnail = tb; this.thumbnail = tb;
return tb; return tb;
}; }
Sprite.prototype.updateSpriteThumb = function () { updateSpriteThumb () {
var tb = this.thumbnail; var tb = this.thumbnail;
if (!tb) { if (!tb) {
return; return;
@ -189,9 +212,9 @@ Sprite.prototype.updateSpriteThumb = function () {
var cnv = tb.childNodes[0]; var cnv = tb.childNodes[0];
this.drawMyImage(cnv, cnv.width, cnv.height); this.drawMyImage(cnv, cnv.width, cnv.height);
tb.childNodes[1].textContent = this.name; tb.childNodes[1].textContent = this.name;
}; }
Sprite.prototype.drawMyImage = function (cnv, w, h) { drawMyImage (cnv, w, h) {
if (!this.img) { if (!this.img) {
return; return;
} }
@ -220,13 +243,13 @@ Sprite.prototype.drawMyImage = function (cnv, w, h) {
} else { } else {
ctx.drawImage(img, 0, 0, imgw, imgh, ix, iy, iw, ih); ctx.drawImage(img, 0, 0, imgw, imgh, ix, iy, iw, ih);
} }
}; }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// sprite Primitives // sprite Primitives
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
Sprite.prototype.goHome = function () { goHome () {
this.setPos(this.homex, this.homey); this.setPos(this.homex, this.homey);
this.scale = this.homescale; this.scale = this.homescale;
this.shown = this.homeshown; this.shown = this.homeshown;
@ -234,9 +257,9 @@ Sprite.prototype.goHome = function () {
this.div.style.opacity = this.shown ? 1 : 0; this.div.style.opacity = this.shown ? 1 : 0;
this.setHeading(0); this.setHeading(0);
this.render(); this.render();
}; }
Sprite.prototype.touchingAny = function () { touchingAny () {
if (!this.shown) { if (!this.shown) {
return false; return false;
} }
@ -270,9 +293,9 @@ Sprite.prototype.touchingAny = function () {
} }
} }
return false; return false;
}; }
Sprite.prototype.verifyHit = function (other) { verifyHit (other) {
var ctx = ScratchJr.workingCanvas.getContext('2d'); var ctx = ScratchJr.workingCanvas.getContext('2d');
var ctx2 = ScratchJr.workingCanvas2.getContext('2d'); var ctx2 = ScratchJr.workingCanvas2.getContext('2d');
ctx.clearRect(0, 0, 480, 360); ctx.clearRect(0, 0, 480, 360);
@ -290,7 +313,8 @@ Sprite.prototype.verifyHit = function (other) {
this.stamp(ctx); this.stamp(ctx);
// Normally, we could do a source-over followed by a source-in to detect where the two images collide. // Normally, we could do a source-over followed by a source-in to detect where the two images collide.
// However, unfortunately, behavior on Android 4.2 and Android 4.4+ varies. // However, unfortunately, behavior on Android 4.2 and Android 4.4+ varies.
// On Android 4.4+, we could potentially use this more efficient strategy, but we opted for using a single strategy // On Android 4.4+, we could potentially use this more efficient strategy,
// but we opted for using a single strategy
// that works on all platforms, despite it being less efficient. // that works on all platforms, despite it being less efficient.
// A future optimization could detect the behavior and use // A future optimization could detect the behavior and use
// the right strategy. // the right strategy.
@ -315,18 +339,18 @@ Sprite.prototype.verifyHit = function (other) {
} }
} }
return false; return false;
}; }
Sprite.prototype.getAlpha = function (data, node, w) { getAlpha (data, node, w) {
return data[(node.x * 4) + node.y * w * 4 + 3]; return data[(node.x * 4) + node.y * w * 4 + 3];
}; }
Sprite.prototype.setHeading = function (angle) { setHeading (angle) {
this.angle = angle % 360; this.angle = angle % 360;
this.render(); this.render();
}; }
Sprite.prototype.setPos = function (dx, dy) { setPos (dx, dy) {
this.dirx = ((dx - this.xcoor) == 0) ? 1 : (dx - this.xcoor) / Math.abs(dx - this.xcoor); this.dirx = ((dx - this.xcoor) == 0) ? 1 : (dx - this.xcoor) / Math.abs(dx - this.xcoor);
this.diry = ((dy - this.ycoor) == 0) ? 1 : (dy - this.ycoor) / Math.abs(dy - this.ycoor); this.diry = ((dy - this.ycoor) == 0) ? 1 : (dy - this.ycoor) / Math.abs(dy - this.ycoor);
this.xcoor = dx; this.xcoor = dx;
@ -339,17 +363,17 @@ Sprite.prototype.setPos = function (dx, dy) {
top: '0px' top: '0px'
}); });
this.updateBubble(); this.updateBubble();
}; }
Sprite.prototype.wrap = function () { wrap () {
if (this.type == 'text') { if (this.type == 'text') {
this.wrapText(); this.wrapText();
} else { } else {
this.wrapChar(); this.wrapChar();
} }
}; }
Sprite.prototype.wrapChar = function () { wrapChar () {
if (this.xcoor < 0) { if (this.xcoor < 0) {
this.xcoor = 480 + this.xcoor; this.xcoor = 480 + this.xcoor;
} }
@ -362,9 +386,9 @@ Sprite.prototype.wrapChar = function () {
if (this.ycoor >= 360) { if (this.ycoor >= 360) {
this.ycoor = this.ycoor - 360; this.ycoor = this.ycoor - 360;
} }
}; }
Sprite.prototype.wrapText = function () { wrapText () {
var max = this.cx > 480 ? this.cx : 480; var max = this.cx > 480 ? this.cx : 480;
var min = this.cx > 480 ? 480 - this.cx : 0; var min = this.cx > 480 ? 480 - this.cx : 0;
if (this.xcoor < min) { if (this.xcoor < min) {
@ -379,9 +403,9 @@ Sprite.prototype.wrapText = function () {
if (this.ycoor >= 360) { if (this.ycoor >= 360) {
this.ycoor = this.ycoor - 360; this.ycoor = this.ycoor - 360;
} }
}; }
Sprite.prototype.render = function () { render () {
// TODO: Merge these to get better thumbnail rendering on iOS // TODO: Merge these to get better thumbnail rendering on iOS
var dx, dy, mtx; var dx, dy, mtx;
if (isAndroid) { if (isAndroid) {
@ -426,9 +450,9 @@ Sprite.prototype.render = function () {
} }
this.setTransform(mtx); this.setTransform(mtx);
} }
}; }
Sprite.prototype.select = function () { select () {
if (this.borderOn) { if (this.borderOn) {
return; return;
} }
@ -452,9 +476,9 @@ Sprite.prototype.select = function () {
}); });
this.borderOn = true; this.borderOn = true;
this.render(); this.render();
}; }
Sprite.prototype.unselect = function () { unselect () {
if (!this.borderOn) { if (!this.borderOn) {
return; return;
} }
@ -463,32 +487,32 @@ Sprite.prototype.unselect = function () {
} }
this.div.appendChild(this.img); this.div.appendChild(this.img);
this.borderOn = false; this.borderOn = false;
}; }
Sprite.prototype.setTransform = function (transform) { setTransform (transform) {
this.div.style.webkitTransform = transform; this.div.style.webkitTransform = transform;
}; }
Sprite.prototype.screenLeft = function () { screenLeft () {
return Math.round(this.xcoor - this.cx * this.scale); return Math.round(this.xcoor - this.cx * this.scale);
}; }
Sprite.prototype.screenTop = function () { screenTop () {
return Math.round(this.ycoor - this.cy * this.scale); return Math.round(this.ycoor - this.cy * this.scale);
}; }
Sprite.prototype.noScaleFor = function () { noScaleFor () {
this.setScaleTo(this.defaultScale); this.setScaleTo(this.defaultScale);
}; }
Sprite.prototype.changeSizeBy = function (num) { changeSizeBy (num) {
var n = Number(num) + Number(this.scale) * 100; var n = Number(num) + Number(this.scale) * 100;
this.scale = this.getScale(n / 100); this.scale = this.getScale(n / 100);
this.setPos(this.xcoor, this.ycoor); this.setPos(this.xcoor, this.ycoor);
this.render(); this.render();
}; }
Sprite.prototype.setScaleTo = function (n) { setScaleTo (n) {
n = this.getScale(n); n = this.getScale(n);
if (n == this.scale) { if (n == this.scale) {
return; return;
@ -496,9 +520,9 @@ Sprite.prototype.setScaleTo = function (n) {
this.scale = n; this.scale = n;
this.setPos(this.xcoor, this.ycoor); this.setPos(this.xcoor, this.ycoor);
this.render(); this.render();
}; }
Sprite.prototype.getScale = function (n) { getScale (n) {
var mins = Math.max(Math.max(this.w, this.h) * n, 36); var mins = Math.max(Math.max(this.w, this.h) * n, 36);
var maxs = Math.min(Math.min(this.w, this.h) * n, 360); var maxs = Math.min(Math.min(this.w, this.h) * n, 360);
if (mins == 36) { if (mins == 36) {
@ -508,9 +532,9 @@ Sprite.prototype.getScale = function (n) {
return 360 / Math.min(this.w, this.h); return 360 / Math.min(this.w, this.h);
} }
return n; return n;
}; }
Sprite.prototype.getBox = function () { getBox () {
var box = { var box = {
x: this.screenLeft(), x: this.screenLeft(),
y: this.screenTop(), y: this.screenTop(),
@ -518,31 +542,32 @@ Sprite.prototype.getBox = function () {
height: this.h * this.scale height: this.h * this.scale
}; };
return box; return box;
}; }
Sprite.prototype.getBoxWithEffects = function () { getBoxWithEffects () {
if (this.type == 'text') { if (this.type == 'text') {
return new Rectangle(this.screenLeft(), this.screenTop(), this.w * this.scale, this.h * this.scale); return new Rectangle(this.screenLeft(), this.screenTop(), this.w * this.scale, this.h * this.scale);
} }
var max = Math.max(this.outline.width, this.outline.height); var max = Math.max(this.outline.width, this.outline.height);
var w = Math.floor(max * 1.5 * this.scale); var w = Math.floor(max * 1.5 * this.scale);
var h = Math.floor(max * 1.5 * this.scale); var h = Math.floor(max * 1.5 * this.scale);
return new Rectangle(Math.floor(this.xcoor - w / 2), Math.floor(this.ycoor - h / 2), Math.floor(w), Math.floor(h)); return new Rectangle(Math.floor(this.xcoor - w / 2),
}; Math.floor(this.ycoor - h / 2), Math.floor(w), Math.floor(h));
}
////////////////////////////////////////////////// //////////////////////////////////////////////////
// Balloon // Balloon
////////////////////////////////////////////////// //////////////////////////////////////////////////
Sprite.prototype.closeBalloon = function () { closeBalloon () {
if (!this.balloon) { if (!this.balloon) {
return; return;
} }
this.balloon.parentNode.removeChild(this.balloon); this.balloon.parentNode.removeChild(this.balloon);
this.balloon = undefined; this.balloon = undefined;
}; }
Sprite.prototype.openBalloon = function (label) { openBalloon (label) {
if (this.balloon) { if (this.balloon) {
this.closeBalloon(); this.closeBalloon();
} }
@ -596,9 +621,9 @@ Sprite.prototype.openBalloon = function (label) {
visibility: 'visible' visibility: 'visible'
}); });
this.drawBalloon(); this.drawBalloon();
}; }
Sprite.prototype.updateBubble = function () { updateBubble () {
if (this.balloon == null) { if (this.balloon == null) {
return; return;
} }
@ -616,9 +641,9 @@ Sprite.prototype.updateBubble = function () {
this.balloon.left = dx; this.balloon.left = dx;
this.balloon.top = dy; this.balloon.top = dy;
this.drawBalloon(); this.drawBalloon();
}; }
Sprite.prototype.drawBalloon = function () { drawBalloon () {
var img = this.balloon.childNodes[0]; var img = this.balloon.childNodes[0];
var w = this.balloon.offsetWidth; var w = this.balloon.offsetWidth;
var h = this.balloon.offsetHeight; var h = this.balloon.offsetHeight;
@ -646,13 +671,13 @@ Sprite.prototype.drawBalloon = function () {
var b = a[1].split('h-1'); var b = a[1].split('h-1');
str = a[0] + 'h' + (-side1 + 7 + curve) + b[0] + 'h' + (-side2 + 7 + curve) + b[1]; str = a[0] + 'h' + (-side1 + 7 + curve) + b[0] + 'h' + (-side2 + 7 + curve) + b[1];
img.src = 'data:image/svg+xml;base64,' + btoa(str); img.src = 'data:image/svg+xml;base64,' + btoa(str);
}; }
///////////////////////////////////// /////////////////////////////////////
// Sprite rendering // Sprite rendering
//////////////////////////////////// ////////////////////////////////////
Sprite.prototype.stamp = function (ctx, deltax, deltay) { stamp (ctx, deltax, deltay) {
var w = this.outline.width * this.scale; var w = this.outline.width * this.scale;
var h = this.outline.height * this.scale; var h = this.outline.height * this.scale;
var dx = deltax ? deltax : 0; var dx = deltax ? deltax : 0;
@ -665,13 +690,13 @@ Sprite.prototype.stamp = function (ctx, deltax, deltay) {
} }
ctx.drawImage(this.outline, -w / 2, -h / 2, w, h); ctx.drawImage(this.outline, -w / 2, -h / 2, w, h);
ctx.restore(); ctx.restore();
}; }
///////////////////////////////////// /////////////////////////////////////
// Text Creation // Text Creation
///////////////////////////////////// /////////////////////////////////////
Sprite.prototype.createText = function (attr, whenDone) { createText (attr, whenDone) {
var page = attr.page; var page = attr.page;
setProps(this, attr); setProps(this, attr);
this.div = newHTML('p', 'textsprite', page.div); this.div = newHTML('p', 'textsprite', page.div);
@ -707,9 +732,9 @@ Sprite.prototype.createText = function (attr, whenDone) {
whenDone(this); whenDone(this);
} }
} }
}; }
Sprite.prototype.setTextBox = function () { setTextBox () {
var sform = document.forms.activetextbox; var sform = document.forms.activetextbox;
sform.textsprite = this; sform.textsprite = this;
var box = this.getBox(); var box = this.getBox();
@ -771,9 +796,9 @@ Sprite.prototype.setTextBox = function () {
height: (this.fontsize + 10) + 'px' height: (this.fontsize + 10) + 'px'
}); });
} }
}; }
Sprite.prototype.unfocusText = function () { unfocusText () {
ScratchJr.blur(); ScratchJr.blur();
document.body.scrollTop = 0; document.body.scrollTop = 0;
document.body.scrollLeft = 0; document.body.scrollLeft = 0;
@ -808,9 +833,9 @@ Sprite.prototype.unfocusText = function () {
ScratchJr.onBackButtonCallback.pop(); ScratchJr.onBackButtonCallback.pop();
AndroidInterface.scratchjr_forceHideKeyboard(); AndroidInterface.scratchjr_forceHideKeyboard();
} }
}; }
Sprite.prototype.deleteText = function (record) { deleteText (record) {
var id = this.id; var id = this.id;
var page = ScratchJr.stage.currentPage; var page = ScratchJr.stage.currentPage;
page.textstartat = (this.ycoor + (this.fontsize * 1.35)) > 360 ? 36 : this.ycoor; page.textstartat = (this.ycoor + (this.fontsize * 1.35)) > 360 ? 36 : this.ycoor;
@ -833,32 +858,32 @@ Sprite.prototype.deleteText = function (record) {
}); });
ScratchJr.storyStart('Sprite.prototype.deleteText'); ScratchJr.storyStart('Sprite.prototype.deleteText');
} }
}; }
Sprite.prototype.noChars = function (str) { noChars (str) {
for (var i = 0; i < str.length; i++) { for (var i = 0; i < str.length; i++) {
if (str[i] != ' ') { if (str[i] != ' ') {
return false; return false;
} }
} }
return true; return true;
}; }
Sprite.prototype.contractText = function () { contractText () {
var form = document.forms.activetextbox; var form = document.forms.activetextbox;
this.str = form.typing.value.substring(0, form.typing.maxLength); this.str = form.typing.value.substring(0, form.typing.maxLength);
this.recalculateText(); this.recalculateText();
}; }
Sprite.prototype.clickOnText = function (e) { clickOnText (e) {
e.stopPropagation(); e.stopPropagation();
this.setTextBox(); this.setTextBox();
gn('textbox').style.visibility = 'visible'; gn('textbox').style.visibility = 'visible';
this.div.style.visibility = 'hidden'; this.div.style.visibility = 'hidden';
this.activateInput(); this.activateInput();
}; }
Sprite.prototype.activateInput = function () { activateInput () {
this.oldvalue = this.str; this.oldvalue = this.str;
var ti = document.forms.activetextbox.typing; var ti = document.forms.activetextbox.typing;
gn('textbox').style.visibility = 'visible'; gn('textbox').style.visibility = 'visible';
@ -892,9 +917,9 @@ Sprite.prototype.activateInput = function () {
}, 100); }, 100);
} }
} }
}; }
Sprite.prototype.handleWrite = function (e) { handleWrite (e) {
var key = e.keyCode || e.which; var key = e.keyCode || e.which;
var ti = e.target; var ti = e.target;
if (key == 13) { if (key == 13) {
@ -906,24 +931,24 @@ Sprite.prototype.handleWrite = function (e) {
this.deactivateInput(); this.deactivateInput();
} }
} }
}; }
Sprite.prototype.handleKeyUp = function (e) { handleKeyUp (e) {
var ti = e.target; var ti = e.target;
if (!(ti.parentNode).textsprite) { if (!(ti.parentNode).textsprite) {
return; return;
} }
(ti.parentNode).textsprite.str = ti.value; (ti.parentNode).textsprite.str = ti.value;
}; }
Sprite.prototype.deactivateInput = function () { deactivateInput () {
var ti = document.forms.activetextbox.typing; var ti = document.forms.activetextbox.typing;
ti.onblur = undefined; ti.onblur = undefined;
ti.onkeypress = undefined; ti.onkeypress = undefined;
ti.onsubmit = undefined; ti.onsubmit = undefined;
}; }
Sprite.prototype.activate = function () { activate () {
var list = fitInRect(this.w, this.h, ScriptsPane.watermark.offsetWidth, ScriptsPane.watermark.offsetHeight); var list = fitInRect(this.w, this.h, ScriptsPane.watermark.offsetWidth, ScriptsPane.watermark.offsetHeight);
var div = ScriptsPane.watermark; var div = ScriptsPane.watermark;
while (div.childElementCount > 0) { while (div.childElementCount > 0) {
@ -939,26 +964,26 @@ Sprite.prototype.activate = function () {
zoom: Math.floor((list[2] / this.w) * 100) + '%' zoom: Math.floor((list[2] / this.w) * 100) + '%'
}; };
setProps(img.style, attr); setProps(img.style, attr);
}; }
Sprite.prototype.getSVGimage = function (svg) { getSVGimage (svg) {
var img = document.createElement('img'); var img = document.createElement('img');
var str = (new XMLSerializer()).serializeToString(svg); var str = (new XMLSerializer()).serializeToString(svg);
str = str.replace(/ href="data:image/g, ' xlink:href="data:image'); str = str.replace(/ href="data:image/g, ' xlink:href="data:image');
img.src = 'data:image/svg+xml;base64,' + btoa(str); img.src = 'data:image/svg+xml;base64,' + btoa(str);
return img; return img;
}; }
///////////////////////////////////////////////// /////////////////////////////////////////////////
// Text fcn // Text fcn
//////////////////////////////////////////////// ////////////////////////////////////////////////
Sprite.prototype.setColor = function (c) { setColor (c) {
this.color = c; this.color = c;
this.div.style.color = this.color; this.div.style.color = this.color;
}; }
Sprite.prototype.setFontSize = function (n) { setFontSize (n) {
if (n < 12) { if (n < 12) {
n = 12; n = 12;
} }
@ -966,9 +991,9 @@ Sprite.prototype.setFontSize = function (n) {
n = 72; n = 72;
} }
this.fontsize = n; this.fontsize = n;
}; }
Sprite.prototype.recalculateText = function () { recalculateText () {
this.div.style.color = this.color; this.div.style.color = this.color;
this.div.style.fontSize = this.fontsize + 'px'; this.div.style.fontSize = this.fontsize + 'px';
this.div.textContent = this.str; this.div.textContent = this.str;
@ -988,9 +1013,9 @@ Sprite.prototype.recalculateText = function () {
ctx.textBaseline = 'top'; ctx.textBaseline = 'top';
ctx.fillText(this.str, 0, 0); ctx.fillText(this.str, 0, 0);
this.setPos(this.xcoor, this.ycoor); this.setPos(this.xcoor, this.ycoor);
}; }
Sprite.prototype.startShaking = function () { startShaking () {
var p = this.div.parentNode; var p = this.div.parentNode;
var shake = newHTML('div', 'shakeme', p); var shake = newHTML('div', 'shakeme', p);
shake.id = 'shakediv'; shake.id = 'shakediv';
@ -1038,9 +1063,9 @@ Sprite.prototype.startShaking = function () {
cb.id = 'deletesprite'; cb.id = 'deletesprite';
this.div = shake; this.div = shake;
this.div.owner = this; this.div.owner = this;
}; }
Sprite.prototype.stopShaking = function () { stopShaking () {
if (this.div.id != 'shakediv') { if (this.div.id != 'shakediv') {
return; return;
} }
@ -1066,9 +1091,9 @@ Sprite.prototype.stopShaking = function () {
} }
this.setTransform(mtx); this.setTransform(mtx);
} }
}; }
Sprite.prototype.drawCloseButton = function () { drawCloseButton () {
var ctx = this.div.getContext('2d'); var ctx = this.div.getContext('2d');
var img = document.createElement('img'); var img = document.createElement('img');
img.src = 'assets/ui/closeit.svg'; img.src = 'assets/ui/closeit.svg';
@ -1079,13 +1104,13 @@ Sprite.prototype.drawCloseButton = function () {
} else { } else {
ctx.drawImage(img, 0, 0); ctx.drawImage(img, 0, 0);
} }
}; }
////////////////////////////////////////// //////////////////////////////////////////
// Save data // Save data
///////////////////////////////////////// /////////////////////////////////////////
Sprite.prototype.getData = function () { getData () {
var data = (this.type == 'sprite') ? this.getSpriteData() : this.getTextBoxData(); var data = (this.type == 'sprite') ? this.getSpriteData() : this.getTextBoxData();
if (this.type != 'sprite') { if (this.type != 'sprite') {
return data; return data;
@ -1098,9 +1123,9 @@ Sprite.prototype.getData = function () {
} }
data.scripts = res; data.scripts = res;
return data; return data;
}; }
Sprite.prototype.getSpriteData = function () { getSpriteData () {
var data = {}; var data = {};
data.shown = this.shown; data.shown = this.shown;
data.type = this.type; data.type = this.type;
@ -1125,9 +1150,9 @@ Sprite.prototype.getSpriteData = function () {
data.homeshown = this.homeshown; data.homeshown = this.homeshown;
data.homeflip = this.homeflip; data.homeflip = this.homeflip;
return data; return data;
}; }
Sprite.prototype.getTextBoxData = function () { getTextBoxData () {
var data = {}; var data = {};
data.shown = this.shown; data.shown = this.shown;
data.type = this.type; data.type = this.type;
@ -1145,4 +1170,5 @@ Sprite.prototype.getTextBoxData = function () {
data.color = this.color; data.color = this.color;
data.fontsize = this.fontsize; data.fontsize = this.fontsize;
return data; return data;
}; }
}

View file

@ -1,4 +1,21 @@
var Stage = function (div) { import ScratchJr from '../ScratchJr';
import Project from '../../ui/Project';
import Thumbs from '../../ui/Thumbs';
import UI from '../../ui/UI';
import Undo from '../ui/Undo';
import ScriptsPane from '../ui/ScriptsPane';
import Rectangle from '../../geom/Rectangle';
import Events from '../../utils/Events';
import ScratchAudio from '../../utils/ScratchAudio';
import Vector from '../../geom/Vector';
import Page from './Page';
import {newHTML, newDiv, gn,
getIdFor, setProps,
scaleMultiplier, setCanvasSize,
globaly, globalx} from '../../utils/lib';
export default class Stage {
constructor (div) {
this.currentPage = undefined; this.currentPage = undefined;
this.div = newHTML('div', 'stage', div); this.div = newHTML('div', 'stage', div);
this.div.setAttribute('id', 'stage'); this.div.setAttribute('id', 'stage');
@ -24,35 +41,35 @@ var Stage = function (div) {
x: 0, x: 0,
y: 0 y: 0
}; };
}; }
Stage.prototype.setStageScaleAndPosition = function (scale, x, y) { setStageScaleAndPosition (scale, x, y) {
this.stageScale = scale; this.stageScale = scale;
setProps(gn('stage').style, { setProps(gn('stage').style, {
webkitTransform: 'translate(' + (-this.width / 2) + 'px, ' + (-this.height / 2) + 'px) ' + webkitTransform: 'translate(' + (-this.width / 2) + 'px, ' + (-this.height / 2) + 'px) ' +
'scale(' + scale + ') ' + 'scale(' + scale + ') ' +
'translate(' + (this.width / 2 + x) + 'px, ' + (this.height / 2 + y) + 'px)' 'translate(' + (this.width / 2 + x) + 'px, ' + (this.height / 2 + y) + 'px)'
}); });
}; }
Stage.prototype.getPagesID = function () { getPagesID () {
var res = []; var res = [];
for (var i = 0; i < this.pages.length; i++) { for (var i = 0; i < this.pages.length; i++) {
res.push(this.pages[i].id); res.push(this.pages[i].id);
} }
return res; return res;
}; }
Stage.prototype.getPage = function (id) { getPage (id) {
for (var i = 0; i < this.pages.length; i++) { for (var i = 0; i < this.pages.length; i++) {
if (this.pages[i].id == id) { if (this.pages[i].id == id) {
return this.pages[i]; return this.pages[i];
} }
} }
return this.pages[0]; return this.pages[0];
}; }
Stage.prototype.resetPage = function (obj) { resetPage (obj) {
var page = obj.div; var page = obj.div;
for (var i = 0; i < page.childElementCount; i++) { for (var i = 0; i < page.childElementCount; i++) {
var spr = page.childNodes[i].owner; var spr = page.childNodes[i].owner;
@ -63,19 +80,19 @@ Stage.prototype.resetPage = function (obj) {
spr.goHome(); spr.goHome();
} }
} }
}; }
Stage.prototype.resetPages = function () { resetPages () {
for (var i = 0; i < ScratchJr.stage.pages.length; i++) { for (var i = 0; i < ScratchJr.stage.pages.length; i++) {
Stage.prototype.resetPage(ScratchJr.stage.pages[i]); Stage.prototype.resetPage(ScratchJr.stage.pages[i]);
} }
}; }
//goto page //goto page
Stage.prototype.gotoPage = function (n) { gotoPage (n) {
if (n < 1) { if (n < 1) {
return; return;
} }
@ -86,9 +103,9 @@ Stage.prototype.gotoPage = function (n) {
return; return;
} }
this.setPage(this.pages[n - 1], true); this.setPage(this.pages[n - 1], true);
}; }
Stage.prototype.setPage = function (page, isOn) { setPage (page, isOn) {
ScratchJr.stopStrips(); ScratchJr.stopStrips();
var sc = ScratchJr.getSprite() ? gn(ScratchJr.stage.currentPage.currentSpriteName + '_scripts') : undefined; var sc = ScratchJr.getSprite() ? gn(ScratchJr.stage.currentPage.currentSpriteName + '_scripts') : undefined;
if (sc) { if (sc) {
@ -109,9 +126,9 @@ Stage.prototype.setPage = function (page, isOn) {
if (isOn) { if (isOn) {
this.loadPageThreads(); this.loadPageThreads();
} }
}; }
Stage.prototype.loadPageThreads = function () { loadPageThreads () {
ScratchJr.blur(); ScratchJr.blur();
var page = this.currentPage; var page = this.currentPage;
for (var i = 0; i < page.div.childElementCount; i++) { for (var i = 0; i < page.div.childElementCount; i++) {
@ -130,13 +147,13 @@ Stage.prototype.loadPageThreads = function () {
ScratchJr.runtime.addRunScript(spr, b); ScratchJr.runtime.addRunScript(spr, b);
} }
} }
}; }
//Copy Sprite //Copy Sprite
/////////////////////////////////' /////////////////////////////////'
Stage.prototype.copySprite = function (el, thumb) { copySprite (el, thumb) {
ScratchAudio.sndFX('copy.wav'); ScratchAudio.sndFX('copy.wav');
Thumbs.overpage(thumb); Thumbs.overpage(thumb);
var data = Project.encodeSprite(el.owner); var data = Project.encodeSprite(el.owner);
@ -171,13 +188,13 @@ Stage.prototype.copySprite = function (el, thumb) {
ScratchJr.storyStart('Stage.prototype.copySprite'); ScratchJr.storyStart('Stage.prototype.copySprite');
}; };
Project.recreateObject(page, name, data, whenDone, page.id == stg.currentPage.id); Project.recreateObject(page, name, data, whenDone, page.id == stg.currentPage.id);
}; }
//Delete page //Delete page
Stage.prototype.deletePage = function (str, data) { deletePage (str, data) {
// reserve a next id to be able to Undo deleting the first page // reserve a next id to be able to Undo deleting the first page
ScratchJr.storyStart('Stage.prototype.deletePage'); // Record a change for sample projects in story-starter mode ScratchJr.storyStart('Stage.prototype.deletePage'); // Record a change for sample projects in story-starter mode
var pageid = getIdFor('page'); var pageid = getIdFor('page');
@ -234,15 +251,15 @@ Stage.prototype.deletePage = function (str, data) {
}); });
} }
} }
}; }
Stage.prototype.setViewPage = function (page) { setViewPage (page) {
this.currentPage = page; this.currentPage = page;
this.currentPage.div.style.visibility = 'visible'; this.currentPage.div.style.visibility = 'visible';
this.currentPage.setPageSprites('visible'); this.currentPage.setPageSprites('visible');
}; }
Stage.prototype.removePageBlocks = function (str) { removePageBlocks (str) {
var indx = this.getPagesID().indexOf(str); var indx = this.getPagesID().indexOf(str);
for (var n = 0; n < this.pages.length; n++) { for (var n = 0; n < this.pages.length; n++) {
var page = this.pages[n]; var page = this.pages[n];
@ -274,13 +291,13 @@ Stage.prototype.removePageBlocks = function (str) {
} }
} }
} }
}; }
//Events MouseDown //Events MouseDown
Stage.prototype.mouseDown = function (e) { mouseDown (e) {
if (e.touches && (e.touches.length > 1)) { if (e.touches && (e.touches.length > 1)) {
return; return;
} }
@ -321,9 +338,9 @@ Stage.prototype.mouseDown = function (e) {
} else { } else {
this.mouseDownOnSprite(hitobj, pt); this.mouseDownOnSprite(hitobj, pt);
} }
}; }
Stage.prototype.checkShaking = function (pt, target) { checkShaking (pt, target) {
if (!ScratchJr.shaking) { if (!ScratchJr.shaking) {
return target; return target;
} }
@ -333,9 +350,9 @@ Stage.prototype.checkShaking = function (pt, target) {
var h = gn('deletesprite').offsetHeight; var h = gn('deletesprite').offsetHeight;
var rect = new Rectangle(dx, dy, w, h); var rect = new Rectangle(dx, dy, w, h);
return rect.hitRect(pt) ? gn('deletesprite') : target; return rect.hitRect(pt) ? gn('deletesprite') : target;
}; }
Stage.prototype.mouseDownOnSprite = function (spr, pt) { mouseDownOnSprite (spr, pt) {
this.initialPoint = { this.initialPoint = {
x: pt.x, x: pt.x,
y: pt.y y: pt.y
@ -346,9 +363,9 @@ Stage.prototype.mouseDownOnSprite = function (spr, pt) {
Events.holdit(spr.div, this.startShaking); Events.holdit(spr.div, this.startShaking);
} }
this.setEvents(); this.setEvents();
}; }
Stage.prototype.whoIsIt = function (ctx, pt) { whoIsIt (ctx, pt) {
var page = this.currentPage.div; var page = this.currentPage.div;
var spr, pixel; var spr, pixel;
for (var i = page.childElementCount - 1; i > -1; i--) { for (var i = page.childElementCount - 1; i > -1; i--) {
@ -386,9 +403,9 @@ Stage.prototype.whoIsIt = function (ctx, pt) {
} }
} }
return undefined; return undefined;
}; }
Stage.prototype.getStagePt = function (evt) { getStagePt (evt) {
var pt = Events.getTargetPoint(evt); var pt = Events.getTargetPoint(evt);
var mc = this.div; var mc = this.div;
var dx = globalx(mc); var dx = globalx(mc);
@ -398,9 +415,9 @@ Stage.prototype.getStagePt = function (evt) {
pt.x /= this.stageScale; pt.x /= this.stageScale;
pt.y /= this.stageScale; pt.y /= this.stageScale;
return pt; return pt;
}; }
Stage.prototype.setEvents = function () { setEvents () {
var me = this; var me = this;
window.ontouchmove = function (evt) { window.ontouchmove = function (evt) {
me.mouseMove(evt); me.mouseMove(evt);
@ -408,9 +425,9 @@ Stage.prototype.setEvents = function () {
window.ontouchend = function (evt) { window.ontouchend = function (evt) {
me.mouseUp(evt); me.mouseUp(evt);
}; };
}; }
Stage.prototype.startShaking = function (b) { startShaking (b) {
if (!b.owner) { if (!b.owner) {
return; return;
} }
@ -418,18 +435,18 @@ Stage.prototype.startShaking = function (b) {
ScratchJr.shaking = b; ScratchJr.shaking = b;
ScratchJr.stopShaking = ScratchJr.stage.stopShaking; ScratchJr.stopShaking = ScratchJr.stage.stopShaking;
b.owner.startShaking(); b.owner.startShaking();
}; }
Stage.prototype.stopShaking = function (b) { stopShaking (b) {
if (!b.owner) { if (!b.owner) {
return; return;
} }
b.owner.stopShaking(); b.owner.stopShaking();
ScratchJr.shaking = undefined; ScratchJr.shaking = undefined;
ScratchJr.stopShaking = undefined; ScratchJr.stopShaking = undefined;
}; }
Stage.prototype.startSpriteDrag = function () { startSpriteDrag () {
var spr = Events.dragthumbnail.owner; var spr = Events.dragthumbnail.owner;
spr.threads = ScratchJr.runtime.removeRunScript(spr); spr.threads = ScratchJr.runtime.removeRunScript(spr);
this.currentPage.div.appendChild(Events.dragthumbnail); this.currentPage.div.appendChild(Events.dragthumbnail);
@ -439,9 +456,9 @@ Stage.prototype.startSpriteDrag = function () {
}; };
Events.dragged = true; Events.dragged = true;
ScratchJr.changed = true; ScratchJr.changed = true;
}; }
Stage.prototype.mouseMove = function (e) { mouseMove (e) {
if (!Events.dragthumbnail) { if (!Events.dragthumbnail) {
return; return;
} }
@ -467,17 +484,17 @@ Stage.prototype.mouseMove = function (e) {
x: pt.x, x: pt.x,
y: pt.y y: pt.y
}; };
}; }
Stage.prototype.wrapDelta = function (spr, delta) { wrapDelta (spr, delta) {
if (spr.type == 'text') { if (spr.type == 'text') {
return this.wrapText(spr, delta); return this.wrapText(spr, delta);
} else { } else {
return this.wrapChar(spr, delta); return this.wrapChar(spr, delta);
} }
}; }
Stage.prototype.wrapChar = function (spr, delta) { wrapChar (spr, delta) {
if ((delta.x + spr.xcoor) < 0) { if ((delta.x + spr.xcoor) < 0) {
delta.x -= (spr.xcoor + delta.x); delta.x -= (spr.xcoor + delta.x);
} }
@ -491,9 +508,9 @@ Stage.prototype.wrapChar = function (spr, delta) {
delta.y += (359 - (spr.ycoor + delta.y)); delta.y += (359 - (spr.ycoor + delta.y));
} }
return delta; return delta;
}; }
Stage.prototype.wrapText = function (spr, delta) { wrapText (spr, delta) {
var max = spr.cx > 480 ? spr.cx : 480; var max = spr.cx > 480 ? spr.cx : 480;
var min = spr.cx > 480 ? 480 - spr.cx : 0; var min = spr.cx > 480 ? 480 - spr.cx : 0;
if ((delta.x + spr.xcoor) <= min) { if ((delta.x + spr.xcoor) <= min) {
@ -509,9 +526,9 @@ Stage.prototype.wrapText = function (spr, delta) {
delta.y += (359 - (spr.ycoor + delta.y)); delta.y += (359 - (spr.ycoor + delta.y));
} }
return delta; return delta;
}; }
Stage.prototype.mouseUp = function (e) { mouseUp (e) {
var spr = Events.dragthumbnail.owner; var spr = Events.dragthumbnail.owner;
if (Events.timeoutEvent) { if (Events.timeoutEvent) {
clearTimeout(Events.timeoutEvent); clearTimeout(Events.timeoutEvent);
@ -529,29 +546,29 @@ Stage.prototype.mouseUp = function (e) {
Events.clearEvents(); Events.clearEvents();
Events.dragged = false; Events.dragged = false;
Events.dragthumbnail = undefined; Events.dragthumbnail = undefined;
}; }
Stage.prototype.moveElementBy = function (spr) { moveElementBy (spr) {
if (!ScratchJr.inFullscreen) { if (!ScratchJr.inFullscreen) {
spr.homex = spr.xcoor; spr.homex = spr.xcoor;
spr.homey = spr.ycoor; spr.homey = spr.ycoor;
spr.homeflip = spr.flip; spr.homeflip = spr.flip;
} }
Thumbs.updatePages(); Thumbs.updatePages();
}; }
Stage.prototype.clickOnSprite = function (e, spr) { clickOnSprite (e, spr) {
e.preventDefault(); e.preventDefault();
ScratchJr.clearSelection(); ScratchJr.clearSelection();
ScratchJr.startScriptsFor(spr, ['onclick']); ScratchJr.startScriptsFor(spr, ['onclick']);
ScratchJr.startCurrentPageStrips(['ontouch']); ScratchJr.startCurrentPageStrips(['ontouch']);
}; }
//Delete Sprite //Delete Sprite
/////////////////////////////////' /////////////////////////////////'
Stage.prototype.removeSprite = function (sprite) { removeSprite (sprite) {
ScratchJr.shaking = undefined; ScratchJr.shaking = undefined;
ScratchJr.stopShaking = undefined; ScratchJr.stopShaking = undefined;
ScratchAudio.sndFX('cut.wav'); ScratchAudio.sndFX('cut.wav');
@ -562,9 +579,9 @@ Stage.prototype.removeSprite = function (sprite) {
} }
this.currentPage.updateThumb(); this.currentPage.updateThumb();
this.updatePageBlocks(); this.updatePageBlocks();
}; }
Stage.prototype.removeCharacter = function (spr) { removeCharacter (spr) {
ScratchJr.runtime.stopThreadSprite(spr); ScratchJr.runtime.stopThreadSprite(spr);
this.removeFromPage(spr); this.removeFromPage(spr);
Undo.record({ Undo.record({
@ -574,16 +591,16 @@ Stage.prototype.removeCharacter = function (spr) {
}); });
ScratchJr.storyStart('Stage.prototype.removeCharacter'); ScratchJr.storyStart('Stage.prototype.removeCharacter');
Thumbs.updateSprites(); Thumbs.updateSprites();
}; }
Stage.prototype.updatePageBlocks = function () { updatePageBlocks () {
for (var i = 0; i < ScratchJr.stage.pages.length; i++) { for (var i = 0; i < ScratchJr.stage.pages.length; i++) {
var page = ScratchJr.stage.pages[i]; var page = ScratchJr.stage.pages[i];
ScriptsPane.updateScriptsPageBlocks(JSON.parse(page.sprites)); ScriptsPane.updateScriptsPageBlocks(JSON.parse(page.sprites));
} }
}; }
Stage.prototype.removeFromPage = function (spr) { removeFromPage (spr) {
var id = spr.id; var id = spr.id;
var sc = gn(id + '_scripts'); var sc = gn(id + '_scripts');
var page = this.currentPage; var page = this.currentPage;
@ -606,9 +623,9 @@ Stage.prototype.removeFromPage = function (spr) {
var sprites = page.getSprites(); var sprites = page.getSprites();
page.setCurrentSprite((sprites.length > 0) ? gn(sprites[0]).owner : undefined); page.setCurrentSprite((sprites.length > 0) ? gn(sprites[0]).owner : undefined);
} }
}; }
Stage.prototype.renumberPageBlocks = function (list) { renumberPageBlocks (list) {
var pages = this.getPagesID(); var pages = this.getPagesID();
for (var n = 0; n < this.pages.length; n++) { for (var n = 0; n < this.pages.length; n++) {
var page = this.pages[n]; var page = this.pages[n];
@ -630,9 +647,9 @@ Stage.prototype.renumberPageBlocks = function (list) {
} }
} }
} }
}; }
Stage.prototype.clickOnElement = function (e, spr) { clickOnElement (e, spr) {
if (spr.owner.type == 'text') { if (spr.owner.type == 'text') {
if (!ScratchJr.inFullscreen) { if (!ScratchJr.inFullscreen) {
spr.owner.clickOnText(e); spr.owner.clickOnText(e);
@ -640,13 +657,13 @@ Stage.prototype.clickOnElement = function (e, spr) {
} else if (spr.owner.type == 'sprite') { } else if (spr.owner.type == 'sprite') {
this.clickOnSprite(e, spr.owner); this.clickOnSprite(e, spr.owner);
} }
}; }
//Stage clear //Stage clear
/////////////////////////////////////// ///////////////////////////////////////
Stage.prototype.clear = function () { clear () {
for (var i = 0; i < this.pages.length; i++) { for (var i = 0; i < this.pages.length; i++) {
this.removePage(this.pages[i]); this.removePage(this.pages[i]);
} }
@ -654,9 +671,9 @@ Stage.prototype.clear = function () {
while (this.pagesdiv.childElementCount > 0) { while (this.pagesdiv.childElementCount > 0) {
this.pagesdiv.removeChild(this.pagesdiv.childNodes[0]); this.pagesdiv.removeChild(this.pagesdiv.childNodes[0]);
} }
}; }
Stage.prototype.removePage = function (p) { removePage (p) {
var list = JSON.parse(p.sprites); var list = JSON.parse(p.sprites);
for (var j = 0; j < list.length; j++) { for (var j = 0; j < list.length; j++) {
var name = list[j]; var name = list[j];
@ -668,13 +685,13 @@ Stage.prototype.removePage = function (p) {
sprite.parentNode.removeChild(sprite); sprite.parentNode.removeChild(sprite);
} }
p.div.parentNode.removeChild(p.div); p.div.parentNode.removeChild(p.div);
}; }
//Debugging hit masks //Debugging hit masks
/////////////////////////// ///////////////////////////
Stage.prototype.sd = function () { sd () {
var stg = gn('stage'); var stg = gn('stage');
var mask = newDiv(gn('stageframe'), stg.offsetLeft + 1, stg.offsetTop + 1, 482, 362, var mask = newDiv(gn('stageframe'), stg.offsetLeft + 1, stg.offsetTop + 1, 482, 362,
{ {
@ -684,17 +701,17 @@ Stage.prototype.sd = function () {
}); });
mask.setAttribute('id', 'pagemask'); mask.setAttribute('id', 'pagemask');
mask.appendChild(ScratchJr.workingCanvas); mask.appendChild(ScratchJr.workingCanvas);
}; }
Stage.prototype.on = function () { on () {
gn('pagemask').style.visibility = 'visible'; gn('pagemask').style.visibility = 'visible';
}; }
Stage.prototype.off = function () { off () {
gn('pagemask').style.visibility = 'hidden'; gn('pagemask').style.visibility = 'hidden';
}; }
Stage.prototype.sm = function (spr) { sm (spr) {
var stg = gn('stage'); var stg = gn('stage');
var w = spr.outline.width; var w = spr.outline.width;
var h = spr.outline.height; var h = spr.outline.height;
@ -706,12 +723,13 @@ Stage.prototype.sm = function (spr) {
}); });
mask.setAttribute('id', 'spritemask'); mask.setAttribute('id', 'spritemask');
mask.appendChild(spr.outline); mask.appendChild(spr.outline);
}; }
Stage.prototype.son = function () { son () {
gn('spritemask').style.visibility = 'visible'; gn('spritemask').style.visibility = 'visible';
}; }
Stage.prototype.soff = function () { soff () {
gn('spritemask').style.visibility = 'hidden'; gn('spritemask').style.visibility = 'hidden';
}; }
}

View file

@ -1,4 +1,9 @@
var Thread = function (s, block) { import Prims from './Prims';
import Grid from '../ui/Grid';
import Vector from '../../geom/Vector';
export default class Thread {
constructor (s, block) {
this.firstBlock = block.findFirst(); this.firstBlock = block.findFirst();
this.thisblock = block; this.thisblock = block;
this.oldblock = null; this.oldblock = null;
@ -17,9 +22,9 @@ var Thread = function (s, block) {
this.isRunning = true; this.isRunning = true;
this.time = 0; // for debugging purposes this.time = 0; // for debugging purposes
return this; return this;
}; }
Thread.prototype.clear = function () { clear () {
this.stack = []; this.stack = [];
this.firstTime = true; this.firstTime = true;
this.count = -1; this.count = -1;
@ -31,9 +36,9 @@ Thread.prototype.clear = function () {
this.distance = -1; this.distance = -1;
this.called = []; this.called = [];
this.thisblock = this.firstBlock; this.thisblock = this.firstBlock;
}; }
Thread.prototype.duplicate = function () { duplicate () {
var thread = new Thread(this.spr, this.firstBlock); var thread = new Thread(this.spr, this.firstBlock);
thread.count = -1; thread.count = -1;
thread.firstBlock = this.firstBlock; thread.firstBlock = this.firstBlock;
@ -51,9 +56,9 @@ Thread.prototype.duplicate = function () {
thread.called = this.called; thread.called = this.called;
thread.isRunning = this.isRunning; thread.isRunning = this.isRunning;
return thread; return thread;
}; }
Thread.prototype.deselect = function (b) { deselect (b) {
while (b != null) { while (b != null) {
b.unhighlight(); b.unhighlight();
if (b.inside) { if (b.inside) {
@ -62,21 +67,21 @@ Thread.prototype.deselect = function (b) {
} }
b = b.next; b = b.next;
} }
}; }
Thread.prototype.stop = function (b) { stop (b) {
this.stopping(b); this.stopping(b);
this.isRunning = false; this.isRunning = false;
}; }
Thread.prototype.stopping = function (b) { stopping (b) {
this.endPrim(b); this.endPrim(b);
this.deselect(this.firstBlock); this.deselect(this.firstBlock);
this.clear(); this.clear();
this.spr.closeBalloon(); this.spr.closeBalloon();
}; }
Thread.prototype.endPrim = function (stopMine) { endPrim (stopMine) {
if (!this.thisblock) { if (!this.thisblock) {
return; return;
} }
@ -156,4 +161,5 @@ Thread.prototype.endPrim = function (stopMine) {
s.setHeading(angle); s.setHeading(angle);
break; break;
} }
}; }
}

View file

@ -2,7 +2,17 @@
// Scripts // Scripts
/////////////////////////////////////////////// ///////////////////////////////////////////////
var Scripts = function (spr) { import ScratchJr from '../ScratchJr';
import Block from '../blocks/Block';
import BlockSpecs from '../blocks/BlockSpecs';
import ScriptsPane from './ScriptsPane';
import Events from '../../utils/Events';
import ScratchAudio from '../../utils/ScratchAudio';
import {gn, newHTML, setCanvasSize, setProps,
localx, localy, scaleMultiplier, hit3DRect, isTablet} from '../../utils/lib';
export default class Scripts {
constructor (spr) {
this.flowCaret = null; this.flowCaret = null;
this.spr = spr; this.spr = spr;
this.dragList = []; this.dragList = [];
@ -14,25 +24,25 @@ var Scripts = function (spr) {
this.sc.owner = this; this.sc.owner = this;
this.sc.top = 0; this.sc.top = 0;
this.sc.left = 0; this.sc.left = 0;
}; }
Scripts.prototype.activate = function () { activate () {
setProps(this.sc.style, { setProps(this.sc.style, {
visibility: 'visible' visibility: 'visible'
}); });
}; }
Scripts.prototype.deactivate = function () { deactivate () {
setProps(this.sc.style, { setProps(this.sc.style, {
visibility: 'hidden' visibility: 'hidden'
}); });
}; }
//////////////////////////////////////////////// ////////////////////////////////////////////////
// Events MouseDown // Events MouseDown
//////////////////////////////////////////////// ////////////////////////////////////////////////
Scripts.prototype.scriptsMouseDown = function (e) { scriptsMouseDown (e) {
if (isTablet && e.touches && (e.touches.length > 1)) { if (isTablet && e.touches && (e.touches.length > 1)) {
return; return;
} }
@ -88,13 +98,13 @@ Scripts.prototype.scriptsMouseDown = function (e) {
return; return;
} }
ScriptsPane.dragBackground(e); ScriptsPane.dragBackground(e);
}; }
//////////////////////////////////////////////// ////////////////////////////////////////////////
// Events MouseUP // Events MouseUP
//////////////////////////////////////////////// ////////////////////////////////////////////////
Scripts.prototype.addBlockToScripts = function (b, dx, dy) { addBlockToScripts (b, dx, dy) {
if ((this.flowCaret != null) && (this.flowCaret.div.parentNode == this.sc)) { if ((this.flowCaret != null) && (this.flowCaret.div.parentNode == this.sc)) {
this.sc.removeChild(this.flowCaret.div); this.sc.removeChild(this.flowCaret.div);
} }
@ -115,10 +125,10 @@ Scripts.prototype.addBlockToScripts = function (b, dx, dy) {
this.sendToBack(b.owner); this.sendToBack(b.owner);
} }
this.dragList = []; this.dragList = [];
}; }
Scripts.prototype.sendToBack = function (b) { sendToBack (b) {
if (!b.inside) { if (!b.inside) {
return; return;
} }
@ -132,17 +142,17 @@ Scripts.prototype.sendToBack = function (b) {
you = you.next; you = you.next;
} }
this.layout(b); this.layout(b);
}; }
Scripts.prototype.snapToPlace = function (drag) { snapToPlace (drag) {
if ((drag.length < 2) && drag[0].cShape) { if ((drag.length < 2) && drag[0].cShape) {
this.snapCshape(drag); this.snapCshape(drag);
} else { } else {
this.snapBlock(drag); this.snapBlock(drag);
} }
}; }
Scripts.prototype.snapBlock = function (drag) { snapBlock (drag) {
var me = drag[0]; var me = drag[0];
var last = me.findLast(); var last = me.findLast();
var res = this.findClosest(this.available(0, me, drag), me); var res = this.findClosest(this.available(0, me, drag), me);
@ -155,9 +165,9 @@ Scripts.prototype.snapBlock = function (drag) {
return; return;
} }
this.snapToDock(res, last, last.cShape ? 2 : 1, drag); this.snapToDock(res, last, last.cShape ? 2 : 1, drag);
}; }
Scripts.prototype.snapCshape = function (drag) { snapCshape (drag) {
var me = drag[0]; var me = drag[0];
var last = me.findLast(); var last = me.findLast();
var res = this.findClosest(this.available(0, me, drag), me); var res = this.findClosest(this.available(0, me, drag), me);
@ -177,9 +187,9 @@ Scripts.prototype.snapCshape = function (drag) {
if (this.isValid(me, res, 2)) { if (this.isValid(me, res, 2)) {
this.snapToDock(res, last, 2, drag); this.snapToDock(res, last, 2, drag);
} }
}; }
Scripts.prototype.isValid = function (me, res, myn) { isValid (me, res, myn) {
if (res == null) { if (res == null) {
return false; return false;
} }
@ -208,11 +218,11 @@ Scripts.prototype.isValid = function (me, res, myn) {
return false; return false;
} }
return true; return true;
}; }
Scripts.prototype.insideCShape = function (you) { insideCShape (you) {
while (you != null) { while (you != null) {
var next = you.prev; var next = you.prev;
if (next == null) { if (next == null) {
@ -225,9 +235,9 @@ Scripts.prototype.insideCShape = function (you) {
you = next; you = next;
} }
return false; return false;
}; }
Scripts.prototype.snapToDock = function (choice, me, place, drag) { snapToDock (choice, me, place, drag) {
if (choice == null) { if (choice == null) {
return; return;
} }
@ -251,9 +261,9 @@ Scripts.prototype.snapToDock = function (choice, me, place, drag) {
drag[i].moveBlock(drag[i].div.left + bestxy[0], drag[i].div.top + bestxy[1]); drag[i].moveBlock(drag[i].div.left + bestxy[0], drag[i].div.top + bestxy[1]);
} }
me.connectBlock(place, choice[0], choice[1]); me.connectBlock(place, choice[0], choice[1]);
}; }
Scripts.prototype.available = function (myn, me, drag) { available (myn, me, drag) {
var thisxy = null; var thisxy = null;
var res = []; var res = [];
var you = null; var you = null;
@ -286,15 +296,15 @@ Scripts.prototype.available = function (myn, me, drag) {
} }
} }
return res; return res;
}; }
Scripts.prototype.magnitude = function (p) { magnitude (p) {
var x = p[0]; var x = p[0];
var y = p[1]; var y = p[1];
return Math.sqrt((x * x) + (y * y)); return Math.sqrt((x * x) + (y * y));
}; }
Scripts.prototype.findClosest = function (choices) { findClosest (choices) {
var min = 9999; var min = 9999;
var item = null; var item = null;
for (var i = 0; i < choices.length; i++) { for (var i = 0; i < choices.length; i++) {
@ -305,9 +315,9 @@ Scripts.prototype.findClosest = function (choices) {
} }
} }
return item; return item;
}; }
Scripts.prototype.getDockDxDy = function (b1, n1, b2, n2) { getDockDxDy (b1, n1, b2, n2) {
var d1 = (b1.resolveDocks())[n1]; var d1 = (b1.resolveDocks())[n1];
var d2 = (b2.resolveDocks())[n2]; var d2 = (b2.resolveDocks())[n2];
if (b1 == b2) { if (b1 == b2) {
@ -327,14 +337,14 @@ Scripts.prototype.getDockDxDy = function (b1, n1, b2, n2) {
var x2 = b2.div.left + d2[2] * b2.scale; var x2 = b2.div.left + d2[2] * b2.scale;
var y2 = b2.div.top + d2[3] * b2.scale; var y2 = b2.div.top + d2[3] * b2.scale;
return [x1 - x2, y1 - y2]; return [x1 - x2, y1 - y2];
}; }
Scripts.prototype.layout = function (block) { layout (block) {
var first = block.findFirst(); var first = block.findFirst();
this.layoutStrip(first); this.layoutStrip(first);
}; }
Scripts.prototype.layoutStrip = function (b) { layoutStrip (b) {
while (b != null) { while (b != null) {
if (b.cShape) { if (b.cShape) {
this.layoutCshape(b); this.layoutCshape(b);
@ -342,9 +352,9 @@ Scripts.prototype.layoutStrip = function (b) {
this.layoutNextBlock(b); this.layoutNextBlock(b);
b = b.next; b = b.next;
} }
}; }
Scripts.prototype.layoutNextBlock = function (b) { layoutNextBlock (b) {
if (b.next != null) { if (b.next != null) {
var you = b.next; var you = b.next;
var bestxy = this.getDockDxDy(b, b.cShape ? 2 : 1, you, 0); var bestxy = this.getDockDxDy(b, b.cShape ? 2 : 1, you, 0);
@ -353,9 +363,9 @@ Scripts.prototype.layoutNextBlock = function (b) {
} }
you.moveBlock(you.div.left + bestxy[0], you.div.top + bestxy[1]); you.moveBlock(you.div.left + bestxy[0], you.div.top + bestxy[1]);
} }
}; }
Scripts.prototype.layoutCshape = function (b) { layoutCshape (b) {
var inside = 0; var inside = 0;
var maxh = 0; var maxh = 0;
var oldh = b.hrubberband; var oldh = b.hrubberband;
@ -371,14 +381,14 @@ Scripts.prototype.layoutCshape = function (b) {
b.hrubberband = inside; b.hrubberband = inside;
b.redrawRepeat(); b.redrawRepeat();
b.moveBlock(b.div.left, b.div.top + (oldh - b.vrubberband) * b.scale); b.moveBlock(b.div.left, b.div.top + (oldh - b.vrubberband) * b.scale);
}; }
Scripts.prototype.adjustPos = function (me, myn, you, yourn) { adjustPos (me, myn, you, yourn) {
var bestxy = this.getDockDxDy(you, yourn, me, myn); var bestxy = this.getDockDxDy(you, yourn, me, myn);
me.moveBlock(me.div.left + bestxy[0], me.div.top + bestxy[1]); me.moveBlock(me.div.left + bestxy[0], me.div.top + bestxy[1]);
}; }
Scripts.prototype.adjustCheight = function (b) { adjustCheight (b) {
var old = b; var old = b;
var h = b.blockshape.height; var h = b.blockshape.height;
b = b.next; b = b.next;
@ -390,9 +400,9 @@ Scripts.prototype.adjustCheight = function (b) {
} }
h /= (old.scale * window.devicePixelRatio); h /= (old.scale * window.devicePixelRatio);
return (h > 66) ? h - 66 : 0; return (h > 66) ? h - 66 : 0;
}; }
Scripts.prototype.adjustCinside = function (b) { adjustCinside (b) {
var first = b; var first = b;
var last = b; var last = b;
while (b != null) { while (b != null) {
@ -402,9 +412,9 @@ Scripts.prototype.adjustCinside = function (b) {
var w = last.blockshape.width / last.scale / window.devicePixelRatio + var w = last.blockshape.width / last.scale / window.devicePixelRatio +
(last.div.left - first.div.left) / last.scale; (last.div.left - first.div.left) / last.scale;
return w - (last.cShape ? 76 : 76); return w - (last.cShape ? 76 : 76);
}; }
Scripts.prototype.getBlocks = function () { getBlocks () {
var res = []; var res = [];
var sc = this.sc; var sc = this.sc;
for (var i = 0; i < sc.childElementCount; i++) { for (var i = 0; i < sc.childElementCount; i++) {
@ -421,17 +431,17 @@ Scripts.prototype.getBlocks = function () {
res.push(b); res.push(b);
} }
return res; return res;
}; }
Scripts.prototype.findGroup = function (b) { findGroup (b) {
if (b.type != 'block') { if (b.type != 'block') {
return []; return [];
} }
var res = []; var res = [];
return this.findingGroup(res, b); return this.findingGroup(res, b);
}; }
Scripts.prototype.findingGroup = function (res, b) { findingGroup (res, b) {
while (b != null) { while (b != null) {
res.push(b); res.push(b);
if (b.cShape) { if (b.cShape) {
@ -440,9 +450,9 @@ Scripts.prototype.findingGroup = function (res, b) {
b = b.next; b = b.next;
} }
return res; return res;
}; }
Scripts.prototype.gettopblocks = function () { gettopblocks () {
var list = this.getBlocks(); var list = this.getBlocks();
var res = []; var res = [];
for (var n = 0; n < list.length; n++) { for (var n = 0; n < list.length; n++) {
@ -454,11 +464,11 @@ Scripts.prototype.gettopblocks = function () {
} }
} }
return res; return res;
}; }
// A version of gettopblocks that also returns strips which // A version of gettopblocks that also returns strips which
// may be currently starting with a caret and blocks in the dragDiv // may be currently starting with a caret and blocks in the dragDiv
Scripts.prototype.getEncodableBlocks = function () { getEncodableBlocks () {
var list = []; var list = [];
var sc = this.sc; var sc = this.sc;
for (var i =0; i < sc.childElementCount; i++){ for (var i =0; i < sc.childElementCount; i++){
@ -474,16 +484,16 @@ Scripts.prototype.getEncodableBlocks = function () {
if (list[n].prev == null) res.push(list[n]); if (list[n].prev == null) res.push(list[n]);
} }
return res; return res;
}; }
Scripts.prototype.redisplay = function () { redisplay () {
var list = this.gettopblocks(); var list = this.gettopblocks();
for (var n = 0; n < list.length; n++) { for (var n = 0; n < list.length; n++) {
this.layout(list[n]); this.layout(list[n]);
} }
}; }
Scripts.prototype.getBlocksType = function (list) { getBlocksType (list) {
var res = []; var res = [];
var blocks = this.getBlocks(); var blocks = this.getBlocks();
for (var i = 0; i < list.length; i++) { for (var i = 0; i < list.length; i++) {
@ -495,9 +505,9 @@ Scripts.prototype.getBlocksType = function (list) {
} }
} }
return res; return res;
}; }
Scripts.prototype.prepareCaret = function (b) { // Block data structure prepareCaret (b) { // Block data structure
var last = b.findLast(); var last = b.findLast();
var bt = this.getCaretType(last); var bt = this.getCaretType(last);
if (this.flowCaret != null) { if (this.flowCaret != null) {
@ -509,9 +519,9 @@ Scripts.prototype.prepareCaret = function (b) { // Block data structure
} // don't have a caret } // don't have a caret
this.flowCaret = this.newCaret(bt); this.flowCaret = this.newCaret(bt);
this.flowCaret.isCaret = true; this.flowCaret.isCaret = true;
}; }
Scripts.prototype.newCaret = function (bt) { // Block data structure newCaret (bt) { // Block data structure
var parent = this.sc; var parent = this.sc;
var bbx = new Block(BlockSpecs.defs[bt], false, scaleMultiplier); var bbx = new Block(BlockSpecs.defs[bt], false, scaleMultiplier);
setProps(bbx.div.style, { setProps(bbx.div.style, {
@ -524,13 +534,13 @@ Scripts.prototype.newCaret = function (bt) { // Block data structure
parent.appendChild(bbx.div); parent.appendChild(bbx.div);
bbx.moveBlock(0, 0); bbx.moveBlock(0, 0);
return bbx; return bbx;
}; }
//////////////////////////////////////////// ////////////////////////////////////////////
// Caret // Caret
/////////////////////////////////////////// ///////////////////////////////////////////
Scripts.prototype.getCaretType = function (b) { getCaretType (b) {
if (this.dragList[0].aStart) { if (this.dragList[0].aStart) {
return 'caretstart'; return 'caretstart';
} }
@ -541,13 +551,13 @@ Scripts.prototype.getCaretType = function (b) {
return 'caretrepeat'; return 'caretrepeat';
} }
return 'caretcmd'; return 'caretcmd';
}; }
//////////////////////////////////////////////// ////////////////////////////////////////////////
// Events MouseMove // Events MouseMove
//////////////////////////////////////////////// ////////////////////////////////////////////////
Scripts.prototype.removeCaret = function () { removeCaret () {
if (this.flowCaret == null) { if (this.flowCaret == null) {
return; return;
} }
@ -586,9 +596,9 @@ Scripts.prototype.removeCaret = function () {
this.flowCaret.redrawRepeat(); this.flowCaret.redrawRepeat();
} }
this.flowCaret.div.style.visibility = 'hidden'; this.flowCaret.div.style.visibility = 'hidden';
}; }
Scripts.prototype.insertCaret = function (x, y) { insertCaret (x, y) {
if (this.flowCaret == null) { if (this.flowCaret == null) {
return; return;
} }
@ -600,9 +610,9 @@ Scripts.prototype.insertCaret = function (x, y) {
if (this.flowCaret.div.style.visibility == 'visible') { if (this.flowCaret.div.style.visibility == 'visible') {
this.layout(this.flowCaret); this.layout(this.flowCaret);
} }
}; }
Scripts.prototype.deleteBlocks = function () { deleteBlocks () {
ScratchJr.storyStart('Scripts.prototype.deleteBlocks'); ScratchJr.storyStart('Scripts.prototype.deleteBlocks');
ScriptsPane.cleanCarets(); ScriptsPane.cleanCarets();
ScratchAudio.sndFX('cut.wav'); ScratchAudio.sndFX('cut.wav');
@ -616,9 +626,9 @@ Scripts.prototype.deleteBlocks = function () {
} }
b.div.parentNode.removeChild(b.div); b.div.parentNode.removeChild(b.div);
} }
}; }
Scripts.prototype.recreateStrip = function (list) { recreateStrip (list) {
var res = []; var res = [];
var b = null; var b = null;
var loops = ['repeat']; var loops = ['repeat'];
@ -670,14 +680,14 @@ Scripts.prototype.recreateStrip = function (list) {
this.layout(res[0]); this.layout(res[0]);
} }
return res; return res;
}; }
///////////////////////////////// /////////////////////////////////
// Load // Load
//////////////////////////////// ////////////////////////////////
Scripts.prototype.recreateBlock = function (data) { recreateBlock (data) {
var op = data[0]; var op = data[0];
var val = data[1] == 'null' ? null : data[1]; var val = data[1] == 'null' ? null : data[1];
var dx = data[2]; var dx = data[2];
@ -696,4 +706,5 @@ Scripts.prototype.recreateBlock = function (data) {
this.sc.appendChild(bbx.div); this.sc.appendChild(bbx.div);
bbx.update(this.spr); bbx.update(this.spr);
return bbx; return bbx;
}; }
}

View file

@ -2,7 +2,11 @@
// Scrolling Pane // Scrolling Pane
//////////////////////////////////////////////// ////////////////////////////////////////////////
var Scroll = function (div, id, w, h, cfcn, ofcn) { import Events from '../../utils/Events';
import {newDiv, newHTML, CSSTransition3D, isTablet, setCanvasSize} from '../../utils/lib';
export default class Scroll {
constructor (div, id, w, h, cfcn, ofcn) {
this.hasHorizontal = true; this.hasHorizontal = true;
this.hasVertical = true; this.hasVertical = true;
this.arrowDistance = 6; this.arrowDistance = 6;
@ -17,19 +21,19 @@ var Scroll = function (div, id, w, h, cfcn, ofcn) {
this.getContent = cfcn; this.getContent = cfcn;
this.getObjects = ofcn; this.getObjects = ofcn;
div.scroll = this; // for now; div.scroll = this; // for now;
}; }
Scroll.prototype.update = function () { update () {
this.adjustCanvas(); this.adjustCanvas();
this.refresh(); this.refresh();
this.bounceBack(); this.bounceBack();
}; }
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
// Arrows // Arrows
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Scroll.prototype.addArrows = function (sc, w, h) { addArrows (sc, w, h) {
this.aleft = newHTML('div', 'leftarrow', sc); this.aleft = newHTML('div', 'leftarrow', sc);
this.aleft.style.height = h + 'px'; this.aleft.style.height = h + 'px';
var larrow = newHTML('span', undefined, this.aleft); var larrow = newHTML('span', undefined, this.aleft);
@ -86,20 +90,20 @@ Scroll.prototype.addArrows = function (sc, w, h) {
}; };
} }
}; }
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
// Scrolling // Scrolling
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Scroll.prototype.repositionArrows = function (h) { repositionArrows (h) {
this.aleft.style.height = h + 'px'; this.aleft.style.height = h + 'px';
this.aleft.childNodes[0].style.top = Math.floor((h - this.aleft.childNodes[0].offsetHeight) / 2) + 'px'; this.aleft.childNodes[0].style.top = Math.floor((h - this.aleft.childNodes[0].offsetHeight) / 2) + 'px';
this.aright.style.height = h + 'px'; this.aright.style.height = h + 'px';
this.aright.childNodes[0].style.top = Math.floor((h - this.aright.childNodes[0].offsetHeight) / 2) + 'px'; this.aright.childNodes[0].style.top = Math.floor((h - this.aright.childNodes[0].offsetHeight) / 2) + 'px';
}; }
Scroll.prototype.getAdjustment = function (rect) { // rect of the dragg block canvas getAdjustment (rect) { // rect of the dragg block canvas
var d = this.contents.parentNode; // scripts var d = this.contents.parentNode; // scripts
var w = d.offsetWidth; var w = d.offsetWidth;
var h = d.offsetHeight; var h = d.offsetHeight;
@ -128,9 +132,9 @@ Scroll.prototype.getAdjustment = function (rect) { // rect of the dragg block ca
return 'left'; return 'left';
} }
return 'none'; return 'none';
}; }
Scroll.prototype.bounceBack = function () { bounceBack () {
var owner = this; var owner = this;
var p = this.contents; // scriptscontainer var p = this.contents; // scriptscontainer
var bc = this.getContent(); // blockcanvas var bc = this.getContent(); // blockcanvas
@ -198,13 +202,13 @@ Scroll.prototype.bounceBack = function () {
} }
break; break;
} }
}; }
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
// Refreshing // Refreshing
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Scroll.prototype.refresh = function () { refresh () {
var p = this.contents; // scriptscontainer var p = this.contents; // scriptscontainer
var bc = this.getContent(); // blockcanvas var bc = this.getContent(); // blockcanvas
var w = p.offsetWidth; var w = p.offsetWidth;
@ -243,9 +247,9 @@ Scroll.prototype.refresh = function () {
this.aright.style.visibility = needright; this.aright.style.visibility = needright;
this.aup.style.visibility = needup; this.aup.style.visibility = needup;
this.adown.style.visibility = needdown; this.adown.style.visibility = needdown;
}; }
Scroll.prototype.adjustCanvas = function () { adjustCanvas () {
var bc = this.getContent(); // blockcanvas var bc = this.getContent(); // blockcanvas
var p = this.contents; // scriptscontainer var p = this.contents; // scriptscontainer
var w = p.offsetWidth; var w = p.offsetWidth;
@ -310,21 +314,21 @@ Scroll.prototype.adjustCanvas = function () {
this.moveBlocks(-minx, -miny); this.moveBlocks(-minx, -miny);
Events.move3D(bc, minx, miny); Events.move3D(bc, minx, miny);
} }
}; }
Scroll.prototype.moveBlocks = function (dx, dy) { moveBlocks (dx, dy) {
var allblocks = this.getObjects(); var allblocks = this.getObjects();
for (var i = 0; i < allblocks.length; i++) { for (var i = 0; i < allblocks.length; i++) {
var b = allblocks[i]; var b = allblocks[i];
b.moveBlock(b.div.left + dx, b.div.top + dy); b.moveBlock(b.div.left + dx, b.div.top + dy);
} }
}; }
///////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////
// Scrolling // Scrolling
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Scroll.prototype.scrolldown = function (e) { scrolldown (e) {
if (isTablet && e.touches && (e.touches.length > 1)) { if (isTablet && e.touches && (e.touches.length > 1)) {
return; return;
} }
@ -350,9 +354,9 @@ Scroll.prototype.scrolldown = function (e) {
} }
}; };
CSSTransition3D(sc, transition); CSSTransition3D(sc, transition);
}; }
Scroll.prototype.scrollup = function (e) { scrollup (e) {
if (isTablet && e.touches && (e.touches.length > 1)) { if (isTablet && e.touches && (e.touches.length > 1)) {
return; return;
} }
@ -378,9 +382,9 @@ Scroll.prototype.scrollup = function (e) {
} }
}; };
CSSTransition3D(sc, transition); CSSTransition3D(sc, transition);
}; }
Scroll.prototype.scrollright = function (e) { scrollright (e) {
if (isTablet && e.touches && (e.touches.length > 1)) { if (isTablet && e.touches && (e.touches.length > 1)) {
return; return;
} }
@ -406,9 +410,9 @@ Scroll.prototype.scrollright = function (e) {
} }
}; };
CSSTransition3D(sc, transition); CSSTransition3D(sc, transition);
}; }
Scroll.prototype.scrollleft = function (e) { scrollleft (e) {
if (isTablet && e.touches && (e.touches.length > 1)) { if (isTablet && e.touches && (e.touches.length > 1)) {
return; return;
} }
@ -434,9 +438,9 @@ Scroll.prototype.scrollleft = function (e) {
} }
}; };
CSSTransition3D(sc, transition); CSSTransition3D(sc, transition);
}; }
Scroll.prototype.fitToScreen = function () { fitToScreen () {
var p = this.contents; var p = this.contents;
var sc = this.getContent(); var sc = this.getContent();
var valx = sc.left; var valx = sc.left;
@ -479,4 +483,5 @@ Scroll.prototype.fitToScreen = function () {
break; break;
} }
Events.move3D(sc, valx, valy); Events.move3D(sc, valx, valy);
}; }
}