playing around with various methods to write SVG to canvas

dev-2.0-svg
Michael Aschauer 2017-01-20 16:21:36 +01:00
rodzic ee1f01d48d
commit d301b08f71
4 zmienionych plików z 123 dodań i 336 usunięć

Wyświetl plik

@ -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>

Wyświetl plik

@ -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;
};

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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) {