mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-06 04:42:15 -05:00
SVGImport: Implement support for gradientUnits="objectBoundingBox"
Relates to #650, but still needs unit tests.
This commit is contained in:
parent
98fc51319f
commit
fce126959d
1 changed files with 41 additions and 16 deletions
|
@ -33,9 +33,12 @@ new function() {
|
||||||
: isString
|
: isString
|
||||||
? value
|
? value
|
||||||
: parseFloat(value);
|
: parseFloat(value);
|
||||||
// Support for dimensions in percentage of the root size:
|
// Support for dimensions in percentage of the root size. If root-size
|
||||||
return rootSize && /%\s*$/.test(value)
|
// is not set (e.g. during <defs>), just scale the percentage value to
|
||||||
? rootSize[/x|^width/.test(name) ? 'width' : 'height'] * res / 100
|
// 0..1, as required by gradients with gradientUnits="objectBoundingBox"
|
||||||
|
return /%\s*$/.test(value)
|
||||||
|
? (res / 100) * (rootSize ? rootSize[
|
||||||
|
/x|^width/.test(name) ? 'width' : 'height'] : 1)
|
||||||
: res;
|
: res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +148,14 @@ new function() {
|
||||||
function importGradient(node, type) {
|
function importGradient(node, type) {
|
||||||
var id = (getValue(node, 'href', true) || '').substring(1),
|
var id = (getValue(node, 'href', true) || '').substring(1),
|
||||||
isRadial = type === 'radialgradient',
|
isRadial = type === 'radialgradient',
|
||||||
gradient;
|
gradient,
|
||||||
|
scaleToBounds = getValue(node, 'gradientUnits', true) !==
|
||||||
|
'userSpaceOnUse';
|
||||||
|
prevSize = rootSize;
|
||||||
|
// Clear rootSize during import so that percentage sizes don't get
|
||||||
|
// scaled yet.
|
||||||
|
if (scaleToBounds)
|
||||||
|
rootSize = null;
|
||||||
if (id) {
|
if (id) {
|
||||||
// Gradients are always wrapped in a Color object, so get the
|
// Gradients are always wrapped in a Color object, so get the
|
||||||
// gradient object from there.
|
// gradient object from there.
|
||||||
|
@ -170,8 +180,11 @@ new function() {
|
||||||
origin = getPoint(node, 'x1', 'y1');
|
origin = getPoint(node, 'x1', 'y1');
|
||||||
destination = getPoint(node, 'x2', 'y2');
|
destination = getPoint(node, 'x2', 'y2');
|
||||||
}
|
}
|
||||||
applyAttributes(
|
var color = applyAttributes(
|
||||||
new Color(gradient, origin, destination, highlight), node);
|
new Color(gradient, origin, destination, highlight), node);
|
||||||
|
// TODO: Consider adding support for _scaleToBounds to Color instead?
|
||||||
|
color._scaleToBounds = scaleToBounds;
|
||||||
|
rootSize = prevSize;
|
||||||
// We don't return the gradient, since we only need a reference to it in
|
// We don't return the gradient, since we only need a reference to it in
|
||||||
// definitions, which is created in applyAttributes()
|
// definitions, which is created in applyAttributes()
|
||||||
return null;
|
return null;
|
||||||
|
@ -270,13 +283,12 @@ new function() {
|
||||||
var id = (getValue(node, 'href', true) || '').substring(1),
|
var id = (getValue(node, 'href', true) || '').substring(1),
|
||||||
definition = definitions[id],
|
definition = definitions[id],
|
||||||
point = getPoint(node);
|
point = getPoint(node);
|
||||||
// Use place if we're dealing with a symbol:
|
|
||||||
return definition
|
return definition
|
||||||
? definition instanceof SymbolDefinition
|
? definition instanceof SymbolDefinition
|
||||||
// When placing symbols, we need to take both point and
|
// When placing symbols, we need to take both point and
|
||||||
// matrix into account. This just does the right thing:
|
// matrix into account. place() does the right thing:
|
||||||
? definition.place(point)
|
? definition.place(point)
|
||||||
// Gradient?
|
// A normal item: Clone and translate it.
|
||||||
: definition.clone().translate(point)
|
: definition.clone().translate(point)
|
||||||
: null;
|
: null;
|
||||||
},
|
},
|
||||||
|
@ -395,15 +407,26 @@ new function() {
|
||||||
var attributes = Base.set(Base.each(SvgStyles, function(entry) {
|
var attributes = Base.set(Base.each(SvgStyles, function(entry) {
|
||||||
this[entry.attribute] = function(item, value) {
|
this[entry.attribute] = function(item, value) {
|
||||||
item[entry.set](convertValue(value, entry.type, entry.fromSVG));
|
item[entry.set](convertValue(value, entry.type, entry.fromSVG));
|
||||||
// When applying gradient colors to shapes, we need to offset
|
if (entry.type === 'color') {
|
||||||
// the shape's initial position to get the same results as SVG.
|
|
||||||
if (entry.type === 'color' && item instanceof Shape) {
|
|
||||||
// Do not use result of convertValue() above, since calling
|
// Do not use result of convertValue() above, since calling
|
||||||
// the setter will produce a new cloned color.
|
// the setter will produce a new cloned color.
|
||||||
var color = item[entry.get]();
|
var color = item[entry.get]();
|
||||||
if (color)
|
if (color) {
|
||||||
color.transform(new Matrix().translate(
|
// Emulate SVG's gradientUnits="objectBoundingBox"
|
||||||
item.getPosition(true).negate()));
|
if (color._scaleToBounds) {
|
||||||
|
var bounds = item.getBounds();
|
||||||
|
color.transform(new Matrix()
|
||||||
|
.translate(bounds.getPoint())
|
||||||
|
.scale(bounds.getSize()));
|
||||||
|
}
|
||||||
|
if (item instanceof Shape) {
|
||||||
|
// When applying gradient colors to shapes, we need to
|
||||||
|
// offset the shape's initial position to get the same
|
||||||
|
// results as SVG.
|
||||||
|
color.transform(new Matrix()
|
||||||
|
.translate(item.getPosition(true).negate()));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}, {}), {
|
}, {}), {
|
||||||
|
@ -562,8 +585,7 @@ new function() {
|
||||||
function onLoadCallback(svg) {
|
function onLoadCallback(svg) {
|
||||||
paper = scope;
|
paper = scope;
|
||||||
var item = importSVG(svg, options, isRoot),
|
var item = importSVG(svg, options, isRoot),
|
||||||
onLoad = options.onLoad,
|
onLoad = options.onLoad;
|
||||||
view = scope.project && scope.getView();
|
|
||||||
if (onLoad)
|
if (onLoad)
|
||||||
onLoad.call(this, item, svg);
|
onLoad.call(this, item, svg);
|
||||||
}
|
}
|
||||||
|
@ -605,6 +627,9 @@ new function() {
|
||||||
data = node.getAttribute && node.getAttribute('data-paper-data'),
|
data = node.getAttribute && node.getAttribute('data-paper-data'),
|
||||||
settings = scope.settings,
|
settings = scope.settings,
|
||||||
applyMatrix = settings.applyMatrix;
|
applyMatrix = settings.applyMatrix;
|
||||||
|
// Set rootSize to the view size in the beginning.
|
||||||
|
if (isRoot)
|
||||||
|
rootSize = scope.getView().getSize();
|
||||||
// Have items imported from SVG not bake in all transformations to their
|
// 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
|
// content and children, as this is how SVG works too, but preserve the
|
||||||
// current setting so we can restore it after.
|
// current setting so we can restore it after.
|
||||||
|
|
Loading…
Reference in a new issue