mirror of
https://github.com/scratchfoundation/scratchjr.git
synced 2024-11-25 08:38:30 -05:00
Consolidation of Paint module
This commit is contained in:
parent
eae6c944f0
commit
93a7b66cc8
3 changed files with 966 additions and 953 deletions
|
@ -1,3 +1,10 @@
|
||||||
|
// Originally several files (Paint.js, PaintIO.js, PaintLayout.js)
|
||||||
|
// were all contributing utility functions to the Paint object.
|
||||||
|
// To consolidate it into a single module, I've combined these below.
|
||||||
|
// A nice refactor would be to split them back into the "modules," but that will likely involve
|
||||||
|
// some serious code changes - determining where the relevant Paint.X are called, if any shared
|
||||||
|
// data needs to be moved, etc. -TM
|
||||||
|
|
||||||
var Paint = function () {};
|
var Paint = function () {};
|
||||||
|
|
||||||
Paint.xmlns = 'http://www.w3.org/2000/svg';
|
Paint.xmlns = 'http://www.w3.org/2000/svg';
|
||||||
|
@ -454,3 +461,962 @@ Paint.dragBackground = function (evt) {
|
||||||
|
|
||||||
|
|
||||||
Paint.cmdForGesture = [Paint.ignore, Paint.mouseDown, Paint.pinchStart, Paint.Scroll];
|
Paint.cmdForGesture = [Paint.ignore, Paint.mouseDown, Paint.pinchStart, Paint.Scroll];
|
||||||
|
|
||||||
|
// Originally PaintLayout.js
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
//Layout Setup
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
Paint.layout = function () {
|
||||||
|
Paint.topbar();
|
||||||
|
var div = newHTML('div', 'innerpaint', Paint.frame);
|
||||||
|
Paint.leftPalette(div);
|
||||||
|
var workspaceContainer = newHTML('div', 'workspacebkg-container', div);
|
||||||
|
var workspace = newHTML('div', 'workspacebkg', workspaceContainer);
|
||||||
|
workspace.setAttribute('id', 'workspacebkg');
|
||||||
|
Paint.rightPalette(div);
|
||||||
|
Paint.colorPalette(Paint.frame);
|
||||||
|
Paint.selectButton('path');
|
||||||
|
Paint.createSVGeditor(workspace);
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
//top bar
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
Paint.topbar = function () {
|
||||||
|
var pt = newHTML('div', 'paintop', Paint.frame);
|
||||||
|
Paint.checkMark(pt);
|
||||||
|
PaintUndo.setup(pt); // plug here the undo
|
||||||
|
Paint.nameOfcostume(pt);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.checkMark = function (pt) {
|
||||||
|
var clicky = newHTML('div', 'paintdone', pt);
|
||||||
|
clicky.id = 'donecheck';
|
||||||
|
if (isTablet) {
|
||||||
|
clicky.ontouchstart = Paint.backToProject;
|
||||||
|
} else {
|
||||||
|
clicky.onmousedown = Paint.backToProject;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.nameOfcostume = function (p) {
|
||||||
|
var sform = newHTML('form', 'spriteform', p);
|
||||||
|
sform.name = 'spriteform';
|
||||||
|
var ti = newHTML('input', undefined, sform);
|
||||||
|
ti.onkeypress = undefined;
|
||||||
|
ti.autocomplete = 'off';
|
||||||
|
ti.autocorrect = false;
|
||||||
|
ti.name = 'name';
|
||||||
|
ti.maxLength = 25;
|
||||||
|
ti.firstTime = true;
|
||||||
|
ti.onfocus = Paint.nameFocus;
|
||||||
|
ti.onblur = Paint.nameBlur;
|
||||||
|
ti.onkeypress = Paint.handleNamePress;
|
||||||
|
ti.onkeyup = Paint.handleKeyRelease;
|
||||||
|
sform.onsubmit = Paint.submitNameChange;
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.submitNameChange = function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var input = e.target;
|
||||||
|
input.blur();
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.nameFocus = function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var ti = e.target;
|
||||||
|
ti.firstTime = true;
|
||||||
|
ScratchJr.activeFocus = ti;
|
||||||
|
if (isAndroid) {
|
||||||
|
AndroidInterface.scratchjr_setsoftkeyboardscrolllocation(
|
||||||
|
ti.getBoundingClientRect().top * window.devicePixelRatio,
|
||||||
|
ti.getBoundingClientRect().bottom * window.devicePixelRatio
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Undo.aux = Project.getProject(ScratchJr.stage.currentPage.id);
|
||||||
|
setTimeout(function () {
|
||||||
|
ti.setSelectionRange(ti.value.length, ti.value.length);
|
||||||
|
}, 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.nameBlur = function (e) {
|
||||||
|
ScratchJr.activeFocus = undefined;
|
||||||
|
var spr = ScratchJr.getSprite();
|
||||||
|
var ti = e.target;
|
||||||
|
var val = ScratchJr.validate(ti.value, spr.name);
|
||||||
|
ti.value = val.substring(0, ti.maxLength);
|
||||||
|
ScratchJr.storyStart('Paint.nameBlur');
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.handleNamePress = function (e) {
|
||||||
|
var key = e.keyCode || e.which;
|
||||||
|
if (key == 13) {
|
||||||
|
Paint.submitNameChange(e);
|
||||||
|
} else {
|
||||||
|
var ti = e.target;
|
||||||
|
if (ti.firstTime) {
|
||||||
|
ti.firstTime = false;
|
||||||
|
ti.value = '';
|
||||||
|
}
|
||||||
|
if (ti.value.length == 25) {
|
||||||
|
ScratchAudio.sndFX('boing.wav');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.handleKeyRelease = function (e) {
|
||||||
|
var key = e.keyCode || e.which;
|
||||||
|
var ti = e.target;
|
||||||
|
if (key != 8) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ti.firstTime) {
|
||||||
|
ti.firstTime = false;
|
||||||
|
ti.value = '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
//Left Palette
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
Paint.leftPalette = function (div) {
|
||||||
|
var leftpal = newHTML('div', 'side up', div);
|
||||||
|
var pal = newHTML('div', 'paintpalette', leftpal);
|
||||||
|
pal.setAttribute('id', 'paintpalette');
|
||||||
|
Paint.setupEditPalette(pal);
|
||||||
|
Paint.createSizeSelector(pal);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.setupEditPalette = function (pal) {
|
||||||
|
var section = newHTML('div', 'section', pal);
|
||||||
|
section.setAttribute('id', 'painttools');
|
||||||
|
var list = ['path', 'ellipse', 'rect', 'tri'];
|
||||||
|
var i = 0;
|
||||||
|
for (i = 0; i < list.length; i++) {
|
||||||
|
var but = newHTML('div', 'element off', section);
|
||||||
|
var icon = newHTML('div', 'tool ' + list[i] + ' off', but);
|
||||||
|
icon.setAttribute('key', list[i]);
|
||||||
|
if (isTablet) {
|
||||||
|
icon.ontouchstart = Paint.setMode;
|
||||||
|
} else {
|
||||||
|
icon.onmousedown = Paint.setMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.createSizeSelector = function (pal) {
|
||||||
|
var section = newHTML('div', 'section space', pal);
|
||||||
|
section.setAttribute('id', 'sizeSelector');
|
||||||
|
for (var i = 0; i < Paint.pensizes.length; i++) {
|
||||||
|
var ps = newHTML('div', 'pensizeholder', section);
|
||||||
|
ps.key = i;
|
||||||
|
ps.ontouchstart = function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var n = Number(this.key);
|
||||||
|
Paint.strokewidth = Paint.pensizes[Number(this.key)];
|
||||||
|
Paint.selectPenSize(n);
|
||||||
|
};
|
||||||
|
var c = newHTML('div', 'line t' + i, ps);
|
||||||
|
Paint.drawPenSizeInColor(c);
|
||||||
|
}
|
||||||
|
Paint.strokewidth = Paint.pensizes[1];
|
||||||
|
Paint.selectPenSize(1);
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Pen sizes
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
Paint.drawPenSizeInColor = function (c) {
|
||||||
|
c.style.background = Paint.fillcolor;
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.updateStrokes = function () {
|
||||||
|
var div = gn('sizeSelector');
|
||||||
|
if (!div) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < div.childElementCount; i++) {
|
||||||
|
var elem = div.childNodes[i];
|
||||||
|
Paint.drawPenSizeInColor(elem.childNodes[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.selectPenSize = function (str) {
|
||||||
|
var p = gn('sizeSelector');
|
||||||
|
for (var i = 0; i < p.childElementCount; i++) {
|
||||||
|
var elem = p.childNodes[i];
|
||||||
|
if (elem.key == str) {
|
||||||
|
elem.setAttribute('class', 'pensizeholder on');
|
||||||
|
} else {
|
||||||
|
elem.setAttribute('class', 'pensizeholder off');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
//Right Palette
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
Paint.rightPalette = function (div) {
|
||||||
|
var rightpal = newHTML('div', 'side', div);
|
||||||
|
Paint.addSidePalette(rightpal, 'selectortools', ['select', 'rotate']);
|
||||||
|
Paint.addSidePalette(rightpal, 'edittools', ['stamper', 'scissors']);
|
||||||
|
Paint.addSidePalette(rightpal, 'filltools',
|
||||||
|
(iOS.camera == '1' && Camera.available) ? ['camera', 'paintbucket'] : ['paintbucket']);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.addSidePalette = function (p, id, list) {
|
||||||
|
var pal = newHTML('div', 'paintpalette short', p);
|
||||||
|
pal.setAttribute('id', id);
|
||||||
|
for (var i = 0; i < list.length; i++) {
|
||||||
|
var but = newHTML('div', 'element off', pal);
|
||||||
|
var icon = newHTML('div', 'tool ' + list[i] + ' off', but);
|
||||||
|
icon.setAttribute('key', list[i]);
|
||||||
|
icon.ontouchstart = Paint.setMode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.cameraToolsOn = function () {
|
||||||
|
gn('backdrop').setAttribute('class', 'modal-backdrop fade dark');
|
||||||
|
setProps(gn('backdrop').style, {
|
||||||
|
display: 'block'
|
||||||
|
});
|
||||||
|
var topbar = newHTML('div', 'phototopbar', gn('backdrop'));
|
||||||
|
topbar.setAttribute('id', 'photocontrols');
|
||||||
|
// var actions = newHTML("div",'actions', topbar);
|
||||||
|
// var buttons = newHTML('div', 'photobuttons', actions);
|
||||||
|
var fc = newHTML('div', 'flipcamera', topbar);
|
||||||
|
fc.setAttribute('id', 'cameraflip');
|
||||||
|
fc.setAttribute('key', 'cameraflip');
|
||||||
|
if (isAndroid && !AndroidInterface.scratchjr_has_multiple_cameras()) {
|
||||||
|
fc.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
|
fc.ontouchstart = Paint.setMode;
|
||||||
|
var captureContainer = newHTML('div', 'snapshot-container', gn('backdrop'));
|
||||||
|
captureContainer.setAttribute('id', 'capture-container');
|
||||||
|
var capture = newHTML('div', 'snapshot', captureContainer);
|
||||||
|
capture.setAttribute('id', 'capture');
|
||||||
|
capture.setAttribute('key', 'camerasnap');
|
||||||
|
capture.ontouchstart = Paint.setMode;
|
||||||
|
var cc = newHTML('div', 'cameraclose', topbar);
|
||||||
|
cc.setAttribute('id', 'cameraclose');
|
||||||
|
cc.ontouchstart = Paint.closeCameraMode;
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.closeCameraMode = function () {
|
||||||
|
ScratchAudio.sndFX('exittap.wav');
|
||||||
|
Camera.close();
|
||||||
|
Paint.selectButton('select');
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.cameraToolsOff = function () {
|
||||||
|
gn('backdrop').setAttribute('class', 'modal-backdrop fade');
|
||||||
|
setProps(gn('backdrop').style, {
|
||||||
|
display: 'none'
|
||||||
|
});
|
||||||
|
if (gn('photocontrols')) {
|
||||||
|
gn('photocontrols').parentNode.removeChild(gn('photocontrols'));
|
||||||
|
}
|
||||||
|
if (gn('capture')) {
|
||||||
|
var captureContainer = gn('capture').parentNode;
|
||||||
|
var captureContainerParent = captureContainer.parentNode;
|
||||||
|
captureContainer.removeChild(gn('capture'));
|
||||||
|
captureContainerParent.removeChild(gn('capture-container'));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//////////////////////////////////
|
||||||
|
// canvas Area
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
Paint.setUpCanvasArea = function () {
|
||||||
|
var workspace = gn('workspacebkg');
|
||||||
|
var dx = Math.floor((workspace.offsetWidth - Paint.workspaceWidth) / 2);
|
||||||
|
var dy = Math.floor((workspace.offsetHeight - Paint.workspaceHeight) / 2);
|
||||||
|
var w = Paint.workspaceWidth;
|
||||||
|
var h = Paint.workspaceHeight;
|
||||||
|
|
||||||
|
var div = gn('maincanvas');
|
||||||
|
div.style.background = '#F5F2F7';
|
||||||
|
div.style.top = '0px';
|
||||||
|
div.style.left = '0px';
|
||||||
|
|
||||||
|
div.style.width = w + 'px';
|
||||||
|
div.style.height = h + 'px';
|
||||||
|
div.cx = div.offsetWidth / 2;
|
||||||
|
div.cy = div.offsetHeight / 2;
|
||||||
|
div.dx = dx;
|
||||||
|
div.dy = dy;
|
||||||
|
|
||||||
|
Paint.root.setAttributeNS(null, 'width', w);
|
||||||
|
Paint.root.setAttributeNS(null, 'height', h);
|
||||||
|
Paint.drawGrid(w, h);
|
||||||
|
PaintAction.clearEvents();
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////
|
||||||
|
//Color Palette
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
Paint.colorPalette = function (div) {
|
||||||
|
var swatchlist = Paint.initSwatchList();
|
||||||
|
var spalContainer = newHTML('div', 'swatchpalette-container', div);
|
||||||
|
var spal = newHTML('div', 'swatchpalette', spalContainer);
|
||||||
|
spal.setAttribute('id', 'swatches');
|
||||||
|
for (var i = 0; i < swatchlist.length; i++) {
|
||||||
|
var colour = newHTML('div', 'swatchbucket', spal);
|
||||||
|
// bucket
|
||||||
|
var sf = newHTML('div', 'swatchframe', colour);
|
||||||
|
var sc = newHTML('div', 'swatchcolor', sf);
|
||||||
|
sc.style.background = swatchlist[i];
|
||||||
|
//
|
||||||
|
sf = newHTML('div', 'splasharea off', colour);
|
||||||
|
Paint.setSplashColor(sf, Paint.splash, swatchlist[i]);
|
||||||
|
Paint.addImageUrl(sf, Paint.splashshade);
|
||||||
|
colour.ontouchstart = Paint.selectSwatch;
|
||||||
|
}
|
||||||
|
Paint.setSwatchColor(gn('swatches').childNodes[swatchlist.indexOf('#1C1C1C')]);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.setSplashColor = function (p, str, color) {
|
||||||
|
var dataurl = 'data:image/svg+xml;base64,' + btoa(str.replace(/#662D91/g, color));
|
||||||
|
Paint.addImageUrl(p, dataurl);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.addImageUrl = function (p, url) {
|
||||||
|
var img = document.createElement('img');
|
||||||
|
img.src = url;
|
||||||
|
img.style.position = 'absolute';
|
||||||
|
p.appendChild(img);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.selectSwatch = function (e) {
|
||||||
|
if (e.touches && (e.touches.length > 1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
if (Camera.active) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var t;
|
||||||
|
if (window.event) {
|
||||||
|
t = window.event.srcElement;
|
||||||
|
} else {
|
||||||
|
t = e.target;
|
||||||
|
}
|
||||||
|
var b = 'swatchbucket' != t.className;
|
||||||
|
while (b) {
|
||||||
|
t = t.parentNode;
|
||||||
|
b = t && ('swatchbucket' != t.className);
|
||||||
|
}
|
||||||
|
if (!t) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ScratchAudio.sndFX('splash.wav');
|
||||||
|
Paint.setSwatchColor(t);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.setSwatchColor = function (t) {
|
||||||
|
var tools = ['select', 'wand', 'stamper', 'scissors', 'rotate'];
|
||||||
|
if (t && (tools.indexOf(Paint.mode) > -1)) {
|
||||||
|
Paint.selectButton('paintbucket');
|
||||||
|
}
|
||||||
|
var c = t.childNodes[0].childNodes[0].style.backgroundColor;
|
||||||
|
for (var i = 0; i < gn('swatches').childElementCount; i++) {
|
||||||
|
var mycolor = gn('swatches').childNodes[i].childNodes[0].childNodes[0].style.backgroundColor;
|
||||||
|
if (c == mycolor) {
|
||||||
|
gn('swatches').childNodes[i].childNodes[1].setAttribute('class', 'splasharea on');
|
||||||
|
} else {
|
||||||
|
gn('swatches').childNodes[i].childNodes[1].setAttribute('class', 'splasharea off');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Paint.fillcolor = c;
|
||||||
|
Path.quitEditMode();
|
||||||
|
Paint.updateStrokes();
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.initSwatchList = function () {
|
||||||
|
return [
|
||||||
|
// "#FF5500", // new orange
|
||||||
|
'#FFD2F2', '#FF99D6', '#FF4583', // red pinks
|
||||||
|
'#C30001', '#FF0023', '#FF8300', '#FFB200',
|
||||||
|
'#FFF42E',
|
||||||
|
'#FFF9C2', // pale yellow
|
||||||
|
'#E2FFBD', // pale green
|
||||||
|
'#CFF500', // lime green
|
||||||
|
'#50D823', // problematic
|
||||||
|
// "#2BFC49", // less problematic
|
||||||
|
'#29C130',
|
||||||
|
// "#56C43B", // ERROR?
|
||||||
|
'#2BBF8A', // new green
|
||||||
|
'#027607', '#114D24', //greens
|
||||||
|
'#FFFFFF', '#CCDDE7', '#61787C', '#1C1C1C', // grays
|
||||||
|
'#D830A3', // sarah's pink shoes border
|
||||||
|
'#FF64E9', // purple pinks
|
||||||
|
'#D999FF', ' #A159D3', // vilote
|
||||||
|
'#722696', // sarah's violet
|
||||||
|
'#141463', '#003399', '#1D40ED',
|
||||||
|
'#0079D3', '#009EFF', '#76C8FF',
|
||||||
|
'#ACE0FD', '#11B7BC', '#21F9F3', '#C3FCFC', '#54311E',
|
||||||
|
'#8E572A', '#E4B69D', '#FFCDA4', '#FFEDD7' // skin colors
|
||||||
|
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////
|
||||||
|
// Setup SVG Editor
|
||||||
|
////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
Paint.createSVGeditor = function (container) {
|
||||||
|
var div = newHTML('div', 'maincanvas', container);
|
||||||
|
div.setAttribute('id', 'maincanvas');
|
||||||
|
div.style.background = '#F5F2F7';
|
||||||
|
div.style.top = '0px';
|
||||||
|
div.style.left = '0px';
|
||||||
|
window.onmousemove = undefined;
|
||||||
|
window.onmouseup = undefined;
|
||||||
|
Paint.root = SVGTools.create(div);
|
||||||
|
Paint.root.setAttribute('class', 'active3d');
|
||||||
|
xform = Transform.getTranslateTransform();
|
||||||
|
selxform = Transform.getTranslateTransform();
|
||||||
|
var layer = SVGTools.createGroup(Paint.root, 'layer1');
|
||||||
|
layer.setAttribute('style', 'pointer-events:visiblePainted');
|
||||||
|
SVGTools.createGroup(Paint.root, 'draglayer');
|
||||||
|
SVGTools.createGroup(Paint.root, 'paintgrid');
|
||||||
|
gn('paintgrid').setAttribute('opacity', 0.5);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.clearWorkspace = function () {
|
||||||
|
var fcn = function (div) {
|
||||||
|
while (div.childElementCount > 0) {
|
||||||
|
div.removeChild(div.childNodes[0]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fcn(gn('layer1'));
|
||||||
|
fcn(gn('paintgrid'));
|
||||||
|
fcn(gn('draglayer'));
|
||||||
|
Path.quitEditMode();
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.drawGrid = function (w, h) {
|
||||||
|
var attr, path;
|
||||||
|
if (!Paint.isBkg) {
|
||||||
|
attr = {
|
||||||
|
'd': Paint.getGridPath(w, h, 12),
|
||||||
|
'id': getIdFor('gridpath'),
|
||||||
|
'opacity': 1,
|
||||||
|
'stroke': '#dcddde',
|
||||||
|
'fill': 'none',
|
||||||
|
'stroke-width': 0.5
|
||||||
|
};
|
||||||
|
path = SVGTools.addChild(gn('paintgrid'), 'path', attr);
|
||||||
|
path.setAttribute('style', 'pointer-events:none;');
|
||||||
|
}
|
||||||
|
attr = {
|
||||||
|
'd': Paint.getGridPath(w, h, Paint.isBkg ? 24 : 48),
|
||||||
|
'id': getIdFor('gridpath'),
|
||||||
|
'opacity': 1,
|
||||||
|
'stroke': '#c1c2c3',
|
||||||
|
'fill': 'none',
|
||||||
|
'stroke-width': 0.5
|
||||||
|
};
|
||||||
|
path = SVGTools.addChild(gn('paintgrid'), 'path', attr);
|
||||||
|
path.setAttribute('style', 'pointer-events:none;');
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.getGridPath = function (w, h, gridsize) {
|
||||||
|
var str = '';
|
||||||
|
var dx = gridsize;
|
||||||
|
// vertical
|
||||||
|
var cmd;
|
||||||
|
for (var i = 0; i < w / gridsize; i++) {
|
||||||
|
cmd = 'M' + dx + ',' + 0 + 'L' + dx + ',' + h;
|
||||||
|
str += cmd;
|
||||||
|
dx += gridsize;
|
||||||
|
}
|
||||||
|
var dy = gridsize;
|
||||||
|
// horizontal
|
||||||
|
for (i = 0; i < h / gridsize; i++) {
|
||||||
|
cmd = 'M' + 0 + ',' + dy + 'L' + w + ',' + dy;
|
||||||
|
str += cmd;
|
||||||
|
dy += gridsize;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Originally PaintIO.js
|
||||||
|
///////////////////////////
|
||||||
|
// Loading and saving
|
||||||
|
//////////////////////////
|
||||||
|
|
||||||
|
Paint.initBkg = function (ow, oh) {
|
||||||
|
Paint.nativeJr = true;
|
||||||
|
Paint.workspaceWidth = ow;
|
||||||
|
Paint.workspaceHeight = oh;
|
||||||
|
Paint.setUpCanvasArea();
|
||||||
|
var dh = Paint.root.parentNode.parentNode.offsetHeight / (Paint.workspaceHeight + 10);
|
||||||
|
var dw = Paint.root.parentNode.parentNode.offsetWidth / (Paint.workspaceWidth + 10);
|
||||||
|
Paint.setZoomTo(Math.min(dw, dh));
|
||||||
|
document.forms.spriteform.style.visibility = 'hidden';
|
||||||
|
if (Paint.currentMd5) {
|
||||||
|
Paint.loadBackground(Paint.currentMd5);
|
||||||
|
} else {
|
||||||
|
var attr = {
|
||||||
|
'id': 'staticbkg',
|
||||||
|
'opacity': 1,
|
||||||
|
'fixed': 'yes',
|
||||||
|
fill: ScratchJr.stagecolor
|
||||||
|
};
|
||||||
|
var cmds = [['M', 0, 0], ['L', 480, 0], ['L', 480, 360], ['L', 0, 360], ['L', 0, 0]];
|
||||||
|
attr.d = SVG2Canvas.arrayToString(cmds);
|
||||||
|
SVGTools.addChild(gn('layer1'), 'path', attr);
|
||||||
|
Ghost.drawOffscreen();
|
||||||
|
PaintUndo.record(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.loadBackground = function (md5) {
|
||||||
|
if (md5.indexOf('samples/') >= 0) {
|
||||||
|
// Load sample asset
|
||||||
|
Paint.loadChar(md5);
|
||||||
|
} else if (!MediaLib.keys[md5]) {
|
||||||
|
// Load user asset
|
||||||
|
iOS.getmedia(md5, nextStep);
|
||||||
|
} else {
|
||||||
|
// Load library asset
|
||||||
|
Paint.getBkg(MediaLib.path + md5);
|
||||||
|
}
|
||||||
|
function nextStep (base64) {
|
||||||
|
var str = atob(base64);
|
||||||
|
IO.getImagesInSVG(str, function () {
|
||||||
|
Paint.loadBkg(str);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.getBkg = function (url) {
|
||||||
|
var xmlrequest = new XMLHttpRequest();
|
||||||
|
xmlrequest.onreadystatechange = function () {
|
||||||
|
if (xmlrequest.readyState == 4) {
|
||||||
|
Paint.createBkgFromXML(xmlrequest.responseText);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xmlrequest.open('GET', url, true);
|
||||||
|
xmlrequest.send(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.loadBkg = function (str) {
|
||||||
|
Paint.createBkgFromXML(str);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.createBkgFromXML = function (str) {
|
||||||
|
Paint.nativeJr = str.indexOf('Scratch Jr') > -1;
|
||||||
|
str = str.replace(/>\s*</g, '><');
|
||||||
|
var xmlDoc = new DOMParser().parseFromString(str, 'text/xml');
|
||||||
|
var extxml = document.importNode(xmlDoc.documentElement, true);
|
||||||
|
var flat = Paint.skipUnwantedElements(extxml, []);
|
||||||
|
for (var i = 0; i < flat.length; i++) {
|
||||||
|
gn('layer1').appendChild(flat[i]);
|
||||||
|
if (flat[i].getAttribute('id') == 'fixed') {
|
||||||
|
flat[i].setAttribute('fixed', 'yes');
|
||||||
|
}
|
||||||
|
flat[i].setAttribute('file', 'yes');
|
||||||
|
}
|
||||||
|
Paint.doAbsolute(gn('layer1'));
|
||||||
|
if (!Paint.nativeJr) {
|
||||||
|
Paint.reassingIds(gn('layer1'));
|
||||||
|
} // make sure there are unique mask names
|
||||||
|
// gn("layer1").childNodes[0].setAttribute('id', "staticbkg");
|
||||||
|
var dh = Paint.root.parentNode.parentNode.offsetHeight / (Paint.workspaceHeight + 10);
|
||||||
|
var dw = Paint.root.parentNode.parentNode.offsetWidth / (Paint.workspaceWidth + 10);
|
||||||
|
Paint.setZoomTo(Math.min(dw, dh));
|
||||||
|
PaintUndo.record(true);
|
||||||
|
if (!Paint.nativeJr) {
|
||||||
|
Paint.selectButton('paintbucket');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.initSprite = function (ow, oh) {
|
||||||
|
Paint.nativeJr = true;
|
||||||
|
document.forms.spriteform.style.visibility = 'visible';
|
||||||
|
document.forms.spriteform.name.value = gn(Paint.currentName) ? gn(Paint.currentName).owner.name : Paint.currentName;
|
||||||
|
if (ow) {
|
||||||
|
Paint.workspaceWidth = ow;
|
||||||
|
}
|
||||||
|
if (oh) {
|
||||||
|
Paint.workspaceHeight = oh;
|
||||||
|
}
|
||||||
|
if (Paint.currentMd5) {
|
||||||
|
Paint.loadCharacter(Paint.currentMd5);
|
||||||
|
} else {
|
||||||
|
Paint.setUpCanvasArea();
|
||||||
|
setCanvasSize(
|
||||||
|
Ghost.maskCanvas,
|
||||||
|
Math.round(Number(Paint.root.getAttribute('width')) * Paint.currentZoom),
|
||||||
|
Math.round(Number(Paint.root.getAttribute('height')) * Paint.currentZoom)
|
||||||
|
);
|
||||||
|
var dh = Paint.root.parentNode.parentNode.offsetHeight / (Paint.workspaceHeight + 10);
|
||||||
|
var dw = Paint.root.parentNode.parentNode.offsetWidth / (Paint.workspaceWidth + 10);
|
||||||
|
Paint.setZoomTo(Math.min(dw, dh));
|
||||||
|
PaintUndo.record(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.loadCharacter = function (md5) {
|
||||||
|
if (md5.indexOf('samples/') >= 0) {
|
||||||
|
// Load sample asset
|
||||||
|
Paint.loadChar(md5);
|
||||||
|
} else if (!MediaLib.keys[md5]) {
|
||||||
|
// Load user asset
|
||||||
|
iOS.getmedia(md5, nextStep);
|
||||||
|
} else {
|
||||||
|
// Load library asset
|
||||||
|
Paint.loadChar(MediaLib.path + md5);
|
||||||
|
}
|
||||||
|
function nextStep (base64) {
|
||||||
|
var str = atob(base64);
|
||||||
|
IO.getImagesInSVG(str, function () {
|
||||||
|
Paint.loadSprite(str);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.loadSprite = function (svg) {
|
||||||
|
Paint.createCharFromXML(svg, Paint.currentName);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.loadChar = function (url) {
|
||||||
|
var xmlrequest = new XMLHttpRequest();
|
||||||
|
xmlrequest.onreadystatechange = function () {
|
||||||
|
if (xmlrequest.readyState == 4) {
|
||||||
|
Paint.createCharFromXML(xmlrequest.responseText, Paint.currentName);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xmlrequest.open('GET', url, true);
|
||||||
|
xmlrequest.send(null);
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.adjustShapePosition = function (dx, dy) {
|
||||||
|
xform.setTranslate(dx, dy);
|
||||||
|
Transform.translateTo(gn('layer1'), xform);
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////
|
||||||
|
// Saving
|
||||||
|
/////////////////////////////////
|
||||||
|
|
||||||
|
Paint.savePageImage = function (fcn) {
|
||||||
|
var worthsaving = (gn('layer1').childElementCount > 0);
|
||||||
|
if (!worthsaving) {
|
||||||
|
Paint.close();
|
||||||
|
} else {
|
||||||
|
Paint.saving = true;
|
||||||
|
if (fcn) {
|
||||||
|
Alert.open(Paint.frame, gn('donecheck'), Localization.localize('ALERT_SAVING'), '#28A5DA');
|
||||||
|
Alert.balloon.style.zIndex = 12000;
|
||||||
|
}
|
||||||
|
Paint.svgdata = SVGTools.saveBackground(gn('layer1'), Paint.workspaceWidth, Paint.workspaceHeight);
|
||||||
|
IO.setMedia(Paint.svgdata, 'svg', function (str) {
|
||||||
|
Paint.changeBackground(str, fcn);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.changeBackground = function (md5, fcn) {
|
||||||
|
Paint.saveMD5 = md5;
|
||||||
|
var type = 'userbkgs';
|
||||||
|
var mobj = {};
|
||||||
|
mobj.cond = 'md5 = ? AND version = ?';
|
||||||
|
mobj.items = ['*'];
|
||||||
|
mobj.values = [Paint.saveMD5, ScratchJr.version];
|
||||||
|
IO.query(type, mobj, function (str) {
|
||||||
|
Paint.checkDuplicateBkg(str, fcn);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.checkDuplicateBkg = function (str, fcn) {
|
||||||
|
var list = JSON.parse(str);
|
||||||
|
if (list.length > 0) {
|
||||||
|
if (fcn) {
|
||||||
|
fcn('duplicate');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Paint.addToBkgLib(fcn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// userbkgs: stores backgrounds
|
||||||
|
/////////////////////////////////////
|
||||||
|
/*
|
||||||
|
[version] =>
|
||||||
|
[md5] =>
|
||||||
|
[altmd5] => //for PNG option
|
||||||
|
[ext] => png / svg
|
||||||
|
[width] =>
|
||||||
|
[height] =>
|
||||||
|
*/
|
||||||
|
|
||||||
|
Paint.addToBkgLib = function (fcn) {
|
||||||
|
var dataurl = IO.getThumbnail(Paint.svgdata, 480, 360, 120, 90);
|
||||||
|
var pngBase64 = dataurl.split(',')[1];
|
||||||
|
iOS.setmedia(pngBase64, 'png', setBkgRecord);
|
||||||
|
function setBkgRecord (pngmd5) {
|
||||||
|
var json = {};
|
||||||
|
var keylist = ['md5', 'altmd5', 'version', 'width', 'height', 'ext'];
|
||||||
|
var values = '?,?,?,?,?,?';
|
||||||
|
json.values = [Paint.saveMD5, pngmd5, ScratchJr.version, '480', '360', 'svg'];
|
||||||
|
json.stmt = 'insert into userbkgs (' + keylist.toString() + ') values (' + values + ')';
|
||||||
|
iOS.stmt(json, fcn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.changePage = function () {
|
||||||
|
ScratchJr.stage.currentPage.setBackground(Paint.saveMD5, ScratchJr.stage.currentPage.updateBkg);
|
||||||
|
Paint.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.saveSprite = function (fcn) {
|
||||||
|
var cname = document.forms.spriteform.name.value;
|
||||||
|
var worthsaving = (gn('layer1').childElementCount > 0) && (PaintUndo.index > 0);
|
||||||
|
if (worthsaving) {
|
||||||
|
Paint.saving = true;
|
||||||
|
if (fcn) {
|
||||||
|
Alert.open(Paint.frame, gn('donecheck'), 'Saving...', '#28A5DA');
|
||||||
|
Alert.balloon.style.zIndex = 12000;
|
||||||
|
}
|
||||||
|
Paint.svgdata = SVGTools.saveShape(gn('layer1'), Paint.workspaceWidth, Paint.workspaceHeight);
|
||||||
|
IO.setMedia(Paint.svgdata, 'svg', function (str) {
|
||||||
|
Paint.addOrModifySprite(str, fcn);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
var type = Paint.getLoadType(Paint.spriteId, cname);
|
||||||
|
if ((cname != Paint.currentName) && (type == 'modify')) {
|
||||||
|
ScratchJr.stage.currentPage.modifySpriteName(cname, Paint.spriteId);
|
||||||
|
} else if (Paint.currentMd5 && (type == 'add')) {
|
||||||
|
ScratchJr.stage.currentPage.addSprite(Paint.costumeScale, Paint.currentMd5, cname);
|
||||||
|
}
|
||||||
|
Paint.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.addOrModifySprite = function (str, fcn) {
|
||||||
|
Paint.saveMD5 = str;
|
||||||
|
var mobj = {};
|
||||||
|
mobj.cond = 'md5 = ? AND version = ?';
|
||||||
|
mobj.items = ['*'];
|
||||||
|
mobj.values = [Paint.saveMD5, ScratchJr.version];
|
||||||
|
IO.query('usershapes', mobj, function (str) {
|
||||||
|
Paint.checkDuplicate(str, fcn);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.checkDuplicate = function (str, fcn) {
|
||||||
|
var list = JSON.parse(str);
|
||||||
|
if (list.length > 0) {
|
||||||
|
if (fcn) {
|
||||||
|
fcn('duplicate');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Paint.addToLib(fcn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
// usershapes: stores costumes
|
||||||
|
/////////////////////////////////////
|
||||||
|
/* current data
|
||||||
|
[md5] =>
|
||||||
|
[altmd5] => // for PNG -- not used
|
||||||
|
[version] =>
|
||||||
|
[scale] =>
|
||||||
|
[ext] => png / svg
|
||||||
|
[width] =>
|
||||||
|
[height] =>
|
||||||
|
[name] =>
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
Paint.addToLib = function (fcn) {
|
||||||
|
var scale = '0.5'; // always saves with 1/2 the size
|
||||||
|
var cname = document.forms.spriteform.name.value;
|
||||||
|
cname = ((unescape(cname)).replace(/[0-9]/g, '')).replace(/\s*/g, '');
|
||||||
|
var box = SVGTools.getBox(gn('layer1')).rounded();
|
||||||
|
box = box.expandBy(20);
|
||||||
|
var w = box.width.toString();
|
||||||
|
var h = box.height.toString();
|
||||||
|
var dataurl = IO.getThumbnail(Paint.svgdata, w, h, 120, 90);
|
||||||
|
var pngBase64 = dataurl.split(',')[1];
|
||||||
|
iOS.setmedia(pngBase64, 'png', setCostumeRecord);
|
||||||
|
function setCostumeRecord (pngmd5) {
|
||||||
|
var json = {};
|
||||||
|
var keylist = ['scale', 'md5', 'altmd5', 'version', 'width', 'height', 'ext', 'name'];
|
||||||
|
var values = '?,?,?,?,?,?,?,?';
|
||||||
|
json.values = [scale, Paint.saveMD5, pngmd5, ScratchJr.version, w, h, 'svg', cname];
|
||||||
|
json.stmt = 'insert into usershapes (' + keylist.toString() + ') values (' + values + ')';
|
||||||
|
iOS.stmt(json, fcn);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.changePageSprite = function () {
|
||||||
|
Paint.close();
|
||||||
|
var cname = document.forms.spriteform.name.value;
|
||||||
|
var type = Paint.getLoadType(Paint.spriteId, cname);
|
||||||
|
switch (type) {
|
||||||
|
case 'modify':
|
||||||
|
ScratchJr.stage.currentPage.modifySprite(Paint.saveMD5, cname, Paint.spriteId);
|
||||||
|
break;
|
||||||
|
case 'add':
|
||||||
|
ScratchJr.stage.currentPage.addSprite(Paint.costumeScale, Paint.saveMD5, cname);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ScratchJr.stage.currentPage.update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.getLoadType = function (sid, cid) {
|
||||||
|
if (!cid) {
|
||||||
|
return 'none';
|
||||||
|
}
|
||||||
|
if (sid && cid) {
|
||||||
|
return 'modify';
|
||||||
|
}
|
||||||
|
return 'add';
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////
|
||||||
|
// XML import processs
|
||||||
|
///////////////////////////
|
||||||
|
|
||||||
|
Paint.skipUnwantedElements = function (p, res) {
|
||||||
|
for (var i = 0; i < p.childNodes.length; i++) {
|
||||||
|
var elem = p.childNodes[i];
|
||||||
|
if (elem.nodeName == 'metadata') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (elem.nodeName == 'defs') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (elem.nodeName == 'sodipodi:namedview') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (elem.nodeName == '#comment') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((elem.nodeName == 'g') && (elem.id == 'layer1')) {
|
||||||
|
Paint.skipUnwantedElements(elem, res);
|
||||||
|
if (elem.removeAttribute('id')) {
|
||||||
|
elem.removeAttribute('id');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.reassingIds = function (p) {
|
||||||
|
for (var i = 0; i < p.childNodes.length; i++) {
|
||||||
|
var elem = p.childNodes[i];
|
||||||
|
if (elem.parentNode.getAttribute('fixed') == 'yes') {
|
||||||
|
elem.setAttribute('fixed', 'yes');
|
||||||
|
}
|
||||||
|
var id = elem.getAttribute('id');
|
||||||
|
if (!id) {
|
||||||
|
elem.setAttribute('id', getIdFor(elem.nodeName));
|
||||||
|
}
|
||||||
|
if (elem.nodeName == 'g') {
|
||||||
|
Paint.reassingIds(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.createCharFromXML = function (str) {
|
||||||
|
Paint.nativeJr = str.indexOf('Scratch Jr') > -1;
|
||||||
|
var dx = (Paint.workspaceWidth < 432) ? Math.floor((432 - Paint.workspaceWidth) / 2) : 0;
|
||||||
|
var dy = (Paint.workspaceHeight < 384) ? Math.floor((384 - Paint.workspaceHeight) / 2) : 0;
|
||||||
|
if (Paint.workspaceWidth < 432) {
|
||||||
|
Paint.workspaceWidth = 432;
|
||||||
|
}
|
||||||
|
if (Paint.workspaceHeight < 384) {
|
||||||
|
Paint.workspaceHeight = 384;
|
||||||
|
}
|
||||||
|
Paint.setUpCanvasArea();
|
||||||
|
str = str.replace(/>\s*</g, '><');
|
||||||
|
var xmlDoc = new DOMParser().parseFromString(str, 'text/xml');
|
||||||
|
var extxml = document.importNode(xmlDoc.documentElement, true);
|
||||||
|
var flat = Paint.skipUnwantedElements(extxml, []);
|
||||||
|
for (var i = 0; i < flat.length; i++) {
|
||||||
|
gn('layer1').appendChild(flat[i]);
|
||||||
|
}
|
||||||
|
Paint.doAbsolute(gn('layer1'));
|
||||||
|
Paint.adjustShapePosition(dx, dy);
|
||||||
|
if (!Paint.nativeJr) {
|
||||||
|
Paint.reassingIds(gn('layer1'));
|
||||||
|
} // make sure there are unique mask names
|
||||||
|
Paint.scaleToFit();
|
||||||
|
Paint.minZoom = Paint.currentZoom < 1 ? Paint.currentZoom / 2 : 1;
|
||||||
|
var maxpix = 2290 * 2289; // Magic iOS max canvas size
|
||||||
|
var ratio = maxpix / (Paint.workspaceWidth * Paint.workspaceHeight);
|
||||||
|
var zoom = Math.floor(Math.sqrt(ratio));
|
||||||
|
if (zoom < Paint.maxZoom) {
|
||||||
|
Paint.maxZoom = zoom;
|
||||||
|
}
|
||||||
|
PaintUndo.record(true);
|
||||||
|
if (!Paint.nativeJr) {
|
||||||
|
Paint.selectButton('paintbucket');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.doAbsolute = function (div) {
|
||||||
|
for (var i = 0; i < div.childElementCount; i++) {
|
||||||
|
var elem = div.childNodes[i];
|
||||||
|
if (elem.tagName == 'path') {
|
||||||
|
SVG2Canvas.setAbsolutePath(elem);
|
||||||
|
}
|
||||||
|
if (elem.tagName == 'g') {
|
||||||
|
Paint.doAbsolute(div.childNodes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Paint.getComponents = function (p, res) {
|
||||||
|
for (var i = 0; i < p.childNodes.length; i++) {
|
||||||
|
var elem = p.childNodes[i];
|
||||||
|
if (elem.nodeName == 'metadata') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (elem.nodeName == 'defs') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (elem.nodeName == 'sodipodi:namedview') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (elem.nodeName == '#comment') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (elem.nodeName == 'g') {
|
||||||
|
Paint.getComponents(elem, res);
|
||||||
|
if (elem.getAttribute('id')) {
|
||||||
|
elem.removeAttribute('id');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
res.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
|
@ -1,462 +0,0 @@
|
||||||
///////////////////////////
|
|
||||||
// Loading and saving
|
|
||||||
//////////////////////////
|
|
||||||
|
|
||||||
Paint.initBkg = function (ow, oh) {
|
|
||||||
Paint.nativeJr = true;
|
|
||||||
Paint.workspaceWidth = ow;
|
|
||||||
Paint.workspaceHeight = oh;
|
|
||||||
Paint.setUpCanvasArea();
|
|
||||||
var dh = Paint.root.parentNode.parentNode.offsetHeight / (Paint.workspaceHeight + 10);
|
|
||||||
var dw = Paint.root.parentNode.parentNode.offsetWidth / (Paint.workspaceWidth + 10);
|
|
||||||
Paint.setZoomTo(Math.min(dw, dh));
|
|
||||||
document.forms.spriteform.style.visibility = 'hidden';
|
|
||||||
if (Paint.currentMd5) {
|
|
||||||
Paint.loadBackground(Paint.currentMd5);
|
|
||||||
} else {
|
|
||||||
var attr = {
|
|
||||||
'id': 'staticbkg',
|
|
||||||
'opacity': 1,
|
|
||||||
'fixed': 'yes',
|
|
||||||
fill: ScratchJr.stagecolor
|
|
||||||
};
|
|
||||||
var cmds = [['M', 0, 0], ['L', 480, 0], ['L', 480, 360], ['L', 0, 360], ['L', 0, 0]];
|
|
||||||
attr.d = SVG2Canvas.arrayToString(cmds);
|
|
||||||
SVGTools.addChild(gn('layer1'), 'path', attr);
|
|
||||||
Ghost.drawOffscreen();
|
|
||||||
PaintUndo.record(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.loadBackground = function (md5) {
|
|
||||||
if (md5.indexOf('samples/') >= 0) {
|
|
||||||
// Load sample asset
|
|
||||||
Paint.loadChar(md5);
|
|
||||||
} else if (!MediaLib.keys[md5]) {
|
|
||||||
// Load user asset
|
|
||||||
iOS.getmedia(md5, nextStep);
|
|
||||||
} else {
|
|
||||||
// Load library asset
|
|
||||||
Paint.getBkg(MediaLib.path + md5);
|
|
||||||
}
|
|
||||||
function nextStep (base64) {
|
|
||||||
var str = atob(base64);
|
|
||||||
IO.getImagesInSVG(str, function () {
|
|
||||||
Paint.loadBkg(str);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.getBkg = function (url) {
|
|
||||||
var xmlrequest = new XMLHttpRequest();
|
|
||||||
xmlrequest.onreadystatechange = function () {
|
|
||||||
if (xmlrequest.readyState == 4) {
|
|
||||||
Paint.createBkgFromXML(xmlrequest.responseText);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xmlrequest.open('GET', url, true);
|
|
||||||
xmlrequest.send(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.loadBkg = function (str) {
|
|
||||||
Paint.createBkgFromXML(str);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.createBkgFromXML = function (str) {
|
|
||||||
Paint.nativeJr = str.indexOf('Scratch Jr') > -1;
|
|
||||||
str = str.replace(/>\s*</g, '><');
|
|
||||||
var xmlDoc = new DOMParser().parseFromString(str, 'text/xml');
|
|
||||||
var extxml = document.importNode(xmlDoc.documentElement, true);
|
|
||||||
var flat = Paint.skipUnwantedElements(extxml, []);
|
|
||||||
for (var i = 0; i < flat.length; i++) {
|
|
||||||
gn('layer1').appendChild(flat[i]);
|
|
||||||
if (flat[i].getAttribute('id') == 'fixed') {
|
|
||||||
flat[i].setAttribute('fixed', 'yes');
|
|
||||||
}
|
|
||||||
flat[i].setAttribute('file', 'yes');
|
|
||||||
}
|
|
||||||
Paint.doAbsolute(gn('layer1'));
|
|
||||||
if (!Paint.nativeJr) {
|
|
||||||
Paint.reassingIds(gn('layer1'));
|
|
||||||
} // make sure there are unique mask names
|
|
||||||
// gn("layer1").childNodes[0].setAttribute('id', "staticbkg");
|
|
||||||
var dh = Paint.root.parentNode.parentNode.offsetHeight / (Paint.workspaceHeight + 10);
|
|
||||||
var dw = Paint.root.parentNode.parentNode.offsetWidth / (Paint.workspaceWidth + 10);
|
|
||||||
Paint.setZoomTo(Math.min(dw, dh));
|
|
||||||
PaintUndo.record(true);
|
|
||||||
if (!Paint.nativeJr) {
|
|
||||||
Paint.selectButton('paintbucket');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.initSprite = function (ow, oh) {
|
|
||||||
Paint.nativeJr = true;
|
|
||||||
document.forms.spriteform.style.visibility = 'visible';
|
|
||||||
document.forms.spriteform.name.value = gn(Paint.currentName) ? gn(Paint.currentName).owner.name : Paint.currentName;
|
|
||||||
if (ow) {
|
|
||||||
Paint.workspaceWidth = ow;
|
|
||||||
}
|
|
||||||
if (oh) {
|
|
||||||
Paint.workspaceHeight = oh;
|
|
||||||
}
|
|
||||||
if (Paint.currentMd5) {
|
|
||||||
Paint.loadCharacter(Paint.currentMd5);
|
|
||||||
} else {
|
|
||||||
Paint.setUpCanvasArea();
|
|
||||||
setCanvasSize(
|
|
||||||
Ghost.maskCanvas,
|
|
||||||
Math.round(Number(Paint.root.getAttribute('width')) * Paint.currentZoom),
|
|
||||||
Math.round(Number(Paint.root.getAttribute('height')) * Paint.currentZoom)
|
|
||||||
);
|
|
||||||
var dh = Paint.root.parentNode.parentNode.offsetHeight / (Paint.workspaceHeight + 10);
|
|
||||||
var dw = Paint.root.parentNode.parentNode.offsetWidth / (Paint.workspaceWidth + 10);
|
|
||||||
Paint.setZoomTo(Math.min(dw, dh));
|
|
||||||
PaintUndo.record(true);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.loadCharacter = function (md5) {
|
|
||||||
if (md5.indexOf('samples/') >= 0) {
|
|
||||||
// Load sample asset
|
|
||||||
Paint.loadChar(md5);
|
|
||||||
} else if (!MediaLib.keys[md5]) {
|
|
||||||
// Load user asset
|
|
||||||
iOS.getmedia(md5, nextStep);
|
|
||||||
} else {
|
|
||||||
// Load library asset
|
|
||||||
Paint.loadChar(MediaLib.path + md5);
|
|
||||||
}
|
|
||||||
function nextStep (base64) {
|
|
||||||
var str = atob(base64);
|
|
||||||
IO.getImagesInSVG(str, function () {
|
|
||||||
Paint.loadSprite(str);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.loadSprite = function (svg) {
|
|
||||||
Paint.createCharFromXML(svg, Paint.currentName);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.loadChar = function (url) {
|
|
||||||
var xmlrequest = new XMLHttpRequest();
|
|
||||||
xmlrequest.onreadystatechange = function () {
|
|
||||||
if (xmlrequest.readyState == 4) {
|
|
||||||
Paint.createCharFromXML(xmlrequest.responseText, Paint.currentName);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xmlrequest.open('GET', url, true);
|
|
||||||
xmlrequest.send(null);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.adjustShapePosition = function (dx, dy) {
|
|
||||||
xform.setTranslate(dx, dy);
|
|
||||||
Transform.translateTo(gn('layer1'), xform);
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////////////
|
|
||||||
// Saving
|
|
||||||
/////////////////////////////////
|
|
||||||
|
|
||||||
Paint.savePageImage = function (fcn) {
|
|
||||||
var worthsaving = (gn('layer1').childElementCount > 0);
|
|
||||||
if (!worthsaving) {
|
|
||||||
Paint.close();
|
|
||||||
} else {
|
|
||||||
Paint.saving = true;
|
|
||||||
if (fcn) {
|
|
||||||
Alert.open(Paint.frame, gn('donecheck'), Localization.localize('ALERT_SAVING'), '#28A5DA');
|
|
||||||
Alert.balloon.style.zIndex = 12000;
|
|
||||||
}
|
|
||||||
Paint.svgdata = SVGTools.saveBackground(gn('layer1'), Paint.workspaceWidth, Paint.workspaceHeight);
|
|
||||||
IO.setMedia(Paint.svgdata, 'svg', function (str) {
|
|
||||||
Paint.changeBackground(str, fcn);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.changeBackground = function (md5, fcn) {
|
|
||||||
Paint.saveMD5 = md5;
|
|
||||||
var type = 'userbkgs';
|
|
||||||
var mobj = {};
|
|
||||||
mobj.cond = 'md5 = ? AND version = ?';
|
|
||||||
mobj.items = ['*'];
|
|
||||||
mobj.values = [Paint.saveMD5, ScratchJr.version];
|
|
||||||
IO.query(type, mobj, function (str) {
|
|
||||||
Paint.checkDuplicateBkg(str, fcn);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.checkDuplicateBkg = function (str, fcn) {
|
|
||||||
var list = JSON.parse(str);
|
|
||||||
if (list.length > 0) {
|
|
||||||
if (fcn) {
|
|
||||||
fcn('duplicate');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Paint.addToBkgLib(fcn);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////
|
|
||||||
// userbkgs: stores backgrounds
|
|
||||||
/////////////////////////////////////
|
|
||||||
/*
|
|
||||||
[version] =>
|
|
||||||
[md5] =>
|
|
||||||
[altmd5] => //for PNG option
|
|
||||||
[ext] => png / svg
|
|
||||||
[width] =>
|
|
||||||
[height] =>
|
|
||||||
*/
|
|
||||||
|
|
||||||
Paint.addToBkgLib = function (fcn) {
|
|
||||||
var dataurl = IO.getThumbnail(Paint.svgdata, 480, 360, 120, 90);
|
|
||||||
var pngBase64 = dataurl.split(',')[1];
|
|
||||||
iOS.setmedia(pngBase64, 'png', setBkgRecord);
|
|
||||||
function setBkgRecord (pngmd5) {
|
|
||||||
var json = {};
|
|
||||||
var keylist = ['md5', 'altmd5', 'version', 'width', 'height', 'ext'];
|
|
||||||
var values = '?,?,?,?,?,?';
|
|
||||||
json.values = [Paint.saveMD5, pngmd5, ScratchJr.version, '480', '360', 'svg'];
|
|
||||||
json.stmt = 'insert into userbkgs (' + keylist.toString() + ') values (' + values + ')';
|
|
||||||
iOS.stmt(json, fcn);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.changePage = function () {
|
|
||||||
ScratchJr.stage.currentPage.setBackground(Paint.saveMD5, ScratchJr.stage.currentPage.updateBkg);
|
|
||||||
Paint.close();
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.saveSprite = function (fcn) {
|
|
||||||
var cname = document.forms.spriteform.name.value;
|
|
||||||
var worthsaving = (gn('layer1').childElementCount > 0) && (PaintUndo.index > 0);
|
|
||||||
if (worthsaving) {
|
|
||||||
Paint.saving = true;
|
|
||||||
if (fcn) {
|
|
||||||
Alert.open(Paint.frame, gn('donecheck'), 'Saving...', '#28A5DA');
|
|
||||||
Alert.balloon.style.zIndex = 12000;
|
|
||||||
}
|
|
||||||
Paint.svgdata = SVGTools.saveShape(gn('layer1'), Paint.workspaceWidth, Paint.workspaceHeight);
|
|
||||||
IO.setMedia(Paint.svgdata, 'svg', function (str) {
|
|
||||||
Paint.addOrModifySprite(str, fcn);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
var type = Paint.getLoadType(Paint.spriteId, cname);
|
|
||||||
if ((cname != Paint.currentName) && (type == 'modify')) {
|
|
||||||
ScratchJr.stage.currentPage.modifySpriteName(cname, Paint.spriteId);
|
|
||||||
} else if (Paint.currentMd5 && (type == 'add')) {
|
|
||||||
ScratchJr.stage.currentPage.addSprite(Paint.costumeScale, Paint.currentMd5, cname);
|
|
||||||
}
|
|
||||||
Paint.close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.addOrModifySprite = function (str, fcn) {
|
|
||||||
Paint.saveMD5 = str;
|
|
||||||
var mobj = {};
|
|
||||||
mobj.cond = 'md5 = ? AND version = ?';
|
|
||||||
mobj.items = ['*'];
|
|
||||||
mobj.values = [Paint.saveMD5, ScratchJr.version];
|
|
||||||
IO.query('usershapes', mobj, function (str) {
|
|
||||||
Paint.checkDuplicate(str, fcn);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.checkDuplicate = function (str, fcn) {
|
|
||||||
var list = JSON.parse(str);
|
|
||||||
if (list.length > 0) {
|
|
||||||
if (fcn) {
|
|
||||||
fcn('duplicate');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Paint.addToLib(fcn);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////
|
|
||||||
// usershapes: stores costumes
|
|
||||||
/////////////////////////////////////
|
|
||||||
/* current data
|
|
||||||
[md5] =>
|
|
||||||
[altmd5] => // for PNG -- not used
|
|
||||||
[version] =>
|
|
||||||
[scale] =>
|
|
||||||
[ext] => png / svg
|
|
||||||
[width] =>
|
|
||||||
[height] =>
|
|
||||||
[name] =>
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
Paint.addToLib = function (fcn) {
|
|
||||||
var scale = '0.5'; // always saves with 1/2 the size
|
|
||||||
var cname = document.forms.spriteform.name.value;
|
|
||||||
cname = ((unescape(cname)).replace(/[0-9]/g, '')).replace(/\s*/g, '');
|
|
||||||
var box = SVGTools.getBox(gn('layer1')).rounded();
|
|
||||||
box = box.expandBy(20);
|
|
||||||
var w = box.width.toString();
|
|
||||||
var h = box.height.toString();
|
|
||||||
var dataurl = IO.getThumbnail(Paint.svgdata, w, h, 120, 90);
|
|
||||||
var pngBase64 = dataurl.split(',')[1];
|
|
||||||
iOS.setmedia(pngBase64, 'png', setCostumeRecord);
|
|
||||||
function setCostumeRecord (pngmd5) {
|
|
||||||
var json = {};
|
|
||||||
var keylist = ['scale', 'md5', 'altmd5', 'version', 'width', 'height', 'ext', 'name'];
|
|
||||||
var values = '?,?,?,?,?,?,?,?';
|
|
||||||
json.values = [scale, Paint.saveMD5, pngmd5, ScratchJr.version, w, h, 'svg', cname];
|
|
||||||
json.stmt = 'insert into usershapes (' + keylist.toString() + ') values (' + values + ')';
|
|
||||||
iOS.stmt(json, fcn);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.changePageSprite = function () {
|
|
||||||
Paint.close();
|
|
||||||
var cname = document.forms.spriteform.name.value;
|
|
||||||
var type = Paint.getLoadType(Paint.spriteId, cname);
|
|
||||||
switch (type) {
|
|
||||||
case 'modify':
|
|
||||||
ScratchJr.stage.currentPage.modifySprite(Paint.saveMD5, cname, Paint.spriteId);
|
|
||||||
break;
|
|
||||||
case 'add':
|
|
||||||
ScratchJr.stage.currentPage.addSprite(Paint.costumeScale, Paint.saveMD5, cname);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ScratchJr.stage.currentPage.update();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.getLoadType = function (sid, cid) {
|
|
||||||
if (!cid) {
|
|
||||||
return 'none';
|
|
||||||
}
|
|
||||||
if (sid && cid) {
|
|
||||||
return 'modify';
|
|
||||||
}
|
|
||||||
return 'add';
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////////
|
|
||||||
// XML import processs
|
|
||||||
///////////////////////////
|
|
||||||
|
|
||||||
Paint.skipUnwantedElements = function (p, res) {
|
|
||||||
for (var i = 0; i < p.childNodes.length; i++) {
|
|
||||||
var elem = p.childNodes[i];
|
|
||||||
if (elem.nodeName == 'metadata') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (elem.nodeName == 'defs') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (elem.nodeName == 'sodipodi:namedview') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (elem.nodeName == '#comment') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if ((elem.nodeName == 'g') && (elem.id == 'layer1')) {
|
|
||||||
Paint.skipUnwantedElements(elem, res);
|
|
||||||
if (elem.removeAttribute('id')) {
|
|
||||||
elem.removeAttribute('id');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.push(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.reassingIds = function (p) {
|
|
||||||
for (var i = 0; i < p.childNodes.length; i++) {
|
|
||||||
var elem = p.childNodes[i];
|
|
||||||
if (elem.parentNode.getAttribute('fixed') == 'yes') {
|
|
||||||
elem.setAttribute('fixed', 'yes');
|
|
||||||
}
|
|
||||||
var id = elem.getAttribute('id');
|
|
||||||
if (!id) {
|
|
||||||
elem.setAttribute('id', getIdFor(elem.nodeName));
|
|
||||||
}
|
|
||||||
if (elem.nodeName == 'g') {
|
|
||||||
Paint.reassingIds(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.createCharFromXML = function (str) {
|
|
||||||
Paint.nativeJr = str.indexOf('Scratch Jr') > -1;
|
|
||||||
var dx = (Paint.workspaceWidth < 432) ? Math.floor((432 - Paint.workspaceWidth) / 2) : 0;
|
|
||||||
var dy = (Paint.workspaceHeight < 384) ? Math.floor((384 - Paint.workspaceHeight) / 2) : 0;
|
|
||||||
if (Paint.workspaceWidth < 432) {
|
|
||||||
Paint.workspaceWidth = 432;
|
|
||||||
}
|
|
||||||
if (Paint.workspaceHeight < 384) {
|
|
||||||
Paint.workspaceHeight = 384;
|
|
||||||
}
|
|
||||||
Paint.setUpCanvasArea();
|
|
||||||
str = str.replace(/>\s*</g, '><');
|
|
||||||
var xmlDoc = new DOMParser().parseFromString(str, 'text/xml');
|
|
||||||
var extxml = document.importNode(xmlDoc.documentElement, true);
|
|
||||||
var flat = Paint.skipUnwantedElements(extxml, []);
|
|
||||||
for (var i = 0; i < flat.length; i++) {
|
|
||||||
gn('layer1').appendChild(flat[i]);
|
|
||||||
}
|
|
||||||
Paint.doAbsolute(gn('layer1'));
|
|
||||||
Paint.adjustShapePosition(dx, dy);
|
|
||||||
if (!Paint.nativeJr) {
|
|
||||||
Paint.reassingIds(gn('layer1'));
|
|
||||||
} // make sure there are unique mask names
|
|
||||||
Paint.scaleToFit();
|
|
||||||
Paint.minZoom = Paint.currentZoom < 1 ? Paint.currentZoom / 2 : 1;
|
|
||||||
var maxpix = 2290 * 2289; // Magic iOS max canvas size
|
|
||||||
var ratio = maxpix / (Paint.workspaceWidth * Paint.workspaceHeight);
|
|
||||||
var zoom = Math.floor(Math.sqrt(ratio));
|
|
||||||
if (zoom < Paint.maxZoom) {
|
|
||||||
Paint.maxZoom = zoom;
|
|
||||||
}
|
|
||||||
PaintUndo.record(true);
|
|
||||||
if (!Paint.nativeJr) {
|
|
||||||
Paint.selectButton('paintbucket');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.doAbsolute = function (div) {
|
|
||||||
for (var i = 0; i < div.childElementCount; i++) {
|
|
||||||
var elem = div.childNodes[i];
|
|
||||||
if (elem.tagName == 'path') {
|
|
||||||
SVG2Canvas.setAbsolutePath(elem);
|
|
||||||
}
|
|
||||||
if (elem.tagName == 'g') {
|
|
||||||
Paint.doAbsolute(div.childNodes[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.getComponents = function (p, res) {
|
|
||||||
for (var i = 0; i < p.childNodes.length; i++) {
|
|
||||||
var elem = p.childNodes[i];
|
|
||||||
if (elem.nodeName == 'metadata') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (elem.nodeName == 'defs') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (elem.nodeName == 'sodipodi:namedview') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (elem.nodeName == '#comment') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (elem.nodeName == 'g') {
|
|
||||||
Paint.getComponents(elem, res);
|
|
||||||
if (elem.getAttribute('id')) {
|
|
||||||
elem.removeAttribute('id');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
res.push(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
};
|
|
|
@ -1,491 +0,0 @@
|
||||||
/////////////////////////////////
|
|
||||||
//Layout Setup
|
|
||||||
/////////////////////////////////
|
|
||||||
|
|
||||||
Paint.layout = function () {
|
|
||||||
Paint.topbar();
|
|
||||||
var div = newHTML('div', 'innerpaint', Paint.frame);
|
|
||||||
Paint.leftPalette(div);
|
|
||||||
var workspaceContainer = newHTML('div', 'workspacebkg-container', div);
|
|
||||||
var workspace = newHTML('div', 'workspacebkg', workspaceContainer);
|
|
||||||
workspace.setAttribute('id', 'workspacebkg');
|
|
||||||
Paint.rightPalette(div);
|
|
||||||
Paint.colorPalette(Paint.frame);
|
|
||||||
Paint.selectButton('path');
|
|
||||||
Paint.createSVGeditor(workspace);
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////
|
|
||||||
//top bar
|
|
||||||
/////////////////////////////////
|
|
||||||
|
|
||||||
Paint.topbar = function () {
|
|
||||||
var pt = newHTML('div', 'paintop', Paint.frame);
|
|
||||||
Paint.checkMark(pt);
|
|
||||||
PaintUndo.setup(pt); // plug here the undo
|
|
||||||
Paint.nameOfcostume(pt);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.checkMark = function (pt) {
|
|
||||||
var clicky = newHTML('div', 'paintdone', pt);
|
|
||||||
clicky.id = 'donecheck';
|
|
||||||
if (isTablet) {
|
|
||||||
clicky.ontouchstart = Paint.backToProject;
|
|
||||||
} else {
|
|
||||||
clicky.onmousedown = Paint.backToProject;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.nameOfcostume = function (p) {
|
|
||||||
var sform = newHTML('form', 'spriteform', p);
|
|
||||||
sform.name = 'spriteform';
|
|
||||||
var ti = newHTML('input', undefined, sform);
|
|
||||||
ti.onkeypress = undefined;
|
|
||||||
ti.autocomplete = 'off';
|
|
||||||
ti.autocorrect = false;
|
|
||||||
ti.name = 'name';
|
|
||||||
ti.maxLength = 25;
|
|
||||||
ti.firstTime = true;
|
|
||||||
ti.onfocus = Paint.nameFocus;
|
|
||||||
ti.onblur = Paint.nameBlur;
|
|
||||||
ti.onkeypress = Paint.handleNamePress;
|
|
||||||
ti.onkeyup = Paint.handleKeyRelease;
|
|
||||||
sform.onsubmit = Paint.submitNameChange;
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.submitNameChange = function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
var input = e.target;
|
|
||||||
input.blur();
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.nameFocus = function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
var ti = e.target;
|
|
||||||
ti.firstTime = true;
|
|
||||||
ScratchJr.activeFocus = ti;
|
|
||||||
if (isAndroid) {
|
|
||||||
AndroidInterface.scratchjr_setsoftkeyboardscrolllocation(
|
|
||||||
ti.getBoundingClientRect().top * window.devicePixelRatio,
|
|
||||||
ti.getBoundingClientRect().bottom * window.devicePixelRatio
|
|
||||||
);
|
|
||||||
}
|
|
||||||
Undo.aux = Project.getProject(ScratchJr.stage.currentPage.id);
|
|
||||||
setTimeout(function () {
|
|
||||||
ti.setSelectionRange(ti.value.length, ti.value.length);
|
|
||||||
}, 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.nameBlur = function (e) {
|
|
||||||
ScratchJr.activeFocus = undefined;
|
|
||||||
var spr = ScratchJr.getSprite();
|
|
||||||
var ti = e.target;
|
|
||||||
var val = ScratchJr.validate(ti.value, spr.name);
|
|
||||||
ti.value = val.substring(0, ti.maxLength);
|
|
||||||
ScratchJr.storyStart('Paint.nameBlur');
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.handleNamePress = function (e) {
|
|
||||||
var key = e.keyCode || e.which;
|
|
||||||
if (key == 13) {
|
|
||||||
Paint.submitNameChange(e);
|
|
||||||
} else {
|
|
||||||
var ti = e.target;
|
|
||||||
if (ti.firstTime) {
|
|
||||||
ti.firstTime = false;
|
|
||||||
ti.value = '';
|
|
||||||
}
|
|
||||||
if (ti.value.length == 25) {
|
|
||||||
ScratchAudio.sndFX('boing.wav');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.handleKeyRelease = function (e) {
|
|
||||||
var key = e.keyCode || e.which;
|
|
||||||
var ti = e.target;
|
|
||||||
if (key != 8) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (ti.firstTime) {
|
|
||||||
ti.firstTime = false;
|
|
||||||
ti.value = '';
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////
|
|
||||||
//Left Palette
|
|
||||||
/////////////////////////////////
|
|
||||||
|
|
||||||
Paint.leftPalette = function (div) {
|
|
||||||
var leftpal = newHTML('div', 'side up', div);
|
|
||||||
var pal = newHTML('div', 'paintpalette', leftpal);
|
|
||||||
pal.setAttribute('id', 'paintpalette');
|
|
||||||
Paint.setupEditPalette(pal);
|
|
||||||
Paint.createSizeSelector(pal);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.setupEditPalette = function (pal) {
|
|
||||||
var section = newHTML('div', 'section', pal);
|
|
||||||
section.setAttribute('id', 'painttools');
|
|
||||||
var list = ['path', 'ellipse', 'rect', 'tri'];
|
|
||||||
var i = 0;
|
|
||||||
for (i = 0; i < list.length; i++) {
|
|
||||||
var but = newHTML('div', 'element off', section);
|
|
||||||
var icon = newHTML('div', 'tool ' + list[i] + ' off', but);
|
|
||||||
icon.setAttribute('key', list[i]);
|
|
||||||
if (isTablet) {
|
|
||||||
icon.ontouchstart = Paint.setMode;
|
|
||||||
} else {
|
|
||||||
icon.onmousedown = Paint.setMode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.createSizeSelector = function (pal) {
|
|
||||||
var section = newHTML('div', 'section space', pal);
|
|
||||||
section.setAttribute('id', 'sizeSelector');
|
|
||||||
for (var i = 0; i < Paint.pensizes.length; i++) {
|
|
||||||
var ps = newHTML('div', 'pensizeholder', section);
|
|
||||||
ps.key = i;
|
|
||||||
ps.ontouchstart = function (e) {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
var n = Number(this.key);
|
|
||||||
Paint.strokewidth = Paint.pensizes[Number(this.key)];
|
|
||||||
Paint.selectPenSize(n);
|
|
||||||
};
|
|
||||||
var c = newHTML('div', 'line t' + i, ps);
|
|
||||||
Paint.drawPenSizeInColor(c);
|
|
||||||
}
|
|
||||||
Paint.strokewidth = Paint.pensizes[1];
|
|
||||||
Paint.selectPenSize(1);
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////////////
|
|
||||||
// Pen sizes
|
|
||||||
////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
Paint.drawPenSizeInColor = function (c) {
|
|
||||||
c.style.background = Paint.fillcolor;
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.updateStrokes = function () {
|
|
||||||
var div = gn('sizeSelector');
|
|
||||||
if (!div) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (var i = 0; i < div.childElementCount; i++) {
|
|
||||||
var elem = div.childNodes[i];
|
|
||||||
Paint.drawPenSizeInColor(elem.childNodes[0]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.selectPenSize = function (str) {
|
|
||||||
var p = gn('sizeSelector');
|
|
||||||
for (var i = 0; i < p.childElementCount; i++) {
|
|
||||||
var elem = p.childNodes[i];
|
|
||||||
if (elem.key == str) {
|
|
||||||
elem.setAttribute('class', 'pensizeholder on');
|
|
||||||
} else {
|
|
||||||
elem.setAttribute('class', 'pensizeholder off');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////
|
|
||||||
//Right Palette
|
|
||||||
/////////////////////////////////
|
|
||||||
|
|
||||||
Paint.rightPalette = function (div) {
|
|
||||||
var rightpal = newHTML('div', 'side', div);
|
|
||||||
Paint.addSidePalette(rightpal, 'selectortools', ['select', 'rotate']);
|
|
||||||
Paint.addSidePalette(rightpal, 'edittools', ['stamper', 'scissors']);
|
|
||||||
Paint.addSidePalette(rightpal, 'filltools',
|
|
||||||
(iOS.camera == '1' && Camera.available) ? ['camera', 'paintbucket'] : ['paintbucket']);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.addSidePalette = function (p, id, list) {
|
|
||||||
var pal = newHTML('div', 'paintpalette short', p);
|
|
||||||
pal.setAttribute('id', id);
|
|
||||||
for (var i = 0; i < list.length; i++) {
|
|
||||||
var but = newHTML('div', 'element off', pal);
|
|
||||||
var icon = newHTML('div', 'tool ' + list[i] + ' off', but);
|
|
||||||
icon.setAttribute('key', list[i]);
|
|
||||||
icon.ontouchstart = Paint.setMode;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.cameraToolsOn = function () {
|
|
||||||
gn('backdrop').setAttribute('class', 'modal-backdrop fade dark');
|
|
||||||
setProps(gn('backdrop').style, {
|
|
||||||
display: 'block'
|
|
||||||
});
|
|
||||||
var topbar = newHTML('div', 'phototopbar', gn('backdrop'));
|
|
||||||
topbar.setAttribute('id', 'photocontrols');
|
|
||||||
// var actions = newHTML("div",'actions', topbar);
|
|
||||||
// var buttons = newHTML('div', 'photobuttons', actions);
|
|
||||||
var fc = newHTML('div', 'flipcamera', topbar);
|
|
||||||
fc.setAttribute('id', 'cameraflip');
|
|
||||||
fc.setAttribute('key', 'cameraflip');
|
|
||||||
if (isAndroid && !AndroidInterface.scratchjr_has_multiple_cameras()) {
|
|
||||||
fc.style.display = 'none';
|
|
||||||
}
|
|
||||||
|
|
||||||
fc.ontouchstart = Paint.setMode;
|
|
||||||
var captureContainer = newHTML('div', 'snapshot-container', gn('backdrop'));
|
|
||||||
captureContainer.setAttribute('id', 'capture-container');
|
|
||||||
var capture = newHTML('div', 'snapshot', captureContainer);
|
|
||||||
capture.setAttribute('id', 'capture');
|
|
||||||
capture.setAttribute('key', 'camerasnap');
|
|
||||||
capture.ontouchstart = Paint.setMode;
|
|
||||||
var cc = newHTML('div', 'cameraclose', topbar);
|
|
||||||
cc.setAttribute('id', 'cameraclose');
|
|
||||||
cc.ontouchstart = Paint.closeCameraMode;
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.closeCameraMode = function () {
|
|
||||||
ScratchAudio.sndFX('exittap.wav');
|
|
||||||
Camera.close();
|
|
||||||
Paint.selectButton('select');
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.cameraToolsOff = function () {
|
|
||||||
gn('backdrop').setAttribute('class', 'modal-backdrop fade');
|
|
||||||
setProps(gn('backdrop').style, {
|
|
||||||
display: 'none'
|
|
||||||
});
|
|
||||||
if (gn('photocontrols')) {
|
|
||||||
gn('photocontrols').parentNode.removeChild(gn('photocontrols'));
|
|
||||||
}
|
|
||||||
if (gn('capture')) {
|
|
||||||
var captureContainer = gn('capture').parentNode;
|
|
||||||
var captureContainerParent = captureContainer.parentNode;
|
|
||||||
captureContainer.removeChild(gn('capture'));
|
|
||||||
captureContainerParent.removeChild(gn('capture-container'));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//////////////////////////////////
|
|
||||||
// canvas Area
|
|
||||||
//////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
Paint.setUpCanvasArea = function () {
|
|
||||||
var workspace = gn('workspacebkg');
|
|
||||||
var dx = Math.floor((workspace.offsetWidth - Paint.workspaceWidth) / 2);
|
|
||||||
var dy = Math.floor((workspace.offsetHeight - Paint.workspaceHeight) / 2);
|
|
||||||
var w = Paint.workspaceWidth;
|
|
||||||
var h = Paint.workspaceHeight;
|
|
||||||
|
|
||||||
var div = gn('maincanvas');
|
|
||||||
div.style.background = '#F5F2F7';
|
|
||||||
div.style.top = '0px';
|
|
||||||
div.style.left = '0px';
|
|
||||||
|
|
||||||
div.style.width = w + 'px';
|
|
||||||
div.style.height = h + 'px';
|
|
||||||
div.cx = div.offsetWidth / 2;
|
|
||||||
div.cy = div.offsetHeight / 2;
|
|
||||||
div.dx = dx;
|
|
||||||
div.dy = dy;
|
|
||||||
|
|
||||||
Paint.root.setAttributeNS(null, 'width', w);
|
|
||||||
Paint.root.setAttributeNS(null, 'height', h);
|
|
||||||
Paint.drawGrid(w, h);
|
|
||||||
PaintAction.clearEvents();
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////
|
|
||||||
//Color Palette
|
|
||||||
/////////////////////////////////
|
|
||||||
|
|
||||||
Paint.colorPalette = function (div) {
|
|
||||||
var swatchlist = Paint.initSwatchList();
|
|
||||||
var spalContainer = newHTML('div', 'swatchpalette-container', div);
|
|
||||||
var spal = newHTML('div', 'swatchpalette', spalContainer);
|
|
||||||
spal.setAttribute('id', 'swatches');
|
|
||||||
for (var i = 0; i < swatchlist.length; i++) {
|
|
||||||
var colour = newHTML('div', 'swatchbucket', spal);
|
|
||||||
// bucket
|
|
||||||
var sf = newHTML('div', 'swatchframe', colour);
|
|
||||||
var sc = newHTML('div', 'swatchcolor', sf);
|
|
||||||
sc.style.background = swatchlist[i];
|
|
||||||
//
|
|
||||||
sf = newHTML('div', 'splasharea off', colour);
|
|
||||||
Paint.setSplashColor(sf, Paint.splash, swatchlist[i]);
|
|
||||||
Paint.addImageUrl(sf, Paint.splashshade);
|
|
||||||
colour.ontouchstart = Paint.selectSwatch;
|
|
||||||
}
|
|
||||||
Paint.setSwatchColor(gn('swatches').childNodes[swatchlist.indexOf('#1C1C1C')]);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.setSplashColor = function (p, str, color) {
|
|
||||||
var dataurl = 'data:image/svg+xml;base64,' + btoa(str.replace(/#662D91/g, color));
|
|
||||||
Paint.addImageUrl(p, dataurl);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.addImageUrl = function (p, url) {
|
|
||||||
var img = document.createElement('img');
|
|
||||||
img.src = url;
|
|
||||||
img.style.position = 'absolute';
|
|
||||||
p.appendChild(img);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.selectSwatch = function (e) {
|
|
||||||
if (e.touches && (e.touches.length > 1)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
if (Camera.active) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var t;
|
|
||||||
if (window.event) {
|
|
||||||
t = window.event.srcElement;
|
|
||||||
} else {
|
|
||||||
t = e.target;
|
|
||||||
}
|
|
||||||
var b = 'swatchbucket' != t.className;
|
|
||||||
while (b) {
|
|
||||||
t = t.parentNode;
|
|
||||||
b = t && ('swatchbucket' != t.className);
|
|
||||||
}
|
|
||||||
if (!t) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ScratchAudio.sndFX('splash.wav');
|
|
||||||
Paint.setSwatchColor(t);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.setSwatchColor = function (t) {
|
|
||||||
var tools = ['select', 'wand', 'stamper', 'scissors', 'rotate'];
|
|
||||||
if (t && (tools.indexOf(Paint.mode) > -1)) {
|
|
||||||
Paint.selectButton('paintbucket');
|
|
||||||
}
|
|
||||||
var c = t.childNodes[0].childNodes[0].style.backgroundColor;
|
|
||||||
for (var i = 0; i < gn('swatches').childElementCount; i++) {
|
|
||||||
var mycolor = gn('swatches').childNodes[i].childNodes[0].childNodes[0].style.backgroundColor;
|
|
||||||
if (c == mycolor) {
|
|
||||||
gn('swatches').childNodes[i].childNodes[1].setAttribute('class', 'splasharea on');
|
|
||||||
} else {
|
|
||||||
gn('swatches').childNodes[i].childNodes[1].setAttribute('class', 'splasharea off');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Paint.fillcolor = c;
|
|
||||||
Path.quitEditMode();
|
|
||||||
Paint.updateStrokes();
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.initSwatchList = function () {
|
|
||||||
return [
|
|
||||||
// "#FF5500", // new orange
|
|
||||||
'#FFD2F2', '#FF99D6', '#FF4583', // red pinks
|
|
||||||
'#C30001', '#FF0023', '#FF8300', '#FFB200',
|
|
||||||
'#FFF42E',
|
|
||||||
'#FFF9C2', // pale yellow
|
|
||||||
'#E2FFBD', // pale green
|
|
||||||
'#CFF500', // lime green
|
|
||||||
'#50D823', // problematic
|
|
||||||
// "#2BFC49", // less problematic
|
|
||||||
'#29C130',
|
|
||||||
// "#56C43B", // ERROR?
|
|
||||||
'#2BBF8A', // new green
|
|
||||||
'#027607', '#114D24', //greens
|
|
||||||
'#FFFFFF', '#CCDDE7', '#61787C', '#1C1C1C', // grays
|
|
||||||
'#D830A3', // sarah's pink shoes border
|
|
||||||
'#FF64E9', // purple pinks
|
|
||||||
'#D999FF', ' #A159D3', // vilote
|
|
||||||
'#722696', // sarah's violet
|
|
||||||
'#141463', '#003399', '#1D40ED',
|
|
||||||
'#0079D3', '#009EFF', '#76C8FF',
|
|
||||||
'#ACE0FD', '#11B7BC', '#21F9F3', '#C3FCFC', '#54311E',
|
|
||||||
'#8E572A', '#E4B69D', '#FFCDA4', '#FFEDD7' // skin colors
|
|
||||||
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////
|
|
||||||
// Setup SVG Editor
|
|
||||||
////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
Paint.createSVGeditor = function (container) {
|
|
||||||
var div = newHTML('div', 'maincanvas', container);
|
|
||||||
div.setAttribute('id', 'maincanvas');
|
|
||||||
div.style.background = '#F5F2F7';
|
|
||||||
div.style.top = '0px';
|
|
||||||
div.style.left = '0px';
|
|
||||||
window.onmousemove = undefined;
|
|
||||||
window.onmouseup = undefined;
|
|
||||||
Paint.root = SVGTools.create(div);
|
|
||||||
Paint.root.setAttribute('class', 'active3d');
|
|
||||||
xform = Transform.getTranslateTransform();
|
|
||||||
selxform = Transform.getTranslateTransform();
|
|
||||||
var layer = SVGTools.createGroup(Paint.root, 'layer1');
|
|
||||||
layer.setAttribute('style', 'pointer-events:visiblePainted');
|
|
||||||
SVGTools.createGroup(Paint.root, 'draglayer');
|
|
||||||
SVGTools.createGroup(Paint.root, 'paintgrid');
|
|
||||||
gn('paintgrid').setAttribute('opacity', 0.5);
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.clearWorkspace = function () {
|
|
||||||
var fcn = function (div) {
|
|
||||||
while (div.childElementCount > 0) {
|
|
||||||
div.removeChild(div.childNodes[0]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
fcn(gn('layer1'));
|
|
||||||
fcn(gn('paintgrid'));
|
|
||||||
fcn(gn('draglayer'));
|
|
||||||
Path.quitEditMode();
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.drawGrid = function (w, h) {
|
|
||||||
var attr, path;
|
|
||||||
if (!Paint.isBkg) {
|
|
||||||
attr = {
|
|
||||||
'd': Paint.getGridPath(w, h, 12),
|
|
||||||
'id': getIdFor('gridpath'),
|
|
||||||
'opacity': 1,
|
|
||||||
'stroke': '#dcddde',
|
|
||||||
'fill': 'none',
|
|
||||||
'stroke-width': 0.5
|
|
||||||
};
|
|
||||||
path = SVGTools.addChild(gn('paintgrid'), 'path', attr);
|
|
||||||
path.setAttribute('style', 'pointer-events:none;');
|
|
||||||
}
|
|
||||||
attr = {
|
|
||||||
'd': Paint.getGridPath(w, h, Paint.isBkg ? 24 : 48),
|
|
||||||
'id': getIdFor('gridpath'),
|
|
||||||
'opacity': 1,
|
|
||||||
'stroke': '#c1c2c3',
|
|
||||||
'fill': 'none',
|
|
||||||
'stroke-width': 0.5
|
|
||||||
};
|
|
||||||
path = SVGTools.addChild(gn('paintgrid'), 'path', attr);
|
|
||||||
path.setAttribute('style', 'pointer-events:none;');
|
|
||||||
};
|
|
||||||
|
|
||||||
Paint.getGridPath = function (w, h, gridsize) {
|
|
||||||
var str = '';
|
|
||||||
var dx = gridsize;
|
|
||||||
// vertical
|
|
||||||
var cmd;
|
|
||||||
for (var i = 0; i < w / gridsize; i++) {
|
|
||||||
cmd = 'M' + dx + ',' + 0 + 'L' + dx + ',' + h;
|
|
||||||
str += cmd;
|
|
||||||
dx += gridsize;
|
|
||||||
}
|
|
||||||
var dy = gridsize;
|
|
||||||
// horizontal
|
|
||||||
for (i = 0; i < h / gridsize; i++) {
|
|
||||||
cmd = 'M' + 0 + ',' + dy + 'L' + w + ',' + dy;
|
|
||||||
str += cmd;
|
|
||||||
dy += gridsize;
|
|
||||||
}
|
|
||||||
return str;
|
|
||||||
};
|
|
Loading…
Reference in a new issue