Support linked gradients.

Closes #441.
This commit is contained in:
Jürg Lehni 2014-04-07 01:18:17 +02:00
parent 46ac9052c8
commit b8f1cfea9f
2 changed files with 168 additions and 14 deletions

View file

@ -0,0 +1,138 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Gradients</title>
<script type="text/javascript" src="../../dist/paper-full.js"></script>
<script type="text/paperscript" canvas="canvas">
var item = project.importSVG(document.getElementById('svg'));
</script>
</head>
<body>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="210mm"
height="297mm"
id="svg">
<defs
id="defs1903">
<linearGradient
id="linearGradient3794">
<stop
id="stop3796"
style="stop-color:#ff5555;stop-opacity:1"
offset="0" />
<stop
id="stop3808"
style="stop-color:#522ba8;stop-opacity:1"
offset="0.18868095" />
<stop
id="stop3802"
style="stop-color:#ff00ff;stop-opacity:1"
offset="0.38376093" />
<stop
id="stop3804"
style="stop-color:#ff6600;stop-opacity:1"
offset="0.57983696" />
<stop
id="stop3806"
style="stop-color:#28170b;stop-opacity:1"
offset="0.80833077" />
<stop
id="stop3798"
style="stop-color:#ff5555;stop-opacity:0"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient3770">
<stop
id="stop3772"
style="stop-color:#d1ab00;stop-opacity:1"
offset="0" />
<stop
id="stop3788"
style="stop-color:#502d16;stop-opacity:1"
offset="0.0625" />
<stop
id="stop3786"
style="stop-color:#ff5555;stop-opacity:1"
offset="0.125" />
<stop
id="stop3784"
style="stop-color:#00ff00;stop-opacity:1"
offset="0.54704088" />
<stop
id="stop3782"
style="stop-color:#ffff00;stop-opacity:1"
offset="0.79772007" />
<stop
id="stop3774"
style="stop-color:#2b1100;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
id="linearGradient3760">
<stop
id="stop3762"
style="stop-color:#ff6600;stop-opacity:1"
offset="0" />
<stop
id="stop3764"
style="stop-color:#2b1100;stop-opacity:1"
offset="1" />
</linearGradient>
<linearGradient
x1="443.22928"
y1="215.30028"
x2="867.58954"
y2="229.58598"
id="linearGradient3768"
xlink:href="#linearGradient3760"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="443.22928"
y1="215.30028"
x2="867.58954"
y2="229.58598"
id="linearGradient3776"
xlink:href="#linearGradient3770"
gradientUnits="userSpaceOnUse" />
<linearGradient
x1="454.28571"
y1="-7.6378121"
x2="591.42859"
y2="480.93362"
id="linearGradient3800"
xlink:href="#linearGradient3794"
gradientUnits="userSpaceOnUse" />
</defs>
<metadata
id="metadata1906">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1">
<path
d="m 325.71425,440.93359 -24.52516,-67.66103 -63.02035,-34.75536 5.11537,-71.78671 -43.43569,-57.38329 33.87141,-63.49982 -16.34058,-70.089121 56.77078,-44.233226 13.57994,-70.675915 69.85396,-17.318309 41.15239,-59.042199 70.85875,12.5911 61.6092,-37.19955 59.61144,40.3234 71.41322,-8.92476 38.05675,61.08341 68.86926,20.893202 9.92171,71.281547 54.41716,47.098539 -19.92888,69.154452 30.55585,65.16011 -46.33359,55.06994 1.41115,71.9549 -64.7268,31.46332 -27.97755,66.30805 -71.92816,2.4164 -52.52867,49.19593 -66.69248,-27.04832 -67.99711,23.57737 -49.92508,-51.83614 z"
transform="translate(-125.71429,194.28571) scale(0.5, 0.5)"
id="path3792"
style="fill:url(#linearGradient3800);fill-opacity:1;stroke;stroke:black;stroke-width:2px;" />
</g>
</svg>
<canvas id="canvas" width="900" height="900"></canvas>
</body>
</html>

View file

@ -79,9 +79,6 @@ new function() {
currentStyle = project._currentStyle,
children = [];
if (!isClip) {
// Have the group not pass on all transformations to its children,
// as this is how SVG works too.
item._applyMatrix = false;
item = applyAttributes(item, node, isRoot);
// Style on items needs to be handled differently than all other
// items: We first apply the style to the item, then use it as the
@ -142,16 +139,25 @@ new function() {
}
function importGradient(node, type) {
var nodes = node.childNodes,
stops = [];
for (var i = 0, l = nodes.length; i < l; i++) {
var child = nodes[i];
if (child.nodeType === 1)
stops.push(applyAttributes(new GradientStop(), child));
var id = (getValue(node, 'href', true) || '').substring(1),
isRadial = type === 'radialgradient',
gradient;
if (id) {
// Gradients are always wrapped in a Color object, so get the
// gradient object from there.
// TODO: Handle exception if there is no definition for this id.
gradient = definitions[id].getGradient();
} else {
var nodes = node.childNodes,
stops = [];
for (var i = 0, l = nodes.length; i < l; i++) {
var child = nodes[i];
if (child.nodeType === 1)
stops.push(applyAttributes(new GradientStop(), child));
}
gradient = new Gradient(stops, isRadial);
}
var isRadial = type === 'radialgradient',
gradient = new Gradient(stops, isRadial),
origin, destination, highlight;
var origin, destination, highlight;
if (isRadial) {
origin = getPoint(node, 'cx', 'cy');
destination = origin.add(getValue(node, 'r'), 0);
@ -538,6 +544,8 @@ new function() {
}
if (isRoot) {
// Have the group not pass on all transformations to its children,
// as this is how SVG works too.
// See if it's a string but handle markup separately
if (typeof source === 'string' && !/^.*</.test(source)) {
/*#*/ if (__options.environment == 'browser') {
@ -571,8 +579,16 @@ new function() {
// jsdom in Node.js uses uppercase values for nodeName...
var type = node.nodeName.toLowerCase(),
importer = importers[type],
item = importer && importer(node, type, isRoot, options) || null,
data = node.getAttribute && node.getAttribute('data-paper-data');
item,
data = node.getAttribute && node.getAttribute('data-paper-data'),
settings = scope.settings,
prevApplyMatrix = settings.applyMatrix;
// Have items imported from SVG not bake in all transformations to their
// content and children, as this is how SVG works too, but preserve the
// current setting so we can restore it after.
settings.applyMatrix = false;
item = importer && importer(node, type, isRoot, options) || null;
settings.applyMatrix = prevApplyMatrix;
if (item) {
// See importGroup() for an explanation of this filtering:
if (!(item instanceof Group))