Uplifted to latest CanVG for <image> support, made sure (most) images will appear in exported canvas
git-svn-id: http://svg-edit.googlecode.com/svn/trunk@1667 eee81c28-f429-11dd-99c0-75d572ba1dddmaster
parent
414832eb60
commit
23851a90a8
|
@ -11,11 +11,27 @@ if(!window.console) {
|
||||||
window.console.log = function(str) {};
|
window.console.log = function(str) {};
|
||||||
window.console.dir = function(str) {};
|
window.console.dir = function(str) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// <3 IE
|
||||||
|
if(!Array.indexOf){
|
||||||
|
Array.prototype.indexOf = function(obj){
|
||||||
|
for(var i=0; i<this.length; i++){
|
||||||
|
if(this[i]==obj){
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(function(){
|
(function(){
|
||||||
// canvg(target, s)
|
// canvg(target, s)
|
||||||
// target: canvas element or the id of a canvas element
|
// target: canvas element or the id of a canvas element
|
||||||
// s: svg string or url to svg file
|
// s: svg string or url to svg file
|
||||||
this.canvg = function (target, s) {
|
// opts: optional hash of options
|
||||||
|
// ignoreMouse: true => ignore mouse events
|
||||||
|
// ignoreAnimation: true => ignore animations
|
||||||
|
this.canvg = function (target, s, opts) {
|
||||||
if (typeof target == 'string') {
|
if (typeof target == 'string') {
|
||||||
target = document.getElementById(target);
|
target = document.getElementById(target);
|
||||||
}
|
}
|
||||||
|
@ -30,6 +46,7 @@ if(!window.console) {
|
||||||
svg = target.svg;
|
svg = target.svg;
|
||||||
svg.stop();
|
svg.stop();
|
||||||
}
|
}
|
||||||
|
svg.opts = opts;
|
||||||
|
|
||||||
var ctx = target.getContext('2d');
|
var ctx = target.getContext('2d');
|
||||||
if (s.substr(0,1) == '<') {
|
if (s.substr(0,1) == '<') {
|
||||||
|
@ -43,7 +60,7 @@ if(!window.console) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function build() {
|
function build() {
|
||||||
var svg = {};
|
var svg = { };
|
||||||
|
|
||||||
svg.FRAMERATE = 30;
|
svg.FRAMERATE = 30;
|
||||||
|
|
||||||
|
@ -290,6 +307,13 @@ if(!window.console) {
|
||||||
this.angleTo = function(p) {
|
this.angleTo = function(p) {
|
||||||
return Math.atan2(p.y - this.y, p.x - this.x);
|
return Math.atan2(p.y - this.y, p.x - this.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.applyTransform = function(v) {
|
||||||
|
var xp = this.x * v[0] + this.y * v[2] + v[4];
|
||||||
|
var yp = this.x * v[1] + this.y * v[3] + v[5];
|
||||||
|
this.x = xp;
|
||||||
|
this.y = yp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
svg.CreatePoint = function(s) {
|
svg.CreatePoint = function(s) {
|
||||||
var a = svg.ToNumberArray(s);
|
var a = svg.ToNumberArray(s);
|
||||||
|
@ -389,6 +413,10 @@ if(!window.console) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.isPointInBox = function(x, y) {
|
||||||
|
return (this.x1 <= x && x <= this.x2 && this.y1 <= y && y <= this.y2);
|
||||||
|
}
|
||||||
|
|
||||||
this.addPoint(x1, y1);
|
this.addPoint(x1, y1);
|
||||||
this.addPoint(x2, y2);
|
this.addPoint(x2, y2);
|
||||||
}
|
}
|
||||||
|
@ -404,6 +432,9 @@ if(!window.console) {
|
||||||
this.apply = function(ctx) {
|
this.apply = function(ctx) {
|
||||||
ctx.translate(this.p.x || 0.0, this.p.y || 0.0);
|
ctx.translate(this.p.x || 0.0, this.p.y || 0.0);
|
||||||
}
|
}
|
||||||
|
this.applyToPoint = function(p) {
|
||||||
|
p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rotate
|
// rotate
|
||||||
|
@ -417,6 +448,12 @@ if(!window.console) {
|
||||||
ctx.rotate(this.angle.Angle.toRadians());
|
ctx.rotate(this.angle.Angle.toRadians());
|
||||||
ctx.translate(-this.cx, -this.cy);
|
ctx.translate(-this.cx, -this.cy);
|
||||||
}
|
}
|
||||||
|
this.applyToPoint = function(p) {
|
||||||
|
var a = this.angle.Angle.toRadians();
|
||||||
|
p.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]);
|
||||||
|
p.applyTransform([Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]);
|
||||||
|
p.applyTransform([1, 0, 0, 1, -this.p.x || 0.0, -this.p.y || 0.0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Type.scale = function(s) {
|
this.Type.scale = function(s) {
|
||||||
|
@ -424,6 +461,9 @@ if(!window.console) {
|
||||||
this.apply = function(ctx) {
|
this.apply = function(ctx) {
|
||||||
ctx.scale(this.p.x || 1.0, this.p.y || this.p.x || 1.0);
|
ctx.scale(this.p.x || 1.0, this.p.y || this.p.x || 1.0);
|
||||||
}
|
}
|
||||||
|
this.applyToPoint = function(p) {
|
||||||
|
p.applyTransform([this.p.x || 0.0, 0, 0, this.p.y || 0.0, 0, 0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Type.matrix = function(s) {
|
this.Type.matrix = function(s) {
|
||||||
|
@ -431,6 +471,9 @@ if(!window.console) {
|
||||||
this.apply = function(ctx) {
|
this.apply = function(ctx) {
|
||||||
ctx.transform(this.m[0], this.m[1], this.m[2], this.m[3], this.m[4], this.m[5]);
|
ctx.transform(this.m[0], this.m[1], this.m[2], this.m[3], this.m[4], this.m[5]);
|
||||||
}
|
}
|
||||||
|
this.applyToPoint = function(p) {
|
||||||
|
p.applyTransform(this.m);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.Type.SkewBase = function(s) {
|
this.Type.SkewBase = function(s) {
|
||||||
|
@ -455,12 +498,19 @@ if(!window.console) {
|
||||||
this.Type.skewY.prototype = new this.Type.SkewBase;
|
this.Type.skewY.prototype = new this.Type.SkewBase;
|
||||||
|
|
||||||
this.transforms = [];
|
this.transforms = [];
|
||||||
|
|
||||||
this.apply = function(ctx) {
|
this.apply = function(ctx) {
|
||||||
for (var i=0; i<this.transforms.length; i++) {
|
for (var i=0; i<this.transforms.length; i++) {
|
||||||
this.transforms[i].apply(ctx);
|
this.transforms[i].apply(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.applyToPoint = function(p) {
|
||||||
|
for (var i=0; i<this.transforms.length; i++) {
|
||||||
|
this.transforms[i].applyToPoint(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var data = v.split(/\s(?=[a-z])/);
|
var data = v.split(/\s(?=[a-z])/);
|
||||||
for (var i=0; i<data.length; i++) {
|
for (var i=0; i<data.length; i++) {
|
||||||
var type = data[i].split('(')[0];
|
var type = data[i].split('(')[0];
|
||||||
|
@ -470,6 +520,43 @@ if(!window.console) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// aspect ratio
|
||||||
|
svg.AspectRatio = function(ctx, aspectRatio, width, desiredWidth, height, desiredHeight, minX, minY, refX, refY) {
|
||||||
|
// aspect ratio - http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute
|
||||||
|
aspectRatio = svg.compressSpaces(aspectRatio);
|
||||||
|
aspectRatio = aspectRatio.replace(/^defer\s/,''); // ignore defer
|
||||||
|
var align = aspectRatio.split(' ')[0] || 'xMidYMid';
|
||||||
|
var meetOrSlice = aspectRatio.split(' ')[1] || 'meet';
|
||||||
|
|
||||||
|
// calculate scale
|
||||||
|
var scaleX = width / desiredWidth;
|
||||||
|
var scaleY = height / desiredHeight;
|
||||||
|
var scaleMin = Math.min(scaleX, scaleY);
|
||||||
|
var scaleMax = Math.max(scaleX, scaleY);
|
||||||
|
if (meetOrSlice == 'meet') { desiredWidth *= scaleMin; desiredHeight *= scaleMin; }
|
||||||
|
if (meetOrSlice == 'slice') { desiredWidth *= scaleMax; desiredHeight *= scaleMax; }
|
||||||
|
|
||||||
|
refX = new svg.Property('refX', refX);
|
||||||
|
refY = new svg.Property('refY', refY);
|
||||||
|
if (refX.hasValue() && refY.hasValue()) {
|
||||||
|
ctx.translate(-scaleMin * refX.Length.toPixels('x'), -scaleMin * refY.Length.toPixels('y'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// align
|
||||||
|
if (align.match(/^xMid/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(width / 2.0 - desiredWidth / 2.0, 0);
|
||||||
|
if (align.match(/YMid$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, height / 2.0 - desiredHeight / 2.0);
|
||||||
|
if (align.match(/^xMax/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(width - desiredWidth, 0);
|
||||||
|
if (align.match(/YMax$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, height - desiredHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
// scale
|
||||||
|
if (meetOrSlice == 'meet') ctx.scale(scaleMin, scaleMin);
|
||||||
|
if (meetOrSlice == 'slice') ctx.scale(scaleMax, scaleMax);
|
||||||
|
|
||||||
|
// translate
|
||||||
|
ctx.translate(minX == null ? 0 : -minX, minY == null ? 0 : -minY);
|
||||||
|
}
|
||||||
|
|
||||||
// elements
|
// elements
|
||||||
svg.Element = {}
|
svg.Element = {}
|
||||||
|
|
||||||
|
@ -505,6 +592,9 @@ if(!window.console) {
|
||||||
|
|
||||||
// base render
|
// base render
|
||||||
this.render = function(ctx) {
|
this.render = function(ctx) {
|
||||||
|
// don't render display=none
|
||||||
|
if (this.attribute('display').value == 'none') return;
|
||||||
|
|
||||||
ctx.save();
|
ctx.save();
|
||||||
this.setContext(ctx);
|
this.setContext(ctx);
|
||||||
this.renderChildren(ctx);
|
this.renderChildren(ctx);
|
||||||
|
@ -581,10 +671,14 @@ if(!window.console) {
|
||||||
this.styles[name] = new svg.Property(name, value);
|
this.styles[name] = new svg.Property(name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add id
|
||||||
|
if (this.attribute('id').hasValue()) {
|
||||||
|
if (svg.Definitions[this.attribute('id').value] == null) {
|
||||||
|
svg.Definitions[this.attribute('id').value] = this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set id
|
|
||||||
if (this.attribute('id').hasValue()) svg.Definitions[this.attribute('id').value] = this;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -660,6 +754,7 @@ if(!window.console) {
|
||||||
|
|
||||||
this.renderChildren = function(ctx) {
|
this.renderChildren = function(ctx) {
|
||||||
this.path(ctx);
|
this.path(ctx);
|
||||||
|
svg.Mouse.checkPath(this, ctx);
|
||||||
if (ctx.fillStyle != '') ctx.fill();
|
if (ctx.fillStyle != '') ctx.fill();
|
||||||
if (ctx.strokeStyle != '') ctx.stroke();
|
if (ctx.strokeStyle != '') ctx.stroke();
|
||||||
|
|
||||||
|
@ -743,36 +838,17 @@ if(!window.console) {
|
||||||
width = viewBox[2];
|
width = viewBox[2];
|
||||||
height = viewBox[3];
|
height = viewBox[3];
|
||||||
|
|
||||||
// aspect ratio - http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute
|
svg.AspectRatio(ctx,
|
||||||
var preserveAspectRatio = svg.compressSpaces(this.attribute('preserveAspectRatio').value);
|
this.attribute('preserveAspectRatio').value,
|
||||||
preserveAspectRatio = preserveAspectRatio.replace(/^defer\s/,''); // ignore defer
|
svg.ViewPort.width(),
|
||||||
var align = preserveAspectRatio.split(' ')[0] || 'xMidYMid';
|
width,
|
||||||
var meetOrSlice = preserveAspectRatio.split(' ')[1] || 'meet';
|
svg.ViewPort.height(),
|
||||||
|
height,
|
||||||
// calculate scale
|
minX,
|
||||||
var scaleX = svg.ViewPort.width() / width;
|
minY,
|
||||||
var scaleY = svg.ViewPort.height() / height;
|
this.attribute('refX').value,
|
||||||
var scaleMin = Math.min(scaleX, scaleY);
|
this.attribute('refY').value);
|
||||||
var scaleMax = Math.max(scaleX, scaleY);
|
|
||||||
if (meetOrSlice == 'meet') { width *= scaleMin; height *= scaleMin; }
|
|
||||||
if (meetOrSlice == 'slice') { width *= scaleMax; height *= scaleMax; }
|
|
||||||
|
|
||||||
if (this.attribute('refX').hasValue() && this.attribute('refY').hasValue()) {
|
|
||||||
ctx.translate(-scaleMin * this.attribute('refX').Length.toPixels('x'), -scaleMin * this.attribute('refY').Length.toPixels('y'));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// align
|
|
||||||
if (align.match(/^xMid/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(svg.ViewPort.width() / 2.0 - width / 2.0, 0);
|
|
||||||
if (align.match(/YMid$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, svg.ViewPort.height() / 2.0 - height / 2.0);
|
|
||||||
if (align.match(/^xMax/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(svg.ViewPort.width() - width, 0);
|
|
||||||
if (align.match(/YMax$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, svg.ViewPort.height() - height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// scale
|
|
||||||
if (meetOrSlice == 'meet') ctx.scale(scaleMin, scaleMin);
|
|
||||||
if (meetOrSlice == 'slice') ctx.scale(scaleMax, scaleMax);
|
|
||||||
ctx.translate(-minX, -minY);
|
|
||||||
|
|
||||||
svg.ViewPort.RemoveCurrent();
|
svg.ViewPort.RemoveCurrent();
|
||||||
svg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);
|
svg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);
|
||||||
}
|
}
|
||||||
|
@ -969,6 +1045,7 @@ if(!window.console) {
|
||||||
this.reset = function() {
|
this.reset = function() {
|
||||||
this.i = -1;
|
this.i = -1;
|
||||||
this.command = '';
|
this.command = '';
|
||||||
|
this.previousCommand = '';
|
||||||
this.control = new svg.Point(0, 0);
|
this.control = new svg.Point(0, 0);
|
||||||
this.current = new svg.Point(0, 0);
|
this.current = new svg.Point(0, 0);
|
||||||
this.points = [];
|
this.points = [];
|
||||||
|
@ -987,7 +1064,7 @@ if(!window.console) {
|
||||||
this.isRelativeCommand = function() {
|
this.isRelativeCommand = function() {
|
||||||
return this.command == this.command.toLowerCase();
|
return this.command == this.command.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getToken = function() {
|
this.getToken = function() {
|
||||||
this.i = this.i + 1;
|
this.i = this.i + 1;
|
||||||
return this.tokens[this.i];
|
return this.tokens[this.i];
|
||||||
|
@ -998,6 +1075,7 @@ if(!window.console) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.nextCommand = function() {
|
this.nextCommand = function() {
|
||||||
|
this.previousCommand = this.command;
|
||||||
this.command = this.getToken();
|
this.command = this.getToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,8 +1097,13 @@ if(!window.console) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getReflectedControlPoint = function() {
|
this.getReflectedControlPoint = function() {
|
||||||
|
if (this.previousCommand.toLowerCase() != 'c' && this.previousCommand.toLowerCase() != 's') {
|
||||||
|
return this.current;
|
||||||
|
}
|
||||||
|
|
||||||
|
// reflect point
|
||||||
var p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y);
|
var p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y);
|
||||||
return this.makeAbsolute(p);
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.makeAbsolute = function(p) {
|
this.makeAbsolute = function(p) {
|
||||||
|
@ -1146,7 +1229,6 @@ if(!window.console) {
|
||||||
if (ctx != null) ctx.quadraticCurveTo(cntrl.x, cntrl.y, cp.x, cp.y);
|
if (ctx != null) ctx.quadraticCurveTo(cntrl.x, cntrl.y, cp.x, cp.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (pp.command.toUpperCase() == 'A') {
|
else if (pp.command.toUpperCase() == 'A') {
|
||||||
while (!pp.isCommandOrEnd()) {
|
while (!pp.isCommandOrEnd()) {
|
||||||
var curr = pp.current;
|
var curr = pp.current;
|
||||||
|
@ -1304,7 +1386,7 @@ if(!window.console) {
|
||||||
// definitions element
|
// definitions element
|
||||||
svg.Element.defs = function(node) {
|
svg.Element.defs = function(node) {
|
||||||
this.base = svg.Element.ElementBase;
|
this.base = svg.Element.ElementBase;
|
||||||
this.base(node);
|
this.base(node);
|
||||||
|
|
||||||
this.render = function(ctx) {
|
this.render = function(ctx) {
|
||||||
// NOOP
|
// NOOP
|
||||||
|
@ -1324,15 +1406,20 @@ if(!window.console) {
|
||||||
var child = this.children[i];
|
var child = this.children[i];
|
||||||
this.stops.push(child);
|
this.stops.push(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getGradient = function() {
|
this.getGradient = function() {
|
||||||
// OVERRIDE ME!
|
// OVERRIDE ME!
|
||||||
}
|
}
|
||||||
|
|
||||||
this.createGradient = function(ctx, element) {
|
this.createGradient = function(ctx, element) {
|
||||||
|
var stopsContainer = this;
|
||||||
|
if (this.attribute('xlink:href').hasValue()) {
|
||||||
|
stopsContainer = this.attribute('xlink:href').Definition.getDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
var g = this.getGradient(ctx, element);
|
var g = this.getGradient(ctx, element);
|
||||||
for (var i=0; i<this.stops.length; i++) {
|
for (var i=0; i<stopsContainer.stops.length; i++) {
|
||||||
g.addColorStop(this.stops[i].offset, this.stops[i].color);
|
g.addColorStop(stopsContainer.stops[i].offset, stopsContainer.stops[i].color);
|
||||||
}
|
}
|
||||||
return g;
|
return g;
|
||||||
}
|
}
|
||||||
|
@ -1360,7 +1447,15 @@ if(!window.console) {
|
||||||
? bb.y() + bb.height() * this.attribute('y2').numValue()
|
? bb.y() + bb.height() * this.attribute('y2').numValue()
|
||||||
: this.attribute('y2').Length.toPixels('y'));
|
: this.attribute('y2').Length.toPixels('y'));
|
||||||
|
|
||||||
return ctx.createLinearGradient(x1, y1, x2, y2);
|
var p1 = new svg.Point(x1, y1);
|
||||||
|
var p2 = new svg.Point(x2, y2);
|
||||||
|
if (this.attribute('gradientTransform').hasValue()) {
|
||||||
|
var transform = new svg.Transform(this.attribute('gradientTransform').value);
|
||||||
|
transform.applyToPoint(p1);
|
||||||
|
transform.applyToPoint(p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.createLinearGradient(p1.x, p1.y, p2.x, p2.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
svg.Element.linearGradient.prototype = new svg.Element.GradientBase;
|
svg.Element.linearGradient.prototype = new svg.Element.GradientBase;
|
||||||
|
@ -1397,7 +1492,15 @@ if(!window.console) {
|
||||||
? (bb.width() + bb.height()) / 2.0 * this.attribute('r').numValue()
|
? (bb.width() + bb.height()) / 2.0 * this.attribute('r').numValue()
|
||||||
: this.attribute('r').Length.toPixels());
|
: this.attribute('r').Length.toPixels());
|
||||||
|
|
||||||
return ctx.createRadialGradient(fx, fy, 0, cx, cy, r);
|
var c = new svg.Point(cx, cy);
|
||||||
|
var f = new svg.Point(fx, fy);
|
||||||
|
if (this.attribute('gradientTransform').hasValue()) {
|
||||||
|
var transform = new svg.Transform(this.attribute('gradientTransform').value);
|
||||||
|
transform.applyToPoint(c);
|
||||||
|
transform.applyToPoint(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ctx.createRadialGradient(f.x, f.y, 0, c.x, c.y, r);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
svg.Element.radialGradient.prototype = new svg.Element.GradientBase;
|
svg.Element.radialGradient.prototype = new svg.Element.GradientBase;
|
||||||
|
@ -1555,10 +1658,26 @@ if(!window.console) {
|
||||||
var x = this.attribute('x').Length.toPixels('x');
|
var x = this.attribute('x').Length.toPixels('x');
|
||||||
var y = this.attribute('y').Length.toPixels('y');
|
var y = this.attribute('y').Length.toPixels('y');
|
||||||
for (var i=0; i<this.children.length; i++) {
|
for (var i=0; i<this.children.length; i++) {
|
||||||
this.children[i].x = x;
|
var child = this.children[i];
|
||||||
this.children[i].y = y;
|
|
||||||
this.children[i].render(ctx);
|
if (child.attribute('x').hasValue()) {
|
||||||
x += this.children[i].measureText(ctx);
|
child.x = child.attribute('x').Length.toPixels('x');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (child.attribute('dx').hasValue()) x += child.attribute('dx').Length.toPixels('x');
|
||||||
|
child.x = x;
|
||||||
|
x += child.measureText(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child.attribute('y').hasValue()) {
|
||||||
|
child.y = child.attribute('y').Length.toPixels('y');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (child.attribute('dy').hasValue()) y += child.attribute('dy').Length.toPixels('y');
|
||||||
|
child.y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
child.render(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1578,7 +1697,9 @@ if(!window.console) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.measureText = function(ctx) {
|
this.measureText = function(ctx) {
|
||||||
return ctx.measureText(svg.compressSpaces(this.getText())).width;
|
var textToMeasure = svg.compressSpaces(this.getText());
|
||||||
|
if (!ctx.measureText) return textToMeasure.length * 10;
|
||||||
|
return ctx.measureText(textToMeasure).width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
svg.Element.TextElementBase.prototype = new svg.Element.RenderedElementBase;
|
svg.Element.TextElementBase.prototype = new svg.Element.RenderedElementBase;
|
||||||
|
@ -1608,6 +1729,96 @@ if(!window.console) {
|
||||||
}
|
}
|
||||||
svg.Element.tref.prototype = new svg.Element.TextElementBase;
|
svg.Element.tref.prototype = new svg.Element.TextElementBase;
|
||||||
|
|
||||||
|
// a element
|
||||||
|
svg.Element.a = function(node) {
|
||||||
|
this.base = svg.Element.TextElementBase;
|
||||||
|
this.base(node);
|
||||||
|
|
||||||
|
this.hasText = true;
|
||||||
|
for (var i=0; i<node.childNodes.length; i++) {
|
||||||
|
if (node.childNodes[i].nodeType != 3) this.hasText = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// this might contain text
|
||||||
|
this.text = this.hasText ? node.childNodes[0].nodeValue : '';
|
||||||
|
this.getText = function() {
|
||||||
|
return this.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.baseRenderChildren = this.renderChildren;
|
||||||
|
this.renderChildren = function(ctx) {
|
||||||
|
if (this.hasText) {
|
||||||
|
// render as text element
|
||||||
|
this.baseRenderChildren(ctx);
|
||||||
|
var fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize);
|
||||||
|
svg.Mouse.checkBoundingBox(this, new svg.BoundingBox(this.x, this.y - fontSize.Length.toPixels('y'), this.x + this.measureText(ctx), this.y));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// render as temporary group
|
||||||
|
var g = new svg.Element.g();
|
||||||
|
g.children = this.children;
|
||||||
|
g.parent = this;
|
||||||
|
g.render(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onclick = function() {
|
||||||
|
window.open(this.attribute('xlink:href').value);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onmousemove = function() {
|
||||||
|
svg.ctx.canvas.style.cursor = 'pointer';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
svg.Element.a.prototype = new svg.Element.TextElementBase;
|
||||||
|
|
||||||
|
// image element
|
||||||
|
svg.Element.image = function(node) {
|
||||||
|
this.base = svg.Element.RenderedElementBase;
|
||||||
|
this.base(node);
|
||||||
|
|
||||||
|
this.img = document.createElement('img');
|
||||||
|
this.loaded = false;
|
||||||
|
|
||||||
|
var that = this;
|
||||||
|
this.renderChildren = function(ctx) {
|
||||||
|
if (!this.loaded) {
|
||||||
|
var src = this.attribute('xlink:href').value;
|
||||||
|
this.img.onload = function() {
|
||||||
|
that.loaded = true;
|
||||||
|
that.drawImage(ctx);
|
||||||
|
}
|
||||||
|
this.img.src = src;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.drawImage(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.drawImage = function(ctx) {
|
||||||
|
var x = this.attribute('x').Length.toPixels('x');
|
||||||
|
var y = this.attribute('y').Length.toPixels('y');
|
||||||
|
|
||||||
|
var width = this.attribute('width').Length.toPixels('x');
|
||||||
|
var height = this.attribute('height').Length.toPixels('y');
|
||||||
|
if (width == 0 || height == 0) return;
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
ctx.translate(x, y);
|
||||||
|
svg.AspectRatio(ctx,
|
||||||
|
this.attribute('preserveAspectRatio').value,
|
||||||
|
width,
|
||||||
|
this.img.width,
|
||||||
|
height,
|
||||||
|
this.img.height,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
ctx.drawImage(this.img, 0, 0);
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
svg.Element.image.prototype = new svg.Element.RenderedElementBase;
|
||||||
|
|
||||||
// group element
|
// group element
|
||||||
svg.Element.g = function(node) {
|
svg.Element.g = function(node) {
|
||||||
this.base = svg.Element.RenderedElementBase;
|
this.base = svg.Element.RenderedElementBase;
|
||||||
|
@ -1621,14 +1832,7 @@ if(!window.console) {
|
||||||
this.base(node);
|
this.base(node);
|
||||||
}
|
}
|
||||||
svg.Element.symbol.prototype = new svg.Element.RenderedElementBase;
|
svg.Element.symbol.prototype = new svg.Element.RenderedElementBase;
|
||||||
|
|
||||||
// a element
|
|
||||||
svg.Element.a = function(node) {
|
|
||||||
this.base = svg.Element.RenderedElementBase;
|
|
||||||
this.base(node);
|
|
||||||
}
|
|
||||||
svg.Element.a.prototype = new svg.Element.RenderedElementBase;
|
|
||||||
|
|
||||||
// style element
|
// style element
|
||||||
svg.Element.style = function(node) {
|
svg.Element.style = function(node) {
|
||||||
this.base = svg.Element.ElementBase;
|
this.base = svg.Element.ElementBase;
|
||||||
|
@ -1658,7 +1862,6 @@ if(!window.console) {
|
||||||
svg.Styles[cssClass] = props;
|
svg.Styles[cssClass] = props;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1676,8 +1879,17 @@ if(!window.console) {
|
||||||
if (this.attribute('y').hasValue()) ctx.translate(0, this.attribute('y').Length.toPixels('y'));
|
if (this.attribute('y').hasValue()) ctx.translate(0, this.attribute('y').Length.toPixels('y'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.getDefinition = function() {
|
||||||
|
return this.attribute('xlink:href').Definition.getDefinition();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.path = function(ctx) {
|
||||||
|
var element = this.getDefinition();
|
||||||
|
if (element != null) element.path(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
this.renderChildren = function(ctx) {
|
this.renderChildren = function(ctx) {
|
||||||
var element = this.attribute('xlink:href').Definition.getDefinition();
|
var element = this.getDefinition();
|
||||||
if (element != null) element.render(ctx);
|
if (element != null) element.render(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1732,6 +1944,28 @@ if(!window.console) {
|
||||||
// load from xml
|
// load from xml
|
||||||
svg.loadXml = function(ctx, xml) {
|
svg.loadXml = function(ctx, xml) {
|
||||||
svg.init(ctx);
|
svg.init(ctx);
|
||||||
|
|
||||||
|
var mapXY = function(p) {
|
||||||
|
var e = ctx.canvas;
|
||||||
|
while (e) {
|
||||||
|
p.x -= e.offsetLeft;
|
||||||
|
p.y -= e.offsetTop;
|
||||||
|
e = e.offsetParent;
|
||||||
|
}
|
||||||
|
if (window.scrollX) p.x += window.scrollX;
|
||||||
|
if (window.scrollY) p.y += window.scrollY;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind mouse
|
||||||
|
ctx.canvas.onclick = function(e) {
|
||||||
|
var p = mapXY(new svg.Point(e != null ? e.clientX : event.clientX, e != null ? e.clientY : event.clientY));
|
||||||
|
svg.Mouse.onclick(p.x, p.y);
|
||||||
|
}
|
||||||
|
ctx.canvas.onmousemove = function(e) {
|
||||||
|
var p = mapXY(new svg.Point(e != null ? e.clientX : event.clientX, e != null ? e.clientY : event.clientY));
|
||||||
|
svg.Mouse.onmousemove(p.x, p.y);
|
||||||
|
}
|
||||||
|
|
||||||
var dom = svg.parseXml(xml);
|
var dom = svg.parseXml(xml);
|
||||||
var e = svg.CreateElement(dom.documentElement);
|
var e = svg.CreateElement(dom.documentElement);
|
||||||
|
@ -1749,16 +1983,25 @@ if(!window.console) {
|
||||||
ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
|
ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
|
||||||
e.render(ctx);
|
e.render(ctx);
|
||||||
svg.intervalID = setInterval(function() {
|
svg.intervalID = setInterval(function() {
|
||||||
// update animations
|
|
||||||
var needUpdate = false;
|
var needUpdate = false;
|
||||||
for (var i=0; i<svg.Animations.length; i++) {
|
|
||||||
needUpdate = needUpdate | svg.Animations[i].update(1000 / svg.FRAMERATE);
|
// need update from mouse events?
|
||||||
|
if (svg.opts == null || svg.opts['ignoreMouse'] != true) {
|
||||||
|
needUpdate = needUpdate | svg.Mouse.hasEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// need update from animations?
|
||||||
|
if (svg.opts == null || svg.opts['ignoreAnimation'] != true) {
|
||||||
|
for (var i=0; i<svg.Animations.length; i++) {
|
||||||
|
needUpdate = needUpdate | svg.Animations[i].update(1000 / svg.FRAMERATE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// render if needed
|
// render if needed
|
||||||
if (needUpdate) {
|
if (needUpdate) {
|
||||||
ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
|
ctx.clearRect(0, 0, ctx.canvas.clientWidth, ctx.canvas.clientHeight);
|
||||||
e.render(ctx);
|
e.render(ctx);
|
||||||
|
svg.Mouse.runEvents(); // run and clear our events
|
||||||
}
|
}
|
||||||
}, 1000 / svg.FRAMERATE);
|
}, 1000 / svg.FRAMERATE);
|
||||||
}
|
}
|
||||||
|
@ -1769,6 +2012,56 @@ if(!window.console) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svg.Mouse = new (function() {
|
||||||
|
this.events = [];
|
||||||
|
this.hasEvents = function() { return this.events.length != 0; }
|
||||||
|
|
||||||
|
this.onclick = function(x, y) {
|
||||||
|
this.events.push({ type: 'onclick', x: x, y: y,
|
||||||
|
run: function(e) { if (e.onclick) e.onclick(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.onmousemove = function(x, y) {
|
||||||
|
this.events.push({ type: 'onmousemove', x: x, y: y,
|
||||||
|
run: function(e) { if (e.onmousemove) e.onmousemove(); }
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.eventElements = [];
|
||||||
|
|
||||||
|
this.checkPath = function(element, ctx) {
|
||||||
|
for (var i=0; i<this.events.length; i++) {
|
||||||
|
var e = this.events[i];
|
||||||
|
if (ctx.isPointInPath && ctx.isPointInPath(e.x, e.y)) this.eventElements[i] = element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.checkBoundingBox = function(element, bb) {
|
||||||
|
for (var i=0; i<this.events.length; i++) {
|
||||||
|
var e = this.events[i];
|
||||||
|
if (bb.isPointInBox(e.x, e.y)) this.eventElements[i] = element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.runEvents = function() {
|
||||||
|
svg.ctx.canvas.style.cursor = '';
|
||||||
|
|
||||||
|
for (var i=0; i<this.events.length; i++) {
|
||||||
|
var e = this.events[i];
|
||||||
|
var element = this.eventElements[i];
|
||||||
|
while (element) {
|
||||||
|
e.run(element);
|
||||||
|
element = element.parent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// done running, clear
|
||||||
|
this.events = [];
|
||||||
|
this.eventElements = [];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return svg;
|
return svg;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
|
@ -578,24 +578,25 @@
|
||||||
c.width = svgCanvas.contentW;
|
c.width = svgCanvas.contentW;
|
||||||
c.height = svgCanvas.contentH;
|
c.height = svgCanvas.contentH;
|
||||||
canvg(c, data.svg);
|
canvg(c, data.svg);
|
||||||
var datauri = c.toDataURL('image/png');
|
setTimeout(function() {
|
||||||
exportWindow.location.href = datauri;
|
var datauri = c.toDataURL('image/png');
|
||||||
|
exportWindow.location.href = datauri;
|
||||||
var done = $.pref('export_notice_done');
|
var done = $.pref('export_notice_done');
|
||||||
if(done !== "all") {
|
if(done !== "all") {
|
||||||
var note = uiStrings.saveFromBrowser.replace('%s', 'PNG');
|
var note = uiStrings.saveFromBrowser.replace('%s', 'PNG');
|
||||||
|
|
||||||
// Check if there's issues
|
// Check if there's issues
|
||||||
if(issues.length) {
|
if(issues.length) {
|
||||||
var pre = "\n \u2022 ";
|
var pre = "\n \u2022 ";
|
||||||
note += ("\n\n" + uiStrings.noteTheseIssues + pre + issues.join(pre));
|
note += ("\n\n" + uiStrings.noteTheseIssues + pre + issues.join(pre));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note that this will also prevent the notice even though new issues may appear later.
|
// Note that this will also prevent the notice even though new issues may appear later.
|
||||||
// May want to find a way to deal with that without annoying the user
|
// May want to find a way to deal with that without annoying the user
|
||||||
$.pref('export_notice_done', 'all');
|
$.pref('export_notice_done', 'all');
|
||||||
exportWindow.alert(note);
|
exportWindow.alert(note);
|
||||||
}
|
}
|
||||||
|
},1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
// called when we've selected a different element
|
// called when we've selected a different element
|
||||||
|
|
|
@ -7730,7 +7730,6 @@ this.rasterExport = function() {
|
||||||
// Selector and notice
|
// Selector and notice
|
||||||
var issue_list = {
|
var issue_list = {
|
||||||
'feGaussianBlur': uiStrings.exportNoBlur,
|
'feGaussianBlur': uiStrings.exportNoBlur,
|
||||||
'image': uiStrings.exportNoImage,
|
|
||||||
'foreignObject': uiStrings.exportNoforeignObject,
|
'foreignObject': uiStrings.exportNoforeignObject,
|
||||||
'[stroke-dasharray]': uiStrings.exportNoDashArray
|
'[stroke-dasharray]': uiStrings.exportNoDashArray
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue