SvgImporter: Various cleanups and improvements.

This commit is contained in:
Jonathan Puckey 2012-11-08 14:32:09 +01:00
parent 494874ec8f
commit b7c50a16d1

View file

@ -40,6 +40,34 @@ new function() {
return Size.create(getValue(svg, w, index), getValue(svg, h, index)); return Size.create(getValue(svg, w, index), getValue(svg, h, index));
} }
function getSvgRadius(svg) {
return getValue(svg, 'r');
}
function getSvgOrigin(svg) {
return getPoint(svg, 'x1', 'y1');
}
function getSvgDestination(svg) {
return getPoint(svg, 'x2', 'y2');
}
function getSvgCenter(svg) {
return getPoint(svg, 'cx', 'cy');
}
function getSvgPoint(svg, index) {
return getPoint(svg, 'x', 'y', index);
}
function getSvgRadiusSize(svg) {
return getSize(svg, 'rx', 'ry');
}
function getSvgSize(svg) {
return getSize(svg, 'width', 'height');
}
// Define importer functions for various SVG node types // Define importer functions for various SVG node types
function importGroup(svg, type) { function importGroup(svg, type) {
@ -191,13 +219,9 @@ new function() {
for (var i = 0, l = nodes.length; i < l; i++) { for (var i = 0, l = nodes.length; i < l; i++) {
var node = nodes[i]; var node = nodes[i];
if (node.nodeType == 1) { if (node.nodeType == 1) {
var style = node.style, var stop = new GradientStop();
color = new RgbColor(node.getAttribute('stop-color') || style['stop-color']), applyAttributes(stop, node);
opacity = node.getAttribute('stop-opacity') || style['stop-opacity'], stops.push(stop);
offset = node.getAttribute('offset');
if (opacity != '')
color.setAlpha(parseFloat(opacity, 10));
stops.push([color, offset]);
} }
} }
var gradient = new Gradient(stops), var gradient = new Gradient(stops),
@ -205,31 +229,15 @@ new function() {
origin, destination, highlight; origin, destination, highlight;
if (isRadial) { if (isRadial) {
gradient.type = 'radial'; gradient.type = 'radial';
var radius = parseFloat(svg.getAttribute('r'), 10); origin = getSvgCenter(svg);
origin = [ destination = origin.add(getSvgRadius(svg), 0);
parseFloat(svg.getAttribute('cx'), 10),
parseFloat(svg.getAttribute('cy'), 10)
];
destination = [
parseFloat(origin[0] + radius, 10),
parseFloat(origin[1], 10)
];
var fx = svg.getAttribute('fx'); var fx = svg.getAttribute('fx');
if (fx) { if (fx) {
highlight = [ highlight = getPoint(svg, 'fx', 'fy');
parseFloat(fx, 10),
parseFloat(svg.getAttribute('fy'), 10)
];
} }
} else { } else {
origin = [ origin = getSvgOrigin(svg);
parseFloat(svg.getAttribute('x1'), 10), destination = getSvgDestination(svg);
parseFloat(svg.getAttribute('y1'), 10)
];
destination = [
parseFloat(svg.getAttribute('x2'), 10),
parseFloat(svg.getAttribute('y2'), 10)
];
} }
var gradientColor = new GradientColor(gradient, origin, destination, highlight); var gradientColor = new GradientColor(gradient, origin, destination, highlight);
applyAttributes(gradientColor, svg); applyAttributes(gradientColor, svg);
@ -267,29 +275,27 @@ new function() {
// http://www.w3.org/TR/SVG/struct.html#UseElement // http://www.w3.org/TR/SVG/struct.html#UseElement
use: function(svg, type) { use: function(svg, type) {
var id = svg.getAttribute('xlink:href').substr(1); return applyAttributes(null, svg);
return definitions[id].clone();
}, },
// http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGCircleElement // http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGCircleElement
circle: function(svg) { circle: function(svg) {
return new Path.Circle(getPoint(svg, 'cx', 'cy'), return new Path.Circle(getSvgCenter(svg), getSvgRadius(svg));
getValue(svg, 'r'));
}, },
// http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGEllipseElement // http://www.w3.org/TR/SVG/shapes.html#InterfaceSVGEllipseElement
ellipse: function(svg) { ellipse: function(svg) {
var center = getPoint(svg, 'cx', 'cy'), var center = getSvgCenter(svg),
radius = getSize(svg, 'rx', 'ry'); radius = getSvgRadiusSize(svg);
return new Path.Ellipse(new Rectangle(center.subtract(radius), return new Path.Ellipse(new Rectangle(center.subtract(radius),
center.add(radius))); center.add(radius)));
}, },
// http://www.w3.org/TR/SVG/shapes.html#RectElement // http://www.w3.org/TR/SVG/shapes.html#RectElement
rect: function(svg) { rect: function(svg) {
var point = getPoint(svg, 'x', 'y'), var point = getSvgPoint(svg),
size = getSize(svg, 'width', 'height'), size = getSvgSize(svg),
radius = getSize(svg, 'rx', 'ry'); radius = getSvgRadiusSize(svg);
// If radius is 0, Path.RoundRectangle automatically produces a // If radius is 0, Path.RoundRectangle automatically produces a
// normal rectangle for us. // normal rectangle for us.
return new Path.RoundRectangle(new Rectangle(point, size), radius); return new Path.RoundRectangle(new Rectangle(point, size), radius);
@ -297,8 +303,7 @@ new function() {
// http://www.w3.org/TR/SVG/shapes.html#LineElement // http://www.w3.org/TR/SVG/shapes.html#LineElement
line: function(svg) { line: function(svg) {
return new Path.Line(getPoint(svg, 'x1', 'y1'), return new Path.Line(getOrigin(svg), getDestination(svg));
getPoint(svg, 'x2', 'y2'));
}, },
text: function(svg) { text: function(svg) {
@ -310,7 +315,7 @@ new function() {
// TODO: Support for these is missing in Paper.js right now // TODO: Support for these is missing in Paper.js right now
// rotate: character rotation // rotate: character rotation
// lengthAdjust: // lengthAdjust:
var text = new PointText(getPoint(svg, 'x', 'y', 0) var text = new PointText(getSvgPoint(svg, 0)
.add(getPoint(svg, 'dx', 'dy', 0))); .add(getPoint(svg, 'dx', 'dy', 0)));
text.content = svg.textContent || ''; text.content = svg.textContent || '';
return text; return text;
@ -379,13 +384,21 @@ new function() {
// applyAttribute(). So let's have this change propagate back up // applyAttribute(). So let's have this change propagate back up
item = group; item = group;
break; break;
// http://www.w3.org/TR/SVG/coords.html#TransformAttribute // http://www.w3.org/TR/SVG/types.html#DataTypeTransformList
case 'gradientTransform': case 'gradientTransform':
case 'transform': case 'transform':
applyTransform(item, svg); applyTransform(item, svg, name);
break; break;
// http://www.w3.org/TR/SVG/pservers.html#StopOpacityProperty
case 'stop-opacity':
// http://www.w3.org/TR/SVG/masking.html#OpacityProperty
case 'opacity': case 'opacity':
item.setOpacity(parseFloat(value, 10)); var opacity = parseFloat(value, 10);
if (name === 'stop-opacity') {
item.color.setAlpha(opacity);
} else {
item.setOpacity(opacity);
}
break; break;
case 'visibility': case 'visibility':
item.setVisible(value === 'visible'); item.setVisible(value === 'visible');
@ -397,6 +410,17 @@ new function() {
case 'text-anchor': case 'text-anchor':
applyTextAttribute(item, svg, name, value); applyTextAttribute(item, svg, name, value);
break; break;
// http://www.w3.org/TR/SVG/pservers.html#StopColorProperty
case 'stop-color':
item.setColor(value);
break;
// http://www.w3.org/TR/SVG/pservers.html#StopElementOffsetAttribute
// TODO: this can be a string with % at the end
case 'offset':
item.setRampPoint(parseFloat(value, 10));
break;
case 'xlink:href':
item = definitions[value.substr(1)].clone();
default: default:
// Not supported yet. // Not supported yet.
break; break;
@ -448,7 +472,7 @@ new function() {
* @param {Item} item a Paper.js item * @param {Item} item a Paper.js item
*/ */
function applyTransform(item, svg, name) { function applyTransform(item, svg, name) {
var svgTransform = svg[name == 'transform' ? 'transform' : 'gradientTransform'], var svgTransform = svg[name],
transforms = svgTransform.baseVal, transforms = svgTransform.baseVal,
matrix = new Matrix(); matrix = new Matrix();
for (var i = 0, l = transforms.numberOfItems; i < l; i++) { for (var i = 0, l = transforms.numberOfItems; i < l; i++) {