Implement exporting of Gradients to SVG.

This commit is contained in:
Jürg Lehni 2013-02-10 19:38:35 -08:00
parent 199fc046bf
commit e0d0eb175a
3 changed files with 78 additions and 14 deletions

View file

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Gradients</title>
<link rel="stylesheet" href="../css/style.css">
<script type="text/javascript" src="../../dist/paper.js"></script>
<script type="text/paperscript" canvas="canvas">
var path = new Path.Circle(view.center, view.bounds.height * 0.4);
var gradient = new Gradient([ new RgbColor(1, 1, 0, 0), 'red', 'black'], 'radial');
var from = path.position;
var to = path.bounds.rightCenter;
var gradientColor = new GradientColor(gradient, from, to);
path.fillColor = gradientColor;
path.strokeColor = 'black';
document.getElementById('svg').appendChild(project.exportSvg());
</script>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<svg id="svg" style="width: 500px; height: 500px"></svg>
</body>
</html>

View file

@ -25,6 +25,8 @@ var Gradient = this.Gradient = Base.extend(/** @lends Gradient# */{
* @param {String} [type='linear'] 'linear' or 'radial' * @param {String} [type='linear'] 'linear' or 'radial'
*/ */
initialize: function(stops, type) { initialize: function(stops, type) {
// Define this Gradient's unique id.
this._id = ++Base._uid;
this.setStops(stops || ['white', 'black']); this.setStops(stops || ['white', 'black']);
this.type = type || 'linear'; this.type = type || 'linear';
}, },

View file

@ -374,19 +374,56 @@ new function() {
return createElement('use', attrs); return createElement('use', attrs);
} }
function exportColor(color) { function exportGradient(color) {
/* // NOTE: As long as the fillTransform attribute is not implemented,
var gradientSvg = getDefinition(symbol) // we need to create a separate gradient object for each gradient,
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="69" y1="239.5" x2="530" y2="239.5"> // even when they share the same gradient defintion.
<stop offset="0" style="stop-color:#231F20"/> // http://www.svgopen.org/2011/papers/20-Separating_gradients_from_geometry/
<stop offset="0.0896" style="stop-color:#231F20;stop-opacity:0.9104"/> // TODO: Implement gradient mergin in SvgImport
<stop offset="1" style="stop-color:#231F20;stop-opacity:0"/> var gradient = color.gradient,
</linearGradient> gradientNode = getDefinition(color);
*/ if (!gradientNode) {
if (color.gradient) { var origin = color._origin,
return null; destination = color._destination,
highlight = color._hilite,
attrs;
if (gradient.type == 'radial') {
attrs = {
cx: origin.x,
cy: origin.y,
r: origin.getDistance(destination)
};
if (highlight) {
attrs.fx = highlight.x;
attrs.fy = highlight.y;
}
} else {
attrs = {
x1: origin.x,
y1: origin.y,
x2: destination.x,
y2: destination.y
};
}
attrs.gradientUnits = 'userSpaceOnUse';
gradientNode = createElement(gradient.type + 'Gradient', attrs);
var stops = gradient._stops;
for (var i = 0, l = stops.length; i < l; i++) {
var stop = stops[i],
color = stop._color,
attrs = {
offset: stop._rampPoint,
'stop-color': color.toCss(true)
};
// See applyStyle for an explanation of why there are separated
// opacity / color attributes.
if (color.getAlpha() < 1)
attrs['stop-opacity'] = color._alpha;
gradientNode.appendChild(createElement('stop', attrs));
}
setDefinition(gradient, gradientNode, 'gradient');
} }
return color.toCss(true); // false for noAlpha, see above return 'url(#' + gradientNode.id + ')';
} }
var exporters = { var exporters = {
@ -417,11 +454,13 @@ new function() {
// separate the alpha value of colors with alpha into the // separate the alpha value of colors with alpha into the
// separate fill- / stroke-opacity attribute: // separate fill- / stroke-opacity attribute:
if (entry.type === 'color' && value != null && value.getAlpha() < 1) if (entry.type === 'color' && value != null && value.getAlpha() < 1)
attrs[entry.attribute + '-opacity'] = value.getAlpha(); attrs[entry.attribute + '-opacity'] = value._alpha;
attrs[entry.attribute] = value == null attrs[entry.attribute] = value == null
? 'none' ? 'none'
: entry.type === 'color' : entry.type === 'color'
? exportColor(value) ? value.gradient
? exportGradient(value)
: value.toCss(true) // false for noAlpha, see above
: entry.type === 'array' : entry.type === 'array'
? value.join(',') ? value.join(',')
: entry.type === 'number' : entry.type === 'number'