kopia lustrzana https://github.com/backface/turtlestitch
playing around with various methods to write SVG to canvas
rodzic
ee1f01d48d
commit
d301b08f71
14
index.html
14
index.html
|
@ -55,18 +55,24 @@
|
|||
|
||||
<canvas width="480" height="360" id="svg" style="background:white;
|
||||
position:absolute;right:0;bottom:0;width:480px;height:360px;
|
||||
border:1px solid #c0c0c0"></canvas>
|
||||
border:1px solid #c0c0c0;
|
||||
display:none">
|
||||
</canvas>
|
||||
|
||||
<div id="svg2" style="background:white;font-size:60%;position:absolute;
|
||||
position:absolute;right:0;bottom:0;width:480px;height:360px;
|
||||
border:1px solid #c0c0c0" ></div>
|
||||
border:1px solid #c0c0c0;
|
||||
display:none" >
|
||||
</div>
|
||||
|
||||
<div name="debug" id="debug" style="background:white;font-size:60%;position:absolute;
|
||||
width:33%;height:20%;left:34%;bottom:0;overflow:auto;border:1px solid #c0c0c0;
|
||||
"></div>
|
||||
">
|
||||
</div>
|
||||
|
||||
<textarea id="code" width="480" height="360" style="background:white;font-size:60%;position:absolute;
|
||||
width:33%;height:20%;left:0;bottom:0;overflow:auto;border:1px solid #c0c0c0"></textarea>
|
||||
width:33%;height:20%;left:0;bottom:0;overflow:auto;border:1px solid #c0c0c0">
|
||||
</textarea>
|
||||
|
||||
|
||||
</body>
|
||||
|
|
|
@ -74,6 +74,21 @@ IDE_Morph.prototype.setStageExtent = function (aPoint) {
|
|||
turtleShepherd.setStageDimensions(aPoint.x, aPoint.y);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.origNewProject = IDE_Morph.prototype.newProject;
|
||||
IDE_Morph.prototype.newProject = function () {
|
||||
this.origNewProject();
|
||||
turtleShepherd.clear();
|
||||
this.stage.reRender();
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.origRawOpenProjectString = IDE_Morph.prototype.rawOpenProjectString;
|
||||
IDE_Morph.prototype.rawOpenProjectString = function (str) {
|
||||
this.origRawOpenProjectString(str);
|
||||
turtleShepherd.clear();
|
||||
this.stage.children[0].hide();
|
||||
this.stage.reRender();
|
||||
};
|
||||
|
||||
// Create contol bar - (and add custom buttons)
|
||||
IDE_Morph.prototype.createControlBar = function () {
|
||||
// assumes the logo has already been created
|
||||
|
@ -1553,235 +1568,7 @@ IDE_Morph.prototype.createSpriteEditor = function(){
|
|||
this.originalCreateSpriteEditor();
|
||||
this.spriteEditor.color = new Color(240, 240, 240);
|
||||
this.currentSprite.scripts.color = new Color(240, 240, 240);
|
||||
}
|
||||
|
||||
|
||||
/* Sprite BAR
|
||||
|
||||
IDE_Morph.prototype.createSpriteBar = function () {
|
||||
// assumes that the categories pane has already been created
|
||||
var rotationStyleButtons = [],
|
||||
thumbSize = new Point(45, 45),
|
||||
nameField,
|
||||
padlock,
|
||||
thumbnail,
|
||||
tabCorner = 15,
|
||||
tabColors = this.tabColors,
|
||||
tabBar = new AlignmentMorph('row', -tabCorner * 2),
|
||||
tab,
|
||||
symbols = ['\u2192', '\u21BB', '\u2194'],
|
||||
labels = ['don\'t rotate', 'can rotate', 'only face left/right'],
|
||||
myself = this;
|
||||
|
||||
if (this.spriteBar) {
|
||||
this.spriteBar.destroy();
|
||||
}
|
||||
|
||||
this.spriteBar = new Morph();
|
||||
this.spriteBar.color = this.frameColor;
|
||||
//this.add(this.spriteBar);
|
||||
|
||||
function addRotationStyleButton(rotationStyle) {
|
||||
var colors = myself.rotationStyleColors,
|
||||
button;
|
||||
|
||||
button = new ToggleButtonMorph(
|
||||
colors,
|
||||
myself, // the IDE is the target
|
||||
function () {
|
||||
if (myself.currentSprite instanceof SpriteMorph) {
|
||||
myself.currentSprite.rotationStyle = rotationStyle;
|
||||
myself.currentSprite.changed();
|
||||
myself.currentSprite.drawNew();
|
||||
myself.currentSprite.changed();
|
||||
}
|
||||
rotationStyleButtons.forEach(function (each) {
|
||||
each.refresh();
|
||||
});
|
||||
},
|
||||
symbols[rotationStyle], // label
|
||||
function () { // query
|
||||
return myself.currentSprite instanceof SpriteMorph
|
||||
&& myself.currentSprite.rotationStyle === rotationStyle;
|
||||
},
|
||||
null, // environment
|
||||
localize(labels[rotationStyle])
|
||||
);
|
||||
|
||||
button.corner = 8;
|
||||
button.labelMinExtent = new Point(11, 11);
|
||||
button.padding = 0;
|
||||
button.labelShadowOffset = new Point(-1, -1);
|
||||
button.labelShadowColor = colors[1];
|
||||
button.labelColor = myself.buttonLabelColor;
|
||||
button.fixLayout();
|
||||
button.refresh();
|
||||
rotationStyleButtons.push(button);
|
||||
button.setPosition(myself.spriteBar.position().add(2));
|
||||
button.setTop(button.top()
|
||||
+ ((rotationStyleButtons.length - 1) * (button.height() + 2))
|
||||
);
|
||||
myself.spriteBar.add(button);
|
||||
if (myself.currentSprite instanceof StageMorph) {
|
||||
button.hide();
|
||||
}
|
||||
return button;
|
||||
}
|
||||
|
||||
addRotationStyleButton(1);
|
||||
addRotationStyleButton(2);
|
||||
addRotationStyleButton(0);
|
||||
this.rotationStyleButtons = rotationStyleButtons;
|
||||
|
||||
thumbnail = new Morph();
|
||||
thumbnail.setExtent(thumbSize);
|
||||
thumbnail.image = this.currentSprite.thumbnail(thumbSize);
|
||||
thumbnail.setPosition(
|
||||
rotationStyleButtons[0].topRight().add(new Point(5, 3))
|
||||
);
|
||||
this.spriteBar.add(thumbnail);
|
||||
|
||||
thumbnail.fps = 3;
|
||||
|
||||
thumbnail.step = function () {
|
||||
if (thumbnail.version !== myself.currentSprite.version) {
|
||||
thumbnail.image = myself.currentSprite.thumbnail(thumbSize);
|
||||
thumbnail.changed();
|
||||
thumbnail.version = myself.currentSprite.version;
|
||||
}
|
||||
};
|
||||
|
||||
nameField = new InputFieldMorph(this.currentSprite.name);
|
||||
nameField.setWidth(100); // fixed dimensions
|
||||
nameField.contrast = 90;
|
||||
nameField.setPosition(thumbnail.topRight().add(new Point(10, 3)));
|
||||
this.spriteBar.add(nameField);
|
||||
nameField.drawNew();
|
||||
nameField.accept = function () {
|
||||
var newName = nameField.getValue();
|
||||
myself.currentSprite.setName(
|
||||
myself.newSpriteName(newName, myself.currentSprite)
|
||||
);
|
||||
nameField.setContents(myself.currentSprite.name);
|
||||
};
|
||||
this.spriteBar.reactToEdit = nameField.accept;
|
||||
|
||||
// padlock
|
||||
padlock = new ToggleMorph(
|
||||
'checkbox',
|
||||
null,
|
||||
function () {
|
||||
myself.currentSprite.isDraggable =
|
||||
!myself.currentSprite.isDraggable;
|
||||
},
|
||||
localize('draggable'),
|
||||
function () {
|
||||
return myself.currentSprite.isDraggable;
|
||||
}
|
||||
);
|
||||
padlock.label.isBold = false;
|
||||
padlock.label.setColor(this.buttonLabelColor);
|
||||
padlock.color = tabColors[2];
|
||||
padlock.highlightColor = tabColors[0];
|
||||
padlock.pressColor = tabColors[1];
|
||||
|
||||
padlock.tick.shadowOffset = MorphicPreferences.isFlat ?
|
||||
new Point() : new Point(-1, -1);
|
||||
padlock.tick.shadowColor = new Color(); // black
|
||||
padlock.tick.color = this.buttonLabelColor;
|
||||
padlock.tick.isBold = false;
|
||||
padlock.tick.drawNew();
|
||||
|
||||
padlock.setPosition(nameField.bottomLeft().add(2));
|
||||
padlock.drawNew();
|
||||
this.spriteBar.add(padlock);
|
||||
if (this.currentSprite instanceof StageMorph) {
|
||||
padlock.hide();
|
||||
}
|
||||
|
||||
// tab bar
|
||||
tabBar.tabTo = function (tabString) {
|
||||
var active;
|
||||
myself.currentTab = tabString;
|
||||
this.children.forEach(function (each) {
|
||||
each.refresh();
|
||||
if (each.state) {active = each; }
|
||||
});
|
||||
active.refresh(); // needed when programmatically tabbing
|
||||
myself.createSpriteEditor();
|
||||
myself.fixLayout('tabEditor');
|
||||
};
|
||||
|
||||
tab = new TabMorph(
|
||||
tabColors,
|
||||
null, // target
|
||||
function () {tabBar.tabTo('scripts'); },
|
||||
localize('Scripts'), // label
|
||||
function () { // query
|
||||
return myself.currentTab === 'scripts';
|
||||
}
|
||||
);
|
||||
tab.padding = 3;
|
||||
tab.corner = tabCorner;
|
||||
tab.edge = 1;
|
||||
tab.labelShadowOffset = new Point(-1, -1);
|
||||
tab.labelShadowColor = tabColors[1];
|
||||
tab.labelColor = this.buttonLabelColor;
|
||||
tab.drawNew();
|
||||
tab.fixLayout();
|
||||
tabBar.add(tab);
|
||||
|
||||
tab = new TabMorph(
|
||||
tabColors,
|
||||
null, // target
|
||||
function () {tabBar.tabTo('costumes'); },
|
||||
localize('Costumes'), // label
|
||||
function () { // query
|
||||
return myself.currentTab === 'costumes';
|
||||
}
|
||||
);
|
||||
tab.padding = 3;
|
||||
tab.corner = tabCorner;
|
||||
tab.edge = 1;
|
||||
tab.labelShadowOffset = new Point(-1, -1);
|
||||
tab.labelShadowColor = tabColors[1];
|
||||
tab.labelColor = this.buttonLabelColor;
|
||||
tab.drawNew();
|
||||
tab.fixLayout();
|
||||
tabBar.add(tab);
|
||||
|
||||
tab = new TabMorph(
|
||||
tabColors,
|
||||
null, // target
|
||||
function () {tabBar.tabTo('sounds'); },
|
||||
localize('Sounds'), // label
|
||||
function () { // query
|
||||
return myself.currentTab === 'sounds';
|
||||
}
|
||||
);
|
||||
tab.padding = 3;
|
||||
tab.corner = tabCorner;
|
||||
tab.edge = 1;
|
||||
tab.labelShadowOffset = new Point(-1, -1);
|
||||
tab.labelShadowColor = tabColors[1];
|
||||
tab.labelColor = this.buttonLabelColor;
|
||||
tab.drawNew();
|
||||
tab.fixLayout();
|
||||
tabBar.add(tab);
|
||||
|
||||
tabBar.fixLayout();
|
||||
tabBar.children.forEach(function (each) {
|
||||
each.refresh();
|
||||
});
|
||||
this.spriteBar.tabBar = tabBar;
|
||||
this.spriteBar.add(this.spriteBar.tabBar);
|
||||
|
||||
this.spriteBar.fixLayout = function () {
|
||||
this.tabBar.setLeft(this.left());
|
||||
this.tabBar.setBottom(this.bottom());
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
/* CORRAL BAR */
|
||||
|
||||
|
@ -2048,85 +1835,3 @@ ProjectDialogMorph.prototype.buildContents = function () {
|
|||
|
||||
};
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
IDE_Morph.prototype.droppedImageStage = function (aCanvas, name) {
|
||||
var costume = new Costume(
|
||||
aCanvas,
|
||||
this.currentSprite.newCostumeName(
|
||||
name ? name.split('.')[0] : '' // up to period
|
||||
)
|
||||
);
|
||||
|
||||
if (costume.isTainted()) {
|
||||
this.inform(
|
||||
'Unable to import this image',
|
||||
'The picture you wish to import has been\n' +
|
||||
'tainted by a restrictive cross-origin policy\n' +
|
||||
'making it unusable for costumes in Snap!. \n\n' +
|
||||
'Try downloading this picture first to your\n' +
|
||||
'computer, and import it from there.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.stage.addCostume(costume);
|
||||
this.stage.wearCostume(costume);
|
||||
//this.spriteBar.tabBar.tabTo('costumes');
|
||||
this.hasChangedMedia = true;
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
|
||||
IDE_Morph.prototype.getCostumesList = function (dirname) {
|
||||
var dir,
|
||||
costumes = [];
|
||||
|
||||
dir = this.getURL(dirname);
|
||||
dir.split('\n').forEach(
|
||||
function (line) {
|
||||
var startIdx = line.search(new RegExp('href="[^./?].*"')),
|
||||
endIdx,
|
||||
name;
|
||||
|
||||
if (startIdx > 0) {
|
||||
name = line.substring(startIdx + 6);
|
||||
endIdx = name.search(new RegExp('"'));
|
||||
name = name.substring(0, endIdx);
|
||||
costumes.push(name);
|
||||
}
|
||||
}
|
||||
);
|
||||
costumes.sort(function (x, y) {
|
||||
return x < y ? -1 : 1;
|
||||
});
|
||||
return costumes;
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.droppedImageStage = function (aCanvas, name) {
|
||||
var costume = new Costume(
|
||||
aCanvas,
|
||||
this.currentSprite.newCostumeName(
|
||||
name ? name.split('.')[0] : '' // up to period
|
||||
)
|
||||
);
|
||||
|
||||
if (costume.isTainted()) {
|
||||
this.inform(
|
||||
'Unable to import this image',
|
||||
'The picture you wish to import has been\n' +
|
||||
'tainted by a restrictive cross-origin policy\n' +
|
||||
'making it unusable for costumes in Snap!. \n\n' +
|
||||
'Try downloading this picture first to your\n' +
|
||||
'computer, and import it from there.'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
this.stage.addCostume(costume);
|
||||
this.stage.wearCostume(costume);
|
||||
//this.spriteBar.tabBar.tabTo('costumes');
|
||||
this.hasChangedMedia = true;
|
||||
};
|
||||
|
|
|
@ -16,7 +16,7 @@ SpriteMorph.prototype.forward = function (steps) {
|
|||
if (!turtleShepherd.hasSteps())
|
||||
turtleShepherd.initPosition(oldx, oldy);
|
||||
turtleShepherd.addMoveTo(this.xPosition() , this.yPosition() , this.isDown);
|
||||
this.reRender();
|
||||
this.changed();
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.origGotoXY = SpriteMorph.prototype.gotoXY;
|
||||
|
@ -31,7 +31,7 @@ SpriteMorph.prototype.gotoXY = function (x, y, justMe) {
|
|||
if (!turtleShepherd.hasSteps())
|
||||
turtleShepherd.initPosition(oldx, oldy);
|
||||
turtleShepherd.addMoveTo(this.xPosition() , this.yPosition() , this.isDown);
|
||||
this.reRender();
|
||||
this.changed();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -40,7 +40,7 @@ SpriteMorph.prototype.clear = function () {
|
|||
this.origClear();
|
||||
turtleShepherd.clear();
|
||||
//this.changed();
|
||||
this.reRender();
|
||||
this.changed();
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.reRender = function () {
|
||||
|
@ -61,8 +61,6 @@ StageMorph.prototype.mouseScroll = function (y, x) {
|
|||
} else if (y < 0) {
|
||||
turtleShepherd.zoomIn();
|
||||
}
|
||||
|
||||
this.reRender();
|
||||
this.changed();
|
||||
};
|
||||
|
||||
|
@ -77,6 +75,7 @@ StageMorph.prototype.originalSetScale = StageMorph.prototype.setScale;
|
|||
StageMorph.prototype.setScale = function (number) {
|
||||
this.scaleChanged = true;
|
||||
this.originalSetScale(number);
|
||||
|
||||
if (DEBUG) turtleShepherd.debug_msg("scale stage to "+ number );
|
||||
if (DEBUG) turtleShepherd.debug_msg("stage dimensions " +
|
||||
this.extent().x + " " +
|
||||
|
@ -86,17 +85,78 @@ StageMorph.prototype.setScale = function (number) {
|
|||
this.position().y);
|
||||
turtleShepherd.setStageDimensions(this.extent().x, this.extent().y);
|
||||
turtleShepherd.setStagePosition(this.position().x, this.position().y);
|
||||
//this.resizePenTrails();
|
||||
this.resizePenTrails();
|
||||
this.changed();
|
||||
this.reRender();
|
||||
};
|
||||
|
||||
StageMorph.prototype.clearPenTrails = function () {
|
||||
this.trailsCanvas = newCanvas(new Point(this.extent().x,this.extent().y));
|
||||
this.changed();
|
||||
};
|
||||
|
||||
StageMorph.prototype.resizePenTrails = function () {
|
||||
this.trailsCanvas = newCanvas(new Point(this.extent().x,this.extent().y));
|
||||
this.changed();
|
||||
};
|
||||
|
||||
StageMorph.prototype.originalDrawOn = StageMorph.prototype.drawOn;
|
||||
StageMorph.prototype.drawOn = function (aCanvas, aRect) {
|
||||
this.reRender();
|
||||
this.originalDrawOn(aCanvas, aRect);
|
||||
};
|
||||
|
||||
|
||||
|
||||
StageMorph.prototype.originalDrawOn = StageMorph.prototype.drawOn;
|
||||
StageMorph.prototype.drawOn = function (aCanvas, aRect) {
|
||||
this.reRender();
|
||||
// make sure to draw the pen trails canvas as well
|
||||
var rectangle, area, delta, src, context, w, h, sl, st, ws, hs;
|
||||
if (!this.isVisible) {
|
||||
return null;
|
||||
}
|
||||
rectangle = aRect || this.bounds;
|
||||
area = rectangle.intersect(this.bounds);
|
||||
if (area.extent().gt(new Point(0, 0))) {
|
||||
delta = this.position().neg();
|
||||
src = area.copy().translateBy(delta);
|
||||
context = aCanvas.getContext('2d');
|
||||
context.globalAlpha = this.alpha;
|
||||
|
||||
sl = src.left();
|
||||
st = src.top();
|
||||
w = Math.min(src.width(), this.image.width - sl);
|
||||
h = Math.min(src.height(), this.image.height - st);
|
||||
|
||||
if (w < 1 || h < 1) {
|
||||
return null;
|
||||
}
|
||||
// we only draw pen trails!
|
||||
context.save();
|
||||
context.clearRect(
|
||||
area.left(),
|
||||
area.top() ,
|
||||
w,
|
||||
h);
|
||||
try {
|
||||
context.drawImage(
|
||||
this.penTrails(),
|
||||
sl,
|
||||
st,
|
||||
w,
|
||||
h,
|
||||
area.left(),
|
||||
area.top(),
|
||||
w,
|
||||
h
|
||||
);
|
||||
} catch (err) { // sometimes triggered only by Firefox
|
||||
console.log(err);
|
||||
}
|
||||
context.restore();
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
StageMorph.prototype.drawOn = function (aCanvas, aRect) {
|
||||
|
|
|
@ -55,7 +55,7 @@ TurtleShepherd.prototype.addMoveTo= function(x,y,penState) {
|
|||
|
||||
TurtleShepherd.prototype.initPosition = function(x,y) {
|
||||
this.initX = x;
|
||||
this.initY = y;
|
||||
this.initY = -y;
|
||||
if (DEBUG) this.debug_msg("init " + x + " " + y );
|
||||
};
|
||||
|
||||
|
@ -118,11 +118,11 @@ TurtleShepherd.prototype.toSVG = function() {
|
|||
|
||||
//var svgStr = "<?xml version=\"1.0\" standalone=\"no\"?>\n";
|
||||
//svgStr += "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \n\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n";
|
||||
svgStr = '<svg width="' +this.w + '" height="' +this.h + '"' +
|
||||
' viewBox="' + (-1 * this.w / 2 * this.scale) + ' ' +
|
||||
(-1 * this.h / 2 * this.scale) + ' ' +
|
||||
(this.w* this.scale) + ' ' +
|
||||
(this.h* this.scale)+ '"\n';
|
||||
svgStr = '<svg width="' + (this.w) + '" height="' +this.h + '"' +
|
||||
' viewBox="' + (-1 * (this.w / 2) * this.scale) + ' ' +
|
||||
(-1 * (this.h / 2) * this.scale) + ' ' +
|
||||
(this.w * this.scale) + ' ' +
|
||||
(this.h * this.scale) + '"\n';
|
||||
svgStr += ' xmlns="http://www.w3.org/2000/svg" version="1.1">\n';
|
||||
svgStr += '<title>Embroidery export</title>\n';
|
||||
|
||||
|
@ -196,20 +196,36 @@ TurtleShepherd.prototype.toSVG = function() {
|
|||
};
|
||||
|
||||
TurtleShepherd.prototype.reRender = function(cnv) {
|
||||
//load a svg snippet in the canvas with id = 'svg'
|
||||
sourceSVG = turtleShepherd.toSVG();
|
||||
//load a svg snippet in the canvas with id = 'svg'
|
||||
//canvas = document.getElementById('svg');
|
||||
document.getElementById("code").innerHTML = turtleShepherd.toSVG();
|
||||
document.getElementById("svg2").innerHTML = turtleShepherd.toSVG();
|
||||
|
||||
document.getElementById("code").innerHTML = sourceSVG;
|
||||
//document.getElementById("svg2").innerHTML = sourceSVG;
|
||||
//canvg(document.getElementById('svg'), turtleShepherd.toSVG());
|
||||
|
||||
canvg(cnv, turtleShepherd.toSVG());
|
||||
// draw via canvg - works but very slow!
|
||||
//canvg(cnv, turtleShepherd.toSVG());
|
||||
|
||||
if (cnv) {
|
||||
var ctx = cnv.getContext('2d');
|
||||
ctx.clearRect(0, 0, cnv.width, cnv.height);
|
||||
ctx.drawSvg(turtleShepherd.toSVG(), 0, 0, cnv.width, cnv.height);
|
||||
}
|
||||
|
||||
/*
|
||||
// another method to draw svg on canvas
|
||||
var svgString = (new XMLSerializer()).serializeToString(document.querySelector('svg'));
|
||||
var img = new Image();
|
||||
ctx = cnv.getContext('2d');
|
||||
img.src = "data:image/svg+xml;base64," + btoa(svgString);
|
||||
img.onload = function() {
|
||||
// after this, Canvas’ origin-clean is DIRTY
|
||||
ctx.clearRect(0, 0, cnv.width, cnv.height);
|
||||
ctx.drawImage(img, 0, 0, cnv.width, cnv.height);
|
||||
};
|
||||
*/
|
||||
|
||||
//var cnv = caller.parent.penTrails();
|
||||
//alert(cnv);
|
||||
//if (cnv) {
|
||||
// var ctx = cnv.getContext('2d');
|
||||
// ctx.drawSvg(turtleShepherd.toSVG(), 0, 0, cnv.width, cnv.height);
|
||||
//}
|
||||
};
|
||||
|
||||
TurtleShepherd.prototype.debug_msg = function (st, clear) {
|
||||
|
|
Ładowanie…
Reference in New Issue