2012-09-30 17:51:50 -04:00
|
|
|
/*
|
2012-11-02 20:47:14 -04:00
|
|
|
* Paper.js
|
|
|
|
*
|
|
|
|
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
|
|
|
|
* based on Scriptographer.org and designed to be largely API compatible.
|
|
|
|
* http://paperjs.org/
|
|
|
|
* http://scriptographer.org/
|
|
|
|
*
|
|
|
|
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
|
|
|
|
* http://lehni.org/ & http://jonathanpuckey.com/
|
|
|
|
*
|
|
|
|
* Distributed under the MIT license. See LICENSE file for details.
|
|
|
|
*
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
2012-11-02 21:14:20 -04:00
|
|
|
* The base for this code was donated by Stetson-Team-Alpha.
|
2012-11-02 20:47:14 -04:00
|
|
|
* @author Stetson-Team-Alpha
|
|
|
|
*/
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-09-13 20:45:27 -04:00
|
|
|
/**
|
2012-11-02 20:47:14 -04:00
|
|
|
* @name SvgImporter
|
|
|
|
* @class The SvgImporter object represents an object created using the SVG
|
|
|
|
* Canvas that will be converted into a Paper.js object.
|
|
|
|
* The SVG object is imported into Paper.js by converting it into items
|
|
|
|
* within groups.
|
|
|
|
*
|
|
|
|
*/
|
2012-11-02 21:40:41 -04:00
|
|
|
var SvgImporter = this.SvgImporter = new function() {
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
function importGroup(svg) {
|
2012-09-30 17:51:50 -04:00
|
|
|
var group = new Group();
|
2012-11-02 19:51:42 -04:00
|
|
|
var nodes = svg.childNodes;
|
|
|
|
for (var i = 0, l = nodes.length; i < l; i++) {
|
|
|
|
var child = nodes[i];
|
|
|
|
if (child.nodeType == 1) {
|
2012-11-02 21:40:41 -04:00
|
|
|
var item = SvgImporter.importSvg(child);
|
2012-11-02 19:51:42 -04:00
|
|
|
if (item)
|
|
|
|
group.addChild(item);
|
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
return group;
|
2012-11-02 21:40:41 -04:00
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
function importPoly(svgPoly) {
|
|
|
|
var poly = new Path();
|
|
|
|
var points = svgPoly.points;
|
|
|
|
var start = points.getItem(0);
|
|
|
|
var point;
|
|
|
|
poly.moveTo([start.x, start.y]);
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
for (var i = 1; i < points.length; i++) {
|
|
|
|
point = points.getItem(i);
|
|
|
|
poly.lineTo([point.x, point.y]);
|
|
|
|
}
|
|
|
|
if (svgPoly.nodeName.toLowerCase() == 'polygon') {
|
|
|
|
poly.closePath();
|
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
return poly;
|
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
var importers = {
|
|
|
|
g: importGroup,
|
|
|
|
svg: importGroup,
|
|
|
|
polygon: importPoly,
|
|
|
|
polyline: importPoly,
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
circle: function(svgCircle) {
|
|
|
|
var cx = svgCircle.cx.baseVal.value || 0;
|
|
|
|
var cy = svgCircle.cy.baseVal.value || 0;
|
|
|
|
var r = svgCircle.r.baseVal.value || 0;
|
|
|
|
var center = new Point(cx, cy);
|
|
|
|
var circle = new Path.Circle(center, r);
|
|
|
|
return circle;
|
|
|
|
},
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
ellipse: function(svgOval) {
|
|
|
|
var cx = svgOval.cx.baseVal.value || 0;
|
|
|
|
var cy = svgOval.cy.baseVal.value || 0;
|
|
|
|
var rx = svgOval.rx.baseVal.value || 0;
|
|
|
|
var ry = svgOval.ry.baseVal.value || 0;
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
var center = new Point(cx, cy);
|
|
|
|
var offset = new Point(rx, ry);
|
|
|
|
var topLeft = center.subtract(offset);
|
|
|
|
var bottomRight = center.add(offset);
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
var rect = new Rectangle(topLeft, bottomRight);
|
|
|
|
var oval = new Path.Oval(rect);
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
return oval;
|
|
|
|
},
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
rect: function(svgRectangle) {
|
|
|
|
var x = svgRectangle.x.baseVal.value || 0;
|
|
|
|
var y = svgRectangle.y.baseVal.value || 0;
|
|
|
|
var rx = svgRectangle.rx.baseVal.value || 0;
|
|
|
|
var ry = svgRectangle.ry.baseVal.value || 0;
|
|
|
|
var width = svgRectangle.width.baseVal.value || 0;
|
|
|
|
var height = svgRectangle.height.baseVal.value || 0;
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
var topLeft = new Point(x, y);
|
|
|
|
var size = new Size(width, height);
|
|
|
|
var rectangle = new Rectangle(topLeft, size);
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
return new Path.RoundRectangle(rectangle, new Size(rx, ry));
|
|
|
|
},
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
line: function(svgLine) {
|
|
|
|
var x1 = svgLine.x1.baseVal.value || 0;
|
|
|
|
var y1 = svgLine.y1.baseVal.value || 0;
|
|
|
|
var x2 = svgLine.x2.baseVal.value || 0;
|
|
|
|
var y2 = svgLine.y2.baseVal.value || 0;
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
var from = new Point(x1, y1);
|
|
|
|
var to = new Point(x2, y2);
|
|
|
|
var line = new Path.Line(from, to);
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
return line;
|
|
|
|
},
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
text: function(svgText) {
|
|
|
|
var x = svgText.x.baseVal.getItem(0).value || 0;
|
|
|
|
var y = svgText.y.baseVal.getItem(0).value || 0;
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
var dx = 0;
|
|
|
|
var dy = 0;
|
|
|
|
if (svgText.dx.baseVal.numberOfItems) {
|
|
|
|
dx = svgText.dx.baseVal.getItem(0).value || 0;
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-11-02 21:40:41 -04:00
|
|
|
if (svgText.dy.baseVal.numberOfItems) {
|
|
|
|
dy = svgText.dy.baseVal.getItem(0).value || 0;
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-11-02 21:40:41 -04:00
|
|
|
|
|
|
|
var textLength = svgText.textLength.baseVal.value || 0;
|
|
|
|
|
|
|
|
// Not supported by Paper.js
|
|
|
|
// x: multiple values for x
|
|
|
|
// y: multiple values for y
|
|
|
|
// dx: multiple values for x
|
|
|
|
// dy: multiple values for y
|
|
|
|
// rotate: character rotation
|
|
|
|
// lengthAdjust:
|
|
|
|
var textContent = svgText.textContent || "";
|
|
|
|
var bottomLeft = new Point(x, y);
|
|
|
|
|
|
|
|
bottomLeft = bottomLeft.add([dx, dy]);
|
|
|
|
bottomLeft = bottomLeft.subtract([textLength / 2, 0]);
|
|
|
|
var text = new PointText(bottomLeft);
|
|
|
|
text.content = textContent;
|
|
|
|
|
|
|
|
return text;
|
|
|
|
},
|
|
|
|
|
|
|
|
path: function(svgPath) {
|
|
|
|
var path = new Path();
|
|
|
|
var segments = svgPath.pathSegList;
|
|
|
|
var segment;
|
|
|
|
var j;
|
|
|
|
var relativeToPoint;
|
|
|
|
var controlPoint;
|
|
|
|
var prevCommand;
|
|
|
|
var segmentTo;
|
|
|
|
for (var i = 0; i < segments.numberOfItems; i++) {
|
|
|
|
segment = segments.getItem(i);
|
|
|
|
if (segment.pathSegType == SVGPathSeg.PATHSEG_UNKNOWN) {
|
|
|
|
continue;
|
2012-10-22 19:31:08 -04:00
|
|
|
}
|
2012-11-02 21:40:41 -04:00
|
|
|
if (segment.pathSegType % 2 == 1 && path.segments.length > 0) {
|
|
|
|
relativeToPoint = path.lastSegment.point;
|
|
|
|
} else {
|
|
|
|
relativeToPoint = new Point(0, 0);
|
|
|
|
}
|
|
|
|
segmentTo = new Point(segment.x, segment.y);
|
|
|
|
segmentTo = segmentTo.add(relativeToPoint);
|
|
|
|
switch (segment.pathSegType) {
|
|
|
|
case SVGPathSeg.PATHSEG_CLOSEPATH:
|
|
|
|
path.closePath();
|
|
|
|
break;
|
|
|
|
case SVGPathSeg.PATHSEG_MOVETO_ABS:
|
|
|
|
case SVGPathSeg.PATHSEG_MOVETO_REL:
|
|
|
|
path.moveTo(segmentTo);
|
|
|
|
break;
|
|
|
|
case SVGPathSeg.PATHSEG_LINETO_ABS:
|
|
|
|
case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_ABS:
|
|
|
|
case SVGPathSeg.PATHSEG_LINETO_VERTICAL_ABS:
|
|
|
|
case SVGPathSeg.PATHSEG_LINETO_REL:
|
|
|
|
case SVGPathSeg.PATHSEG_LINETO_HORIZONTAL_REL:
|
|
|
|
case SVGPathSeg.PATHSEG_LINETO_VERTICAL_REL:
|
|
|
|
path.lineTo(segmentTo);
|
|
|
|
break;
|
|
|
|
case SVGPathSeg.PATHSEG_CURVETO_CUBIC_ABS:
|
|
|
|
case SVGPathSeg.PATHSEG_CURVETO_CUBIC_REL:
|
|
|
|
path.cubicCurveTo(
|
|
|
|
relativeToPoint.add([segment.x1, segment.y1]),
|
|
|
|
relativeToPoint.add([segment.x2, segment.y2]),
|
|
|
|
segmentTo
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS:
|
|
|
|
case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL:
|
|
|
|
path.quadraticCurveTo(
|
|
|
|
relativeToPoint.add([segment.x1, segment.y1]),
|
|
|
|
segmentTo
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case SVGPathSeg.PATHSEG_ARC_ABS:
|
|
|
|
case SVGPathSeg.PATHSEG_ARC_REL:
|
|
|
|
//TODO: Implement Arcs.
|
|
|
|
//TODO: Requires changes in Paper.js's Path to do.
|
|
|
|
//TODO: http://www.w3.org/TR/SVG/implnote.html
|
|
|
|
break;
|
|
|
|
case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_ABS:
|
|
|
|
case SVGPathSeg.PATHSEG_CURVETO_CUBIC_SMOOTH_REL:
|
|
|
|
prevCommand = segments.getItem(i - 1);
|
|
|
|
controlPoint = new Point(prevCommand.x2, prevCommand.y2);
|
|
|
|
controlPoint = controlPoint.subtract([prevCommand.x, prevCommand.y]);
|
|
|
|
controlPoint = controlPoint.add(path.lastSegment.point);
|
|
|
|
controlPoint = path.lastSegment.point.subtract(controlPoint);
|
|
|
|
controlPoint = path.lastSegment.point.add(controlPoint);
|
|
|
|
path.cubicCurveTo(
|
|
|
|
controlPoint,
|
|
|
|
relativeToPoint.add([segment.x2, segment.y2]),
|
|
|
|
segmentTo
|
|
|
|
);
|
|
|
|
break;
|
|
|
|
case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_ABS:
|
|
|
|
case SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL:
|
|
|
|
for (j = i; j >= 0; --j) {
|
|
|
|
prevCommand = segments.getItem(j);
|
|
|
|
if (prevCommand.pathSegType == SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_ABS ||
|
|
|
|
prevCommand.pathSegType == SVGPathSeg.PATHSEG_CURVETO_QUADRATIC_REL
|
|
|
|
) {
|
|
|
|
controlPoint = new Point(prevCommand.x1, prevCommand.y1);
|
|
|
|
controlPoint = controlPoint.subtract([prevCommand.x, prevCommand.y]);
|
|
|
|
controlPoint = controlPoint.add(path.segments[j].point);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (j; j < i; ++j) {
|
|
|
|
controlPoint = path.segments[j].point.subtract(controlPoint);
|
|
|
|
controlPoint = path.segments[j].point.add(controlPoint);
|
|
|
|
}
|
|
|
|
path.quadraticCurveTo(controlPoint, segmentTo);
|
|
|
|
break;
|
2012-10-22 19:31:08 -04:00
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
return path;
|
|
|
|
},
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-11-02 21:40:41 -04:00
|
|
|
symbol: function(svg) {
|
|
|
|
var item = importGroup(svg);
|
|
|
|
importAttributesAndStyles(svg, item);
|
|
|
|
// TODO: We're returning a symbol. How to handle this?
|
|
|
|
return new Symbol(item);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-11-02 21:40:41 -04:00
|
|
|
};
|
2012-09-30 17:51:50 -04:00
|
|
|
|
2012-09-15 23:58:39 -04:00
|
|
|
/**
|
2012-09-30 17:51:50 -04:00
|
|
|
* Converts various SVG styles and attributes into Paper.js styles and
|
2012-11-02 21:14:20 -04:00
|
|
|
* attributes and applies them to the passed item.
|
2012-09-30 17:51:50 -04:00
|
|
|
*
|
2012-11-02 21:14:20 -04:00
|
|
|
* @param {SVGSVGElement} svg an SVG node to read style and attributes from.
|
|
|
|
* @param {Item} item the item to apply the style and attributes to.
|
2012-09-15 23:58:39 -04:00
|
|
|
*/
|
2012-11-02 21:40:41 -04:00
|
|
|
function importAttributesAndStyles(svg, item) {
|
2012-09-30 17:51:50 -04:00
|
|
|
var name,
|
|
|
|
value,
|
|
|
|
cssName;
|
2012-11-02 21:22:38 -04:00
|
|
|
for (var i = 0; i < svg.style.length; i++) {
|
2012-09-30 17:51:50 -04:00
|
|
|
name = svg.style[i];
|
|
|
|
cssName = name.replace(/-(.)/g, function(match, p) {
|
|
|
|
return p.toUpperCase();
|
|
|
|
});
|
|
|
|
value = svg.style[cssName];
|
2012-11-02 21:40:41 -04:00
|
|
|
applyAttributeOrStyle(name, value, item, svg);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-11-02 21:22:38 -04:00
|
|
|
for (var i = 0; i < svg.attributes.length; i++) {
|
2012-09-30 17:51:50 -04:00
|
|
|
name = svg.attributes[i].name;
|
|
|
|
value = svg.attributes[i].value;
|
2012-11-02 21:40:41 -04:00
|
|
|
applyAttributeOrStyle(name, value, item, svg);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-11-02 21:40:41 -04:00
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
|
|
|
|
/**
|
2012-11-02 21:14:20 -04:00
|
|
|
* Parses an SVG style attibute and applies it to a Paper.js item.
|
2012-09-30 17:51:50 -04:00
|
|
|
*
|
2012-11-02 21:14:20 -04:00
|
|
|
* @param {String} name an SVG style name
|
|
|
|
* @param value the value of the SVG style
|
|
|
|
* @param {Item} item the item to apply the style or attribute to.
|
|
|
|
* @param {SVGSVGElement} svg an SVG node
|
2012-09-16 01:02:23 -04:00
|
|
|
*/
|
2012-11-02 21:40:41 -04:00
|
|
|
function applyAttributeOrStyle(name, value, item, svg) {
|
2012-09-30 17:51:50 -04:00
|
|
|
if (!value) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (name) {
|
2012-10-22 19:31:08 -04:00
|
|
|
case 'id':
|
|
|
|
item.name = value;
|
|
|
|
break;
|
|
|
|
case 'fill':
|
|
|
|
if (value != 'none') {
|
|
|
|
item.fillColor = value;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'stroke':
|
|
|
|
if (value != 'none') {
|
|
|
|
item.strokeColor = value;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'stroke-width':
|
|
|
|
item.strokeWidth = parseFloat(value, 10);
|
|
|
|
break;
|
|
|
|
case 'stroke-linecap':
|
|
|
|
item.strokeCap = value;
|
|
|
|
break;
|
|
|
|
case 'stroke-linejoin':
|
|
|
|
item.strokeJoin = value;
|
|
|
|
break;
|
|
|
|
case 'stroke-dasharray':
|
|
|
|
value = value.replace(/px/g, '');
|
|
|
|
value = value.replace(/, /g, ',');
|
|
|
|
value = value.replace(/ /g, ',');
|
|
|
|
value = value.split(',');
|
|
|
|
for (var i in value) {
|
|
|
|
value[i] = parseFloat(value[i], 10);
|
|
|
|
}
|
|
|
|
item.dashArray = value;
|
|
|
|
break;
|
|
|
|
case 'stroke-dashoffset':
|
|
|
|
item.dashOffset = parseFloat(value, 10);
|
|
|
|
break;
|
|
|
|
case 'stroke-miterlimit':
|
|
|
|
item.miterLimit = parseFloat(value, 10);
|
|
|
|
break;
|
|
|
|
case 'transform':
|
2012-11-02 21:40:41 -04:00
|
|
|
applyTransform(item, svg);
|
2012-10-27 22:25:52 -04:00
|
|
|
break;
|
2012-10-22 19:31:08 -04:00
|
|
|
case 'opacity':
|
|
|
|
item.opacity = parseFloat(value, 10);
|
2012-10-27 22:25:52 -04:00
|
|
|
break;
|
2012-10-22 19:31:08 -04:00
|
|
|
case 'visibility':
|
|
|
|
item.visibility = (value == 'visible') ? true : false;
|
|
|
|
break;
|
|
|
|
case 'font':
|
|
|
|
case 'font-family':
|
|
|
|
case 'font-size':
|
|
|
|
//Implemented in characterStyle below.
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// Not supported yet.
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (item.characterStyle) {
|
|
|
|
switch (name) {
|
|
|
|
case 'font':
|
|
|
|
var text = document.createElement('span');
|
|
|
|
text.style.font = value;
|
2012-11-02 21:22:38 -04:00
|
|
|
for (var i = 0; i < text.style.length; i++) {
|
2012-10-22 19:31:08 -04:00
|
|
|
var n = text.style[i];
|
2012-11-02 21:40:41 -04:00
|
|
|
applyAttributeOrStyle(n, text.style[n], item, svg);
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 'font-family':
|
2012-10-22 19:31:08 -04:00
|
|
|
var fonts = value.split(',');
|
|
|
|
fonts[0] = fonts[0].replace(/^\s+|\s+$/g, "");
|
|
|
|
item.characterStyle.font = fonts[0];
|
2012-09-30 17:51:50 -04:00
|
|
|
break;
|
2012-10-22 19:31:08 -04:00
|
|
|
case 'font-size':
|
|
|
|
item.characterStyle.fontSize = parseFloat(value, 10);
|
2012-09-30 17:51:50 -04:00
|
|
|
break;
|
2012-11-02 21:40:41 -04:00
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
2012-11-02 21:40:41 -04:00
|
|
|
}
|
2012-09-30 17:51:50 -04:00
|
|
|
|
|
|
|
/**
|
2012-11-02 21:14:20 -04:00
|
|
|
* Applies the transformations specified on the SVG node to a Paper.js item
|
2012-09-30 17:51:50 -04:00
|
|
|
*
|
2012-11-02 21:14:20 -04:00
|
|
|
* @param {Item} item a Paper.js item
|
|
|
|
* @param {SVGSVGElement} svg an SVG node
|
2012-09-30 17:51:50 -04:00
|
|
|
*/
|
2012-11-02 21:40:41 -04:00
|
|
|
function applyTransform(item, svg) {
|
2012-09-30 17:51:50 -04:00
|
|
|
var transforms = svg.transform.baseVal;
|
|
|
|
var transform;
|
|
|
|
var matrix = new Matrix();
|
|
|
|
|
2012-11-02 21:22:38 -04:00
|
|
|
for (var i = 0; i < transforms.numberOfItems; i++) {
|
2012-09-30 17:51:50 -04:00
|
|
|
transform = transforms.getItem(i);
|
|
|
|
if (transform.type == SVGTransform.SVG_TRANSFORM_UNKNOWN) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
var transformMatrix = new Matrix(
|
|
|
|
transform.matrix.a,
|
|
|
|
transform.matrix.c,
|
|
|
|
transform.matrix.b,
|
|
|
|
transform.matrix.d,
|
|
|
|
transform.matrix.e,
|
|
|
|
transform.matrix.f
|
|
|
|
);
|
|
|
|
switch (transform.type) {
|
2012-10-22 19:31:08 -04:00
|
|
|
case SVGTransform.SVG_TRANSFORM_TRANSLATE:
|
|
|
|
break;
|
|
|
|
case SVGTransform.SVG_TRANSFORM_SCALE:
|
|
|
|
break;
|
|
|
|
//Compensate for SVG's theta rotation going the opposite direction
|
|
|
|
case SVGTransform.SVG_TRANSFORM_MATRIX:
|
|
|
|
var temp = transformMatrix.getShearX();
|
|
|
|
transformMatrix.setShearX(transformMatrix.getShearY());
|
|
|
|
transformMatrix.setShearY(temp);
|
|
|
|
break;
|
|
|
|
case SVGTransform.SVG_TRANSFORM_SKEWX:
|
|
|
|
transformMatrix.setShearX(transformMatrix.getShearY());
|
|
|
|
transformMatrix.setShearY(0);
|
|
|
|
break;
|
|
|
|
case SVGTransform.SVG_TRANSFORM_SKEWY:
|
|
|
|
transformMatrix.setShearY(transformMatrix.getShearX());
|
|
|
|
transformMatrix.setShearX(0);
|
|
|
|
break;
|
|
|
|
case SVGTransform.SVG_TRANSFORM_ROTATE:
|
2012-10-27 22:25:52 -04:00
|
|
|
transformMatrix.setShearX(-transformMatrix.getShearX());
|
|
|
|
transformMatrix.setShearY(-transformMatrix.getShearY());
|
2012-10-22 19:31:08 -04:00
|
|
|
break;
|
2012-09-30 17:51:50 -04:00
|
|
|
}
|
|
|
|
matrix.concatenate(transformMatrix);
|
|
|
|
}
|
|
|
|
item.transform(matrix);
|
|
|
|
}
|
2012-11-02 21:40:41 -04:00
|
|
|
|
|
|
|
return /** @Lends SvgImporter */{
|
|
|
|
/**
|
|
|
|
* Creates a Paper.js item using data parsed from the selected
|
|
|
|
* SVG DOM node.
|
|
|
|
*
|
|
|
|
* @param {SVGSVGElement} svg the SVG DOM node to convert
|
|
|
|
* @return {Item} the converted Paper.js item
|
|
|
|
*/
|
|
|
|
importSvg: function(svg) {
|
|
|
|
var importer = importers[svg.nodeName.toLowerCase()];
|
|
|
|
// TODO: importer == null: Not supported yet.
|
|
|
|
var item = importer && importer(svg);
|
|
|
|
if (item)
|
|
|
|
importAttributesAndStyles(svg, item);
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
};
|
2012-11-02 19:19:45 -04:00
|
|
|
};
|