mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-20 22:39:50 -05:00
Use applyAttribute() lookup table in SvgImport instead of switch statement.
This commit is contained in:
parent
9d8cddbe42
commit
8585556584
2 changed files with 251 additions and 118 deletions
|
@ -69,7 +69,7 @@ new function() {
|
|||
return new Group(clip, item);
|
||||
}
|
||||
|
||||
// Define importer functions for various SVG node types
|
||||
// Importer functions for various SVG node types //
|
||||
|
||||
function importGroup(node, type) {
|
||||
var nodes = node.childNodes,
|
||||
|
@ -292,7 +292,6 @@ new function() {
|
|||
use: function(node, type) {
|
||||
// Note the namespaced xlink:href attribute is just called href
|
||||
// as a property on node.
|
||||
// TODO: Should getValue become namespace aware?
|
||||
var id = (getValue(node, 'href') || '').substring(1),
|
||||
definition = definitions[id];
|
||||
// Use place if we're dealing with a symbol:
|
||||
|
@ -349,6 +348,134 @@ new function() {
|
|||
}
|
||||
};
|
||||
|
||||
// Attributes & Styles //
|
||||
|
||||
function applyTransform(item, node, name, value) {
|
||||
// http://www.w3.org/TR/SVG/types.html#DataTypeTransformList
|
||||
var transforms = node[name].baseVal,
|
||||
matrix = new Matrix();
|
||||
for (var i = 0, l = transforms.numberOfItems; i < l; i++) {
|
||||
var mx = transforms.getItem(i).matrix;
|
||||
matrix.concatenate(
|
||||
new Matrix(mx.a, mx.b, mx.c, mx.d, mx.e, mx.f));
|
||||
}
|
||||
item.transform(matrix);
|
||||
}
|
||||
|
||||
function applyOpacity(item, node, name, value) {
|
||||
// http://www.w3.org/TR/SVG/painting.html#FillOpacityProperty
|
||||
// http://www.w3.org/TR/SVG/painting.html#StrokeOpacityProperty
|
||||
var color = item[name == 'fill-opacity' ? 'getFillColor'
|
||||
: 'getStrokeColor']();
|
||||
if (color)
|
||||
color.setAlpha(parseFloat(value));
|
||||
}
|
||||
|
||||
function applyTextAttribute(item, node, name, value) {
|
||||
if (item instanceof TextItem) {
|
||||
switch (name) {
|
||||
case 'font':
|
||||
// TODO: Verify if there is not another way?
|
||||
var text = document.createElement('span');
|
||||
text.style.font = value;
|
||||
for (var i = 0; i < text.style.length; i++) {
|
||||
var name = text.style[i];
|
||||
item = applyAttribute(item, node, name, text.style[name]);
|
||||
}
|
||||
break;
|
||||
case 'font-family':
|
||||
item.setFont(value.split(',')[0].replace(/^\s+|\s+$/g, ''));
|
||||
break;
|
||||
case 'font-size':
|
||||
item.setFontSize(parseFloat(value));
|
||||
break;
|
||||
case 'text-anchor':
|
||||
// http://www.w3.org/TR/SVG/text.html#TextAnchorProperty
|
||||
item.setJustification({
|
||||
start: 'left',
|
||||
middle: 'center',
|
||||
end: 'right'
|
||||
}[value]);
|
||||
break;
|
||||
}
|
||||
} else if (item instanceof Group) {
|
||||
// Text styles need to be recursively passed down to children that
|
||||
// might be TextItems explicitely.
|
||||
var children = item._children;
|
||||
for (var i = 0, l = children.length; i < l; i++) {
|
||||
applyTextAttribute(children[i], node, name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var attributes = {
|
||||
id: function(item, node, name, value) {
|
||||
definitions[value] = item;
|
||||
if (item.setName)
|
||||
item.setName(value);
|
||||
},
|
||||
|
||||
'clip-path': function(item, node, name, value) {
|
||||
// http://www.w3.org/TR/SVG/masking.html#ClipPathProperty
|
||||
return createClipGroup(item, getDefinition(value).clone().reduce());
|
||||
},
|
||||
|
||||
gradientTransform: applyTransform,
|
||||
transform: applyTransform,
|
||||
|
||||
opacity: function(item, node, name, value) {
|
||||
// http://www.w3.org/TR/SVG/masking.html#OpacityProperty
|
||||
item.setOpacity(parseFloat(value));
|
||||
},
|
||||
|
||||
'fill-opacity': applyOpacity,
|
||||
'stroke-opacity': applyOpacity,
|
||||
|
||||
font: applyTextAttribute,
|
||||
'font-family': applyTextAttribute,
|
||||
'font-size': applyTextAttribute,
|
||||
'text-anchor': applyTextAttribute,
|
||||
|
||||
'stop-opacity': function(item, node, name, value) {
|
||||
// http://www.w3.org/TR/SVG/pservers.html#StopOpacityProperty
|
||||
item.color.setAlpha(parseFloat(value));
|
||||
},
|
||||
|
||||
visibility: function(item, node, name, value) {
|
||||
item.setVisible(value === 'visible');
|
||||
},
|
||||
|
||||
'stop-color': function(item, node, name, value) {
|
||||
// http://www.w3.org/TR/SVG/pservers.html#StopColorProperty
|
||||
item.setColor(value);
|
||||
},
|
||||
|
||||
offset: function(item, node, name, value) {
|
||||
// http://www.w3.org/TR/SVG/pservers.html#StopElementOffsetAttribute
|
||||
var percentage = value.match(/(.*)%$/);
|
||||
item.setRampPoint(percentage ? percentage[1] / 100 : value);
|
||||
},
|
||||
|
||||
viewBox: function(item, node, name, value) {
|
||||
// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
|
||||
// TODO: implement preserveAspectRatio attribute
|
||||
if (item instanceof Symbol)
|
||||
return;
|
||||
var values = convertValue(value, 'array'),
|
||||
rectangle = Rectangle.create.apply(this, values),
|
||||
size = getSize(node, 'width', 'height', true),
|
||||
scale = size ? rectangle.getSize().divide(size) : 1,
|
||||
offset = rectangle.getPoint(),
|
||||
matrix = new Matrix().translate(offset).scale(scale);
|
||||
item.transform(matrix.inverted());
|
||||
if (size)
|
||||
rectangle.setSize(size);
|
||||
rectangle.setPoint(0);
|
||||
// TODO: the viewbox does not always need to be clipped
|
||||
return createClipGroup(item, new Path.Rectangle(rectangle));
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts various SVG styles and attributes into Paper.js styles and
|
||||
* attributes and applies them to the passed item.
|
||||
|
@ -388,127 +515,16 @@ new function() {
|
|||
if (entry) {
|
||||
item._style[entry.set](convertValue(value, entry.type));
|
||||
} else {
|
||||
switch (name) {
|
||||
case 'id':
|
||||
definitions[value] = item;
|
||||
if (item.setName)
|
||||
item.setName(value);
|
||||
break;
|
||||
// http://www.w3.org/TR/SVG/masking.html#ClipPathProperty
|
||||
case 'clip-path':
|
||||
item = createClipGroup(item,
|
||||
getDefinition(value).clone().reduce());
|
||||
break;
|
||||
// http://www.w3.org/TR/SVG/types.html#DataTypeTransformList
|
||||
case 'gradientTransform':
|
||||
case 'transform':
|
||||
var transforms = node[name].baseVal,
|
||||
matrix = new Matrix();
|
||||
for (var i = 0, l = transforms.numberOfItems; i < l; i++) {
|
||||
var mx = transforms.getItem(i).matrix;
|
||||
matrix.concatenate(
|
||||
new Matrix(mx.a, mx.b, mx.c, mx.d, mx.e, mx.f));
|
||||
}
|
||||
item.transform(matrix);
|
||||
break;
|
||||
// http://www.w3.org/TR/SVG/pservers.html#StopOpacityProperty
|
||||
case 'stop-opacity':
|
||||
// http://www.w3.org/TR/SVG/masking.html#OpacityProperty
|
||||
case 'opacity':
|
||||
var opacity = parseFloat(value);
|
||||
if (name === 'stop-opacity') {
|
||||
item.color.setAlpha(opacity);
|
||||
} else {
|
||||
item.setOpacity(opacity);
|
||||
}
|
||||
break;
|
||||
// http://www.w3.org/TR/SVG/painting.html#FillOpacityProperty
|
||||
case 'fill-opacity':
|
||||
// http://www.w3.org/TR/SVG/painting.html#StrokeOpacityProperty
|
||||
case 'stroke-opacity':
|
||||
var color = item[name == 'fill-opacity' ? 'getFillColor'
|
||||
: 'getStrokeColor']();
|
||||
if (color)
|
||||
color.setAlpha(parseFloat(value));
|
||||
break;
|
||||
case 'visibility':
|
||||
item.setVisible(value === 'visible');
|
||||
break;
|
||||
case 'font':
|
||||
case 'font-family':
|
||||
case 'font-size':
|
||||
// http://www.w3.org/TR/SVG/text.html#TextAnchorProperty
|
||||
case 'text-anchor':
|
||||
applyTextAttribute(item, node, name, value);
|
||||
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
|
||||
case 'offset':
|
||||
var percentage = value.match(/(.*)%$/);
|
||||
item.setRampPoint(percentage ? percentage[1] / 100 : value);
|
||||
break;
|
||||
// http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute
|
||||
// TODO: implement preserveAspectRatio attribute
|
||||
case 'viewBox':
|
||||
if (item instanceof Symbol)
|
||||
break;
|
||||
var values = convertValue(value, 'array'),
|
||||
rectangle = Rectangle.create.apply(this, values),
|
||||
size = getSize(node, 'width', 'height', true),
|
||||
scale = size ? rectangle.getSize().divide(size) : 1,
|
||||
offset = rectangle.getPoint(),
|
||||
matrix = new Matrix().translate(offset).scale(scale);
|
||||
item.transform(matrix.inverted());
|
||||
if (size)
|
||||
rectangle.setSize(size);
|
||||
rectangle.setPoint(0);
|
||||
// TODO: the viewbox does not always need to be clipped
|
||||
item = createClipGroup(item, new Path.Rectangle(rectangle));
|
||||
break;
|
||||
var attribute = attributes[name];
|
||||
if (attribute) {
|
||||
var res = attribute(item, node, name, value);
|
||||
if (res !== undefined)
|
||||
item = res;
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
function applyTextAttribute(item, node, name, value) {
|
||||
if (item instanceof TextItem) {
|
||||
switch (name) {
|
||||
case 'font':
|
||||
// TODO: Verify if there is not another way?
|
||||
var text = document.createElement('span');
|
||||
text.style.font = value;
|
||||
for (var i = 0; i < text.style.length; i++) {
|
||||
var name = text.style[i];
|
||||
item = applyAttribute(item, node, name, text.style[name]);
|
||||
}
|
||||
break;
|
||||
case 'font-family':
|
||||
item.setFont(value.split(',')[0].replace(/^\s+|\s+$/g, ''));
|
||||
break;
|
||||
case 'font-size':
|
||||
item.setFontSize(parseFloat(value));
|
||||
break;
|
||||
case 'text-anchor':
|
||||
item.setJustification({
|
||||
start: 'left',
|
||||
middle: 'center',
|
||||
end: 'right'
|
||||
}[value]);
|
||||
break;
|
||||
}
|
||||
} else if (item instanceof Group) {
|
||||
// Text styles need to be recursively passed down to children that
|
||||
// might be TextItems explicitely.
|
||||
var children = item._children;
|
||||
for (var i = 0, l = children.length; i < l; i++) {
|
||||
applyTextAttribute(children[i], node, name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var definitions = {};
|
||||
function getDefinition(value) {
|
||||
var match = value.match(/\(#([^)']+)/);
|
||||
|
|
117
src/svg/svg-styles.txt
Normal file
117
src/svg/svg-styles.txt
Normal file
|
@ -0,0 +1,117 @@
|
|||
Attributes currently in use:
|
||||
|
||||
gradientTransform
|
||||
viewBox
|
||||
offset
|
||||
|
||||
Stlyes currently in use:
|
||||
|
||||
clip-path
|
||||
transform
|
||||
stop-opacity
|
||||
opacity
|
||||
fill-opacity
|
||||
stroke-opacity
|
||||
visibility
|
||||
font
|
||||
font-family
|
||||
font-size
|
||||
text-anchor
|
||||
stop-color
|
||||
|
||||
fill
|
||||
stroke
|
||||
stroke-width
|
||||
stroke-linecap
|
||||
stroke-linejoin
|
||||
stroke-miterlimit
|
||||
stroke-dasharray
|
||||
stroke-dashoffset
|
||||
|
||||
Font properties:
|
||||
|
||||
√ font
|
||||
√ font-family
|
||||
√ font-size
|
||||
font-size-adjust
|
||||
font-stretch
|
||||
font-style
|
||||
font-variant
|
||||
font-weight
|
||||
|
||||
Text properties:
|
||||
|
||||
direction
|
||||
letter-spacing
|
||||
text-decoration
|
||||
unicode-bidi
|
||||
word-spacing
|
||||
|
||||
Other properties for visual media:
|
||||
|
||||
clip - only applicable to outermost svg element.
|
||||
color - used to provide a potential indirect value (currentColor) for the fill, stroke, stop-color, flood-color and lighting-color properties. (The SVG properties which support color allow a color specification which is extended from CSS2 to accommodate color definitions in arbitrary color spaces. See Color profile descriptions.)
|
||||
cursor
|
||||
display
|
||||
overflow - only applicable to elements which establish a new viewport.
|
||||
√ visibility
|
||||
|
||||
Clipping, Masking and Compositing properties:
|
||||
|
||||
√ clip-path
|
||||
clip-rule
|
||||
mask
|
||||
opacity
|
||||
|
||||
Filter Effects properties:
|
||||
|
||||
enable-background
|
||||
filter
|
||||
flood-color
|
||||
flood-opacity
|
||||
lighting-color
|
||||
|
||||
Gradient properties:
|
||||
|
||||
√ stop-color
|
||||
√ stop-opacity
|
||||
|
||||
Interactivity properties:
|
||||
|
||||
pointer-events
|
||||
|
||||
Color and Painting properties:
|
||||
|
||||
color-interpolation
|
||||
color-interpolation-filters
|
||||
color-profile
|
||||
color-rendering
|
||||
√ fill
|
||||
√ fill-opacity
|
||||
fill-rule
|
||||
image-rendering
|
||||
marker
|
||||
marker-end
|
||||
marker-mid
|
||||
marker-start
|
||||
shape-rendering
|
||||
√ stroke
|
||||
√ stroke-dasharray
|
||||
√ stroke-dashoffset
|
||||
√ stroke-linecap
|
||||
√ stroke-linejoin
|
||||
√ stroke-miterlimit
|
||||
√ stroke-opacity
|
||||
√ stroke-width
|
||||
text-rendering
|
||||
|
||||
Text properties:
|
||||
|
||||
alignment-baseline
|
||||
baseline-shift
|
||||
dominant-baseline
|
||||
glyph-orientation-horizontal
|
||||
glyph-orientation-vertical
|
||||
kerning
|
||||
√ text-anchor
|
||||
writing-mode
|
Loading…
Reference in a new issue