Bump version to v0.9.11

This commit is contained in:
Jürg Lehni 2013-11-02 21:29:09 +01:00
parent af1c6830e0
commit 5bb3482073
8 changed files with 1138 additions and 747 deletions

View file

@ -1,6 +1,6 @@
{ {
"name": "paper", "name": "paper",
"version": "0.9.9", "version": "0.9.11",
"main": "dist/paper.js", "main": "dist/paper.js",
"ignore": [ "ignore": [
"build", "build",

472
dist/paper-core.js vendored
View file

@ -1,5 +1,5 @@
/*! /*!
* Paper.js v0.9.10 - The Swiss Army Knife of Vector Graphics Scripting. * Paper.js v0.9.11 - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/ * http://paperjs.org/
* *
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey * Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
@ -9,7 +9,7 @@
* *
* All rights reserved. * All rights reserved.
* *
* Date: Tue Oct 29 21:56:00 2013 +0100 * Date: Sat Nov 2 21:26:32 2013 +0100
* *
*** ***
* *
@ -466,31 +466,33 @@ Base.inject({
: res; : res;
}, },
deserialize: function(obj, data) { deserialize: function(json, target, _data) {
var res = obj; var res = json;
data = data || {}; _data = _data || {};
if (Array.isArray(obj)) { if (Array.isArray(json)) {
var type = obj[0], var type = json[0],
isDictionary = type === 'dictionary'; isDictionary = type === 'dictionary';
if (!isDictionary) { if (!isDictionary) {
if (data.dictionary && obj.length == 1 && /^#/.test(type)) if (_data.dictionary && json.length == 1 && /^#/.test(type))
return data.dictionary[type]; return _data.dictionary[type];
type = Base.exports[type]; type = Base.exports[type];
} }
res = []; res = [];
for (var i = type ? 1 : 0, l = obj.length; i < l; i++) for (var i = type ? 1 : 0, l = json.length; i < l; i++)
res.push(Base.deserialize(obj[i], data)); res.push(Base.deserialize(json[i], null, _data));
if (isDictionary) { if (isDictionary) {
data.dictionary = res[0]; _data.dictionary = res[0];
} else if (type) { } else if (type) {
var args = res; var args = res;
res = Base.create(type.prototype); res = target instanceof type
? target
: Base.create(type.prototype);
type.apply(res, args); type.apply(res, args);
} }
} else if (Base.isPlainObject(obj)) { } else if (Base.isPlainObject(json)) {
res = {}; res = {};
for (var key in obj) for (var key in json)
res[key] = Base.deserialize(obj[key], data); res[key] = Base.deserialize(json[key], null, _data);
} }
return res; return res;
}, },
@ -499,9 +501,9 @@ Base.inject({
return JSON.stringify(Base.serialize(obj, options)); return JSON.stringify(Base.serialize(obj, options));
}, },
importJSON: function(json) { importJSON: function(json, target) {
return Base.deserialize( return Base.deserialize(
typeof json === 'string' ? JSON.parse(json) : json); typeof json === 'string' ? JSON.parse(json) : json, target);
}, },
splice: function(list, items, index, remove) { splice: function(list, items, index, remove) {
@ -682,7 +684,7 @@ var PaperScope = Base.extend({
} }
}, },
version: '0.9.10', version: '0.9.11',
getView: function() { getView: function() {
return this.project && this.project.view; return this.project && this.project.view;
@ -694,6 +696,10 @@ var PaperScope = Base.extend({
return this._tool; return this._tool;
}, },
getPaper: function() {
return this;
},
evaluate: function(code) { evaluate: function(code) {
var res = paper.PaperScript.evaluate(code, this); var res = paper.PaperScript.evaluate(code, this);
View.updateFocus(); View.updateFocus();
@ -2009,10 +2015,10 @@ var Matrix = Base.extend({
return !this._getDeterminant(); return !this._getDeterminant();
}, },
transform: function( src, srcOff, dst, dstOff, numPts) { transform: function( src, srcOffset, dst, dstOffset, count) {
return arguments.length < 5 return arguments.length < 5
? this._transformPoint(Point.read(arguments)) ? this._transformPoint(Point.read(arguments))
: this._transformCoordinates(src, srcOff, dst, dstOff, numPts); : this._transformCoordinates(src, srcOffset, dst, dstOffset, count);
}, },
_transformPoint: function(point, dest, dontNotify) { _transformPoint: function(point, dest, dontNotify) {
@ -2027,10 +2033,11 @@ var Matrix = Base.extend({
); );
}, },
_transformCoordinates: function(src, srcOff, dst, dstOff, numPts) { _transformCoordinates: function(src, srcOffset, dst, dstOffset, count) {
var i = srcOff, j = dstOff, var i = srcOffset,
srcEnd = srcOff + 2 * numPts; j = dstOffset,
while (i < srcEnd) { max = i + 2 * count;
while (i < max) {
var x = src[i++], var x = src[i++],
y = src[i++]; y = src[i++];
dst[j++] = x * this._a + y * this._b + this._tx; dst[j++] = x * this._a + y * this._b + this._tx;
@ -2736,6 +2743,10 @@ var Item = Base.extend(Callback, {
hasStroke: function() { hasStroke: function() {
return this.getStyle().hasStroke(); return this.getStyle().hasStroke();
},
hasShadow: function() {
return this.getStyle().hasShadow();
} }
}, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'], }, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'],
function(name) { function(name) {
@ -3251,7 +3262,10 @@ var Item = Base.extend(Callback, {
}, { }, {
importJSON: function(json) { importJSON: function(json) {
return this.addChild(Base.importJSON(json)); var res = Base.importJSON(json, this);
return res !== this
? this.addChild(res)
: res;
}, },
addChild: function(item, _preserve) { addChild: function(item, _preserve) {
@ -3387,6 +3401,8 @@ var Item = Base.extend(Callback, {
return removed; return removed;
}, },
clear: '#removeChildren',
reverseChildren: function() { reverseChildren: function() {
if (this._children) { if (this._children) {
this._children.reverse(); this._children.reverse();
@ -3561,43 +3577,49 @@ var Item = Base.extend(Callback, {
_setStyles: function(ctx) { _setStyles: function(ctx) {
var style = this._style, var style = this._style,
matrix = this._matrix,
strokeWidth = style.getStrokeWidth(),
fillColor = style.getFillColor(), fillColor = style.getFillColor(),
strokeColor = style.getStrokeColor(), strokeColor = style.getStrokeColor(),
shadowColor = style.getShadowColor(); shadowColor = style.getShadowColor();
if (fillColor) if (fillColor)
ctx.fillStyle = fillColor.toCanvasStyle(ctx, matrix); ctx.fillStyle = fillColor.toCanvasStyle(ctx);
if (strokeColor && strokeWidth > 0) { if (strokeColor) {
ctx.strokeStyle = strokeColor.toCanvasStyle(ctx, matrix); var strokeWidth = style.getStrokeWidth();
ctx.lineWidth = strokeWidth; if (strokeWidth > 0) {
var strokeJoin = style.getStrokeJoin(), ctx.strokeStyle = strokeColor.toCanvasStyle(ctx);
strokeCap = style.getStrokeCap(), ctx.lineWidth = strokeWidth;
miterLimit = style.getMiterLimit(), var strokeJoin = style.getStrokeJoin(),
dashArray = style.getDashArray(), strokeCap = style.getStrokeCap(),
dashOffset = style.getDashOffset(); miterLimit = style.getMiterLimit();
if (strokeJoin) if (strokeJoin)
ctx.lineJoin = strokeJoin; ctx.lineJoin = strokeJoin;
if (strokeCap) if (strokeCap)
ctx.lineCap = strokeCap; ctx.lineCap = strokeCap;
if (miterLimit) if (miterLimit)
ctx.miterLimit = miterLimit; ctx.miterLimit = miterLimit;
if (paper.support.nativeDash && dashArray && dashArray.length) { if (paper.support.nativeDash) {
if ('setLineDash' in ctx) { var dashArray = style.getDashArray(),
ctx.setLineDash(dashArray); dashOffset = style.getDashOffset();
ctx.lineDashOffset = dashOffset; if (dashArray && dashArray.length) {
} else { if ('setLineDash' in ctx) {
ctx.mozDash = dashArray; ctx.setLineDash(dashArray);
ctx.mozDashOffset = dashOffset; ctx.lineDashOffset = dashOffset;
} else {
ctx.mozDash = dashArray;
ctx.mozDashOffset = dashOffset;
}
}
} }
} }
} }
if (shadowColor) { if (shadowColor) {
ctx.shadowColor = shadowColor.toCanvasStyle(ctx); var shadowBlur = style.getShadowBlur();
ctx.shadowBlur = style.getShadowBlur(); if (shadowBlur > 0) {
var offset = this.getShadowOffset(); ctx.shadowColor = shadowColor.toCanvasStyle(ctx);
ctx.shadowOffsetX = offset.x; ctx.shadowBlur = shadowBlur;
ctx.shadowOffsetY = offset.y; var offset = this.getShadowOffset();
ctx.shadowOffsetX = offset.x;
ctx.shadowOffsetY = offset.y;
}
} }
}, },
@ -3894,8 +3916,8 @@ var Shape = Item.extend({
radius: this._radius, radius: this._radius,
insert: false insert: false
}); });
path.transform(this._matrix);
path.setStyle(this._style); path.setStyle(this._style);
path.transform(this._matrix);
if (insert || insert === undefined) if (insert || insert === undefined)
path.insertAbove(this); path.insertAbove(this);
return path; return path;
@ -3951,8 +3973,10 @@ var Shape = Item.extend({
} }
if (!clip && (hasFill || hasStroke)) { if (!clip && (hasFill || hasStroke)) {
this._setStyles(ctx); this._setStyles(ctx);
if (hasFill) if (hasFill) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (hasStroke) if (hasStroke)
ctx.stroke(); ctx.stroke();
} }
@ -5912,7 +5936,7 @@ var PathItem = Item.extend({
setPathData: function(data) { setPathData: function(data) {
var parts = data.match(/[a-z][^a-z]*/ig), var parts = data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig),
coords, coords,
relative = false, relative = false,
control, control,
@ -5934,18 +5958,15 @@ var PathItem = Item.extend({
); );
} }
if (this._type === 'path') this.clear();
this.removeSegments();
else
this.removeChildren();
for (var i = 0, l = parts.length; i < l; i++) { for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i], var part = parts[i],
cmd = part[0], cmd = part[0],
lower = cmd.toLowerCase(); lower = cmd.toLowerCase();
coords = part.slice(1).trim().split(/[\s,]+|(?=[+-])/); coords = part.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g);
var length = coords && coords.length;
relative = cmd === lower; relative = cmd === lower;
var length = coords.length;
switch (lower) { switch (lower) {
case 'm': case 'm':
case 'l': case 'l':
@ -6304,6 +6325,8 @@ var Path = PathItem.extend({
return removed; return removed;
}, },
clear: '#removeSegments',
isFullySelected: function() { isFullySelected: function() {
var length = this._segments.length; var length = this._segments.length;
return this._selected && length > 0 && this._selectedSegmentState return this._selected && length > 0 && this._selectedSegmentState
@ -6899,8 +6922,10 @@ var Path = PathItem.extend({
if (!clip && !compound && (hasFill || hasStroke)) { if (!clip && !compound && (hasFill || hasStroke)) {
this._setStyles(ctx); this._setStyles(ctx);
if (hasFill) if (hasFill) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (hasStroke) { if (hasStroke) {
if (dashLength) { if (dashLength) {
ctx.beginPath(); ctx.beginPath();
@ -7057,16 +7082,16 @@ var Path = PathItem.extend({
cubicCurveTo: function() { cubicCurveTo: function() {
var handle1 = Point.read(arguments), var handle1 = Point.read(arguments),
handle2 = Point.read(arguments), handle2 = Point.read(arguments),
to = Point.read(arguments); to = Point.read(arguments),
var current = getCurrentSegment(this); current = getCurrentSegment(this);
current.setHandleOut(handle1.subtract(current._point)); current.setHandleOut(handle1.subtract(current._point));
this._add([ new Segment(to, handle2.subtract(to)) ]); this._add([ new Segment(to, handle2.subtract(to)) ]);
}, },
quadraticCurveTo: function() { quadraticCurveTo: function() {
var handle = Point.read(arguments), var handle = Point.read(arguments),
to = Point.read(arguments); to = Point.read(arguments),
var current = getCurrentSegment(this)._point; current = getCurrentSegment(this)._point;
this.cubicCurveTo( this.cubicCurveTo(
handle.add(current.subtract(handle).multiply(1 / 3)), handle.add(current.subtract(handle).multiply(1 / 3)),
handle.add(to.subtract(handle).multiply(1 / 3)), handle.add(to.subtract(handle).multiply(1 / 3)),
@ -7145,25 +7170,41 @@ var Path = PathItem.extend({
this._add(segments); this._add(segments);
}, },
lineBy: function(vector) { lineBy: function() {
vector = Point.read(arguments); var to = Point.read(arguments),
var current = getCurrentSegment(this); current = getCurrentSegment(this)._point;
this.lineTo(current._point.add(vector)); this.lineTo(current.add(to));
}, },
curveBy: function(throughVector, toVector, parameter) { curveBy: function() {
throughVector = Point.read(throughVector); var through = Point.read(arguments),
toVector = Point.read(toVector); to = Point.read(arguments),
var current = getCurrentSegment(this)._point; parameter = Base.read(arguments),
this.curveTo(current.add(throughVector), current.add(toVector), current = getCurrentSegment(this)._point;
parameter); this.curveTo(current.add(through), current.add(to), parameter);
}, },
arcBy: function(throughVector, toVector) { cubicCurveBy: function() {
throughVector = Point.read(throughVector); var handle1 = Point.read(arguments),
toVector = Point.read(toVector); handle2 = Point.read(arguments),
var current = getCurrentSegment(this)._point; to = Point.read(arguments),
this.arcTo(current.add(throughVector), current.add(toVector)); current = getCurrentSegment(this)._point;
this.cubicCurveTo(current.add(handle1), current.add(handle2),
current.add(to));
},
quadraticCurveBy: function() {
var handle = Point.read(arguments),
to = Point.read(arguments),
current = getCurrentSegment(this)._point;
this.quadraticCurveTo(current.add(handle), current.add(to));
},
arcBy: function() {
var through = Point.read(arguments),
to = Point.read(arguments),
current = getCurrentSegment(this)._point;
this.arcTo(current.add(through), current.add(to));
}, },
closePath: function() { closePath: function() {
@ -7644,8 +7685,10 @@ var CompoundPath = PathItem.extend({
if (!param.clip) { if (!param.clip) {
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style; var style = this._style;
if (style.hasFill()) if (style.hasFill()) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (style.hasStroke()) if (style.hasStroke())
ctx.stroke(); ctx.stroke();
} }
@ -7674,13 +7717,15 @@ var CompoundPath = PathItem.extend({
} }
}; };
Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', 'arcTo',
'arcTo', 'lineBy', 'curveBy', 'arcBy'], function(key) { 'lineBy', 'cubicCurveBy', 'quadraticCurveBy', 'curveBy', 'arcBy'],
fields[key] = function() { function(key) {
var path = getCurrentPath(this); fields[key] = function() {
path[key].apply(path, arguments); var path = getCurrentPath(this);
}; path[key].apply(path, arguments);
}); };
}
);
return fields; return fields;
}); });
@ -8212,13 +8257,18 @@ var PointText = TextItem.extend({
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style, var style = this._style,
lines = this._lines, lines = this._lines,
leading = style.getLeading(); leading = style.getLeading(),
shadowColor = ctx.shadowColor;
ctx.font = style.getFontStyle(); ctx.font = style.getFontStyle();
ctx.textAlign = style.getJustification(); ctx.textAlign = style.getJustification();
for (var i = 0, l = lines.length; i < l; i++) { for (var i = 0, l = lines.length; i < l; i++) {
ctx.shadowColor = shadowColor;
var line = lines[i]; var line = lines[i];
if (style.hasFill()) if (style.hasFill()) {
ctx.fillText(line, 0, 0); ctx.fillText(line, 0, 0);
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (style.hasStroke()) if (style.hasStroke())
ctx.strokeText(line, 0, 0); ctx.strokeText(line, 0, 0);
ctx.translate(0, leading); ctx.translate(0, leading);
@ -8597,7 +8647,7 @@ var Color = Base.extend(new function() {
}, },
clone: function() { clone: function() {
return new Color(this._type, this._components.slice(), this._alpha); return new Color(this);
}, },
_convert: function(type) { _convert: function(type) {
@ -8685,23 +8735,21 @@ var Color = Base.extend(new function() {
+ components.join(',') + ')'; + components.join(',') + ')';
}, },
toCanvasStyle: function(ctx, matrix) { toCanvasStyle: function(ctx) {
if (this._canvasStyle) if (this._canvasStyle)
return this._canvasStyle; return this._canvasStyle;
if (this._type !== 'gradient') if (this._type !== 'gradient')
return this._canvasStyle = this.toCSS(); return this._canvasStyle = this.toCSS();
var components = this._components, var components = this._components,
translation = matrix ? matrix.getTranslation() : new Point(),
gradient = components[0], gradient = components[0],
stops = gradient._stops, stops = gradient._stops,
origin = components[1].subtract(translation), origin = components[1],
destination = components[2].subtract(translation), destination = components[2],
canvasGradient; canvasGradient;
if (gradient._radial) { if (gradient._radial) {
var radius = destination.getDistance(origin), var radius = destination.getDistance(origin),
highlight = components[3]; highlight = components[3];
if (highlight) { if (highlight) {
highlight = highlight.subtract(translation);
var vector = highlight.subtract(origin); var vector = highlight.subtract(origin);
if (vector.getLength() > radius) if (vector.getLength() > radius)
highlight = origin.add(vector.normalize(radius - 0.1)); highlight = origin.add(vector.normalize(radius - 0.1));
@ -9027,8 +9075,11 @@ var Style = Base.extend(new function() {
if (isColor) { if (isColor) {
if (old) if (old)
delete old._owner; delete old._owner;
if (value && value.constructor === Color) if (value && value.constructor === Color) {
if (value._owner)
value = value.clone();
value._owner = this._item; value._owner = this._item;
}
} }
this._values[key] = value; this._values[key] = value;
if (this._item) if (this._item)
@ -9118,6 +9169,10 @@ var Style = Base.extend(new function() {
return !!this.getStrokeColor() && this.getStrokeWidth() > 0; return !!this.getStrokeColor() && this.getStrokeWidth() > 0;
}, },
hasShadow: function() {
return !!this.getShadowColor() && this.getShadowBlur() > 0;
},
getLeading: function getLeading() { getLeading: function getLeading() {
var leading = getLeading.base.call(this); var leading = getLeading.base.call(this);
return leading != null ? leading : this.getFontSize() * 1.2; return leading != null ? leading : this.getFontSize() * 1.2;
@ -9377,18 +9432,10 @@ var DomEvent = {
}; };
DomEvent.requestAnimationFrame = new function() { DomEvent.requestAnimationFrame = new function() {
var part = 'equestAnimationFrame', var nativeRequest = DomElement.getPrefixValue(window,
request = window['r' + part] || window['webkitR' + part] 'requestAnimationFrame'),
|| window['mozR' + part] || window['oR' + part] requested = false,
|| window['msR' + part]; callbacks = [],
if (request) {
request(function(time) {
if (time == null)
request = null;
});
}
var callbacks = [],
focused = true, focused = true,
timer; timer;
@ -9401,24 +9448,36 @@ DomEvent.requestAnimationFrame = new function() {
} }
}); });
return function(callback, element) { function handleCallbacks() {
if (request) for (var i = callbacks.length - 1; i >= 0; i--) {
return request(callback, element); var entry = callbacks[i],
callbacks.push([callback, element]); func = entry[0],
if (timer) el = entry[1];
return; if (!el || (PaperScope.getAttribute(el, 'keepalive') == 'true'
timer = setInterval(function() { || focused) && DomElement.isInView(el)) {
for (var i = callbacks.length - 1; i >= 0; i--) { callbacks.splice(i, 1);
var entry = callbacks[i], func();
func = entry[0],
el = entry[1];
if (!el || (PaperScope.getAttribute(el, 'keepalive') == 'true'
|| focused) && DomElement.isInView(el)) {
callbacks.splice(i, 1);
func(Date.now());
}
} }
}, 1000 / 60); }
if (nativeRequest) {
if (callbacks.length) {
nativeRequest(handleCallbacks);
} else {
requested = false;
}
}
}
return function(callback, element) {
callbacks.push([callback, element]);
if (nativeRequest) {
if (!requested) {
nativeRequest(handleCallbacks);
requested = true;
}
} else if (!timer) {
timer = setInterval(handleCallbacks, 1000 / 60);
}
}; };
}; };
@ -10005,6 +10064,7 @@ var Key = new function() {
tool = scope && scope._tool; tool = scope && scope._tool;
keyMap[key] = down; keyMap[key] = down;
if (tool && tool.responds(type)) { if (tool && tool.responds(type)) {
paper = scope;
tool.fire(type, new KeyEvent(down, key, character, event)); tool.fire(type, new KeyEvent(down, key, character, event));
if (view) if (view)
view.draw(true); view.draw(true);
@ -10327,6 +10387,28 @@ var Tool = PaperScopeItem.extend({
}); });
var Http = {
request: function(method, url, callback) {
var xhr = new (window.ActiveXObject || XMLHttpRequest)(
'Microsoft.XMLHTTP');
xhr.open(method.toUpperCase(), url, true);
if ('overrideMimeType' in xhr)
xhr.overrideMimeType('text/plain');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
var status = xhr.status;
if (status === 0 || status === 200) {
callback.call(xhr, xhr.responseText);
} else {
throw new Error('Could not load ' + url + ' (Error '
+ status + ')');
}
}
};
return xhr.send(null);
}
};
var CanvasProvider = { var CanvasProvider = {
canvases: [], canvases: [],
@ -10702,13 +10784,13 @@ new function() {
return attrs; return attrs;
} }
function exportGroup(item) { function exportGroup(item, options) {
var attrs = getTransform(item), var attrs = getTransform(item),
children = item._children; children = item._children;
var node = createElement('g', attrs); var node = createElement('g', attrs);
for (var i = 0, l = children.length; i < l; i++) { for (var i = 0, l = children.length; i < l; i++) {
var child = children[i]; var child = children[i];
var childNode = exportSVG(child); var childNode = exportSVG(child, options);
if (childNode) { if (childNode) {
if (child.isClipMask()) { if (child.isClipMask()) {
var clip = createElement('clipPath'); var clip = createElement('clipPath');
@ -10736,7 +10818,12 @@ new function() {
return createElement('image', attrs); return createElement('image', attrs);
} }
function exportPath(item) { function exportPath(item, options) {
if (options.matchShapes) {
var shape = item.toShape(false);
if (shape)
return exportShape(shape, options);
}
var segments = item._segments, var segments = item._segments,
type, type,
attrs; attrs;
@ -10772,7 +10859,6 @@ new function() {
function exportShape(item) { function exportShape(item) {
var shape = item._shape, var shape = item._shape,
center = item.getPosition(true),
radius = item._radius, radius = item._radius,
attrs = getTransform(item, true, shape !== 'rectangle'); attrs = getTransform(item, true, shape !== 'rectangle');
if (shape === 'rectangle') { if (shape === 'rectangle') {
@ -10806,7 +10892,7 @@ new function() {
return createElement('path', attrs); return createElement('path', attrs);
} }
function exportPlacedSymbol(item) { function exportPlacedSymbol(item, options) {
var attrs = getTransform(item, true), var attrs = getTransform(item, true),
symbol = item.getSymbol(), symbol = item.getSymbol(),
symbolNode = getDefinition(symbol, 'symbol'), symbolNode = getDefinition(symbol, 'symbol'),
@ -10816,7 +10902,7 @@ new function() {
symbolNode = createElement('symbol', { symbolNode = createElement('symbol', {
viewBox: formatter.rectangle(bounds) viewBox: formatter.rectangle(bounds)
}); });
symbolNode.appendChild(exportSVG(definition)); symbolNode.appendChild(exportSVG(definition, options));
setDefinition(symbol, symbolNode, 'symbol'); setDefinition(symbol, symbolNode, 'symbol');
} }
attrs.href = '#' + symbolNode.id; attrs.href = '#' + symbolNode.id;
@ -10827,7 +10913,7 @@ new function() {
return createElement('use', attrs); return createElement('use', attrs);
} }
function exportGradient(color, item) { function exportGradient(color) {
var gradientNode = getDefinition(color, 'color'); var gradientNode = getDefinition(color, 'color');
if (!gradientNode) { if (!gradientNode) {
var gradient = color.getGradient(), var gradient = color.getGradient(),
@ -10951,29 +11037,31 @@ new function() {
} }
function exportDefinitions(node, options) { function exportDefinitions(node, options) {
if (!definitions) var svg = node,
return node;
var svg = node.nodeName.toLowerCase() === 'svg' && node,
defs = null; defs = null;
for (var i in definitions.svgs) { if (definitions) {
if (!defs) { svg = node.nodeName.toLowerCase() === 'svg' && node;
if (!svg) { for (var i in definitions.svgs) {
svg = createElement('svg'); if (!defs) {
svg.appendChild(node); if (!svg) {
svg = createElement('svg');
svg.appendChild(node);
}
defs = svg.insertBefore(createElement('defs'),
svg.firstChild);
} }
defs = svg.insertBefore(createElement('defs'), svg.firstChild); defs.appendChild(definitions.svgs[i]);
} }
defs.appendChild(definitions.svgs[i]); definitions = null;
} }
definitions = null;
return options.asString return options.asString
? new XMLSerializer().serializeToString(svg) ? new XMLSerializer().serializeToString(svg)
: svg; : svg;
} }
function exportSVG(item) { function exportSVG(item, options) {
var exporter = exporters[item._type], var exporter = exporters[item._type],
node = exporter && exporter(item, item._type); node = exporter && exporter(item, options);
if (node && item._data) if (node && item._data)
node.setAttribute('data-paper-data', JSON.stringify(item._data)); node.setAttribute('data-paper-data', JSON.stringify(item._data));
return node && applyStyle(item, node); return node && applyStyle(item, node);
@ -10989,7 +11077,7 @@ new function() {
Item.inject({ Item.inject({
exportSVG: function(options) { exportSVG: function(options) {
options = setOptions(options); options = setOptions(options);
return exportDefinitions(exportSVG(this), options); return exportDefinitions(exportSVG(this, options), options);
} }
}); });
@ -11008,7 +11096,7 @@ new function() {
'xmlns:xlink': 'http://www.w3.org/1999/xlink' 'xmlns:xlink': 'http://www.w3.org/1999/xlink'
}); });
for (var i = 0, l = layers.length; i < l; i++) for (var i = 0, l = layers.length; i < l; i++)
node.appendChild(exportSVG(layers[i])); node.appendChild(exportSVG(layers[i], options));
return exportDefinitions(node, options); return exportDefinitions(node, options);
} }
}); });
@ -11037,15 +11125,15 @@ new function() {
function getPoint(node, x, y, allowNull) { function getPoint(node, x, y, allowNull) {
x = getValue(node, x, false, allowNull); x = getValue(node, x, false, allowNull);
y = getValue(node, y, false, allowNull); y = getValue(node, y, false, allowNull);
return allowNull && x == null && y == null ? null return allowNull && (x == null || y == null) ? null
: new Point(x || 0, y || 0); : new Point(x, y);
} }
function getSize(node, w, h, allowNull) { function getSize(node, w, h, allowNull) {
w = getValue(node, w, false, allowNull); w = getValue(node, w, false, allowNull);
h = getValue(node, h, false, allowNull); h = getValue(node, h, false, allowNull);
return allowNull && w == null && h == null ? null return allowNull && (w == null || h == null) ? null
: new Size(w || 0, h || 0); : new Size(w, h);
} }
function convertValue(value, type, lookup) { function convertValue(value, type, lookup) {
@ -11062,7 +11150,7 @@ new function() {
: value; : value;
} }
function importGroup(node, type, options) { function importGroup(node, type, isRoot, options) {
var nodes = node.childNodes, var nodes = node.childNodes,
clip = type === 'clippath', clip = type === 'clippath',
item = new Group(), item = new Group(),
@ -11071,20 +11159,20 @@ new function() {
children = []; children = [];
if (!clip) { if (!clip) {
item._transformContent = false; item._transformContent = false;
item = applyAttributes(item, node); item = applyAttributes(item, node, isRoot);
project._currentStyle = item._style.clone(); project._currentStyle = item._style.clone();
} }
for (var i = 0, l = nodes.length; i < l; i++) { for (var i = 0, l = nodes.length; i < l; i++) {
var childNode = nodes[i], var childNode = nodes[i],
child; child;
if (childNode.nodeType === 1 if (childNode.nodeType === 1
&& (child = importSVG(childNode, options)) && (child = importSVG(childNode, false, options))
&& !(child instanceof Symbol)) && !(child instanceof Symbol))
children.push(child); children.push(child);
} }
item.addChildren(children); item.addChildren(children);
if (clip) if (clip)
item = applyAttributes(item.reduce(), node); item = applyAttributes(item.reduce(), node, isRoot);
project._currentStyle = currentStyle; project._currentStyle = currentStyle;
if (clip || type === 'defs') { if (clip || type === 'defs') {
item.remove(); item.remove();
@ -11138,8 +11226,8 @@ new function() {
} }
var importers = { var importers = {
'#document': function(node, type, options) { '#document': function(node, type, isRoot, options) {
return importSVG(node.childNodes[0], options); return importSVG(node.childNodes[0], isRoot, options);
}, },
g: importGroup, g: importGroup,
@ -11161,8 +11249,8 @@ new function() {
return raster; return raster;
}, },
symbol: function(node, type) { symbol: function(node, type, isRoot, options) {
return new Symbol(importGroup(node, type), true); return new Symbol(importGroup(node, type, isRoot, options), true);
}, },
defs: importGroup, defs: importGroup,
@ -11256,8 +11344,13 @@ new function() {
var attributes = Base.merge(Base.each(SVGStyles, function(entry) { var attributes = Base.merge(Base.each(SVGStyles, function(entry) {
this[entry.attribute] = function(item, value) { this[entry.attribute] = function(item, value) {
item[entry.set]( item[entry.set](convertValue(value, entry.type, entry.fromSVG));
convertValue(value, entry.type, entry.fromSVG)); if (entry.type === 'color' && item instanceof Shape) {
var color = item[entry.get]();
if (color)
color.transform(new Matrix().translate(
item.getPosition(true).negate()));
}
}; };
}, {}), { }, {}), {
id: function(item, value) { id: function(item, value) {
@ -11343,10 +11436,10 @@ new function() {
: value; : value;
} }
function applyAttributes(item, node) { function applyAttributes(item, node, isRoot) {
var styles = { var styles = {
node: DomElement.getStyles(node) || {}, node: DomElement.getStyles(node) || {},
parent: DomElement.getStyles(node.parentNode) || {} parent: !isRoot && DomElement.getStyles(node.parentNode) || {}
}; };
Base.each(attributes, function(apply, name) { Base.each(attributes, function(apply, name) {
var value = getAttribute(node, name, styles); var value = getAttribute(node, name, styles);
@ -11362,38 +11455,55 @@ new function() {
return match && definitions[match[1]]; return match && definitions[match[1]];
} }
function importSVG(node, options, clearDefs) { function importSVG(node, isRoot, options) {
if (!options) if (!options)
options = {}; options = {};
if (typeof node === 'string') if (typeof node === 'string') {
if (isRoot && !/^.*</.test(node)) {
if (typeof options === 'function')
options = { onLoad: options };
var scope = paper;
return Http.request('get', node, function(svg) {
paper = scope;
var item = importSVG(svg, isRoot, options),
onLoad = options.onLoad,
view = scope.project && scope.project.view;
if (onLoad)
onLoad.call(this, item);
view.draw(true);
});
}
node = new DOMParser().parseFromString(node, 'image/svg+xml'); node = new DOMParser().parseFromString(node, 'image/svg+xml');
}
var type = node.nodeName.toLowerCase(), var type = node.nodeName.toLowerCase(),
importer = importers[type], importer = importers[type],
item = importer && importer(node, type, options), item = importer && importer(node, type, isRoot, options),
data = type !== '#document' && node.getAttribute('data-paper-data'); data = type !== '#document' && node.getAttribute('data-paper-data');
if (options.expandShapes && item instanceof Shape) { if (item) {
item.remove(); if (!(item instanceof Group))
item = item.toPath(); item = applyAttributes(item, node, isRoot);
if (options.expandShapes && item instanceof Shape) {
item.remove();
item = item.toPath();
}
if (data)
item._data = JSON.parse(data);
} }
if (item && !(item instanceof Group)) if (isRoot)
item = applyAttributes(item, node);
if (item && data)
item._data = JSON.parse(data);
if (clearDefs)
definitions = {}; definitions = {};
return item; return item;
} }
Item.inject({ Item.inject({
importSVG: function(node, options) { importSVG: function(node, options) {
return this.addChild(importSVG(node, options, true)); return this.addChild(importSVG(node, true, options));
} }
}); });
Project.inject({ Project.inject({
importSVG: function(node, options) { importSVG: function(node, options) {
this.activate(); this.activate();
return importSVG(node, options, true); return importSVG(node, true, options);
} }
}); });
}; };

File diff suppressed because one or more lines are too long

495
dist/paper-full.js vendored
View file

@ -1,5 +1,5 @@
/*! /*!
* Paper.js v0.9.10 - The Swiss Army Knife of Vector Graphics Scripting. * Paper.js v0.9.11 - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/ * http://paperjs.org/
* *
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey * Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
@ -9,7 +9,7 @@
* *
* All rights reserved. * All rights reserved.
* *
* Date: Tue Oct 29 21:56:00 2013 +0100 * Date: Sat Nov 2 21:26:32 2013 +0100
* *
*** ***
* *
@ -466,31 +466,33 @@ Base.inject({
: res; : res;
}, },
deserialize: function(obj, data) { deserialize: function(json, target, _data) {
var res = obj; var res = json;
data = data || {}; _data = _data || {};
if (Array.isArray(obj)) { if (Array.isArray(json)) {
var type = obj[0], var type = json[0],
isDictionary = type === 'dictionary'; isDictionary = type === 'dictionary';
if (!isDictionary) { if (!isDictionary) {
if (data.dictionary && obj.length == 1 && /^#/.test(type)) if (_data.dictionary && json.length == 1 && /^#/.test(type))
return data.dictionary[type]; return _data.dictionary[type];
type = Base.exports[type]; type = Base.exports[type];
} }
res = []; res = [];
for (var i = type ? 1 : 0, l = obj.length; i < l; i++) for (var i = type ? 1 : 0, l = json.length; i < l; i++)
res.push(Base.deserialize(obj[i], data)); res.push(Base.deserialize(json[i], null, _data));
if (isDictionary) { if (isDictionary) {
data.dictionary = res[0]; _data.dictionary = res[0];
} else if (type) { } else if (type) {
var args = res; var args = res;
res = Base.create(type.prototype); res = target instanceof type
? target
: Base.create(type.prototype);
type.apply(res, args); type.apply(res, args);
} }
} else if (Base.isPlainObject(obj)) { } else if (Base.isPlainObject(json)) {
res = {}; res = {};
for (var key in obj) for (var key in json)
res[key] = Base.deserialize(obj[key], data); res[key] = Base.deserialize(json[key], null, _data);
} }
return res; return res;
}, },
@ -499,9 +501,9 @@ Base.inject({
return JSON.stringify(Base.serialize(obj, options)); return JSON.stringify(Base.serialize(obj, options));
}, },
importJSON: function(json) { importJSON: function(json, target) {
return Base.deserialize( return Base.deserialize(
typeof json === 'string' ? JSON.parse(json) : json); typeof json === 'string' ? JSON.parse(json) : json, target);
}, },
splice: function(list, items, index, remove) { splice: function(list, items, index, remove) {
@ -682,7 +684,7 @@ var PaperScope = Base.extend({
} }
}, },
version: '0.9.10', version: '0.9.11',
getView: function() { getView: function() {
return this.project && this.project.view; return this.project && this.project.view;
@ -694,6 +696,10 @@ var PaperScope = Base.extend({
return this._tool; return this._tool;
}, },
getPaper: function() {
return this;
},
evaluate: function(code) { evaluate: function(code) {
var res = paper.PaperScript.evaluate(code, this); var res = paper.PaperScript.evaluate(code, this);
View.updateFocus(); View.updateFocus();
@ -2009,10 +2015,10 @@ var Matrix = Base.extend({
return !this._getDeterminant(); return !this._getDeterminant();
}, },
transform: function( src, srcOff, dst, dstOff, numPts) { transform: function( src, srcOffset, dst, dstOffset, count) {
return arguments.length < 5 return arguments.length < 5
? this._transformPoint(Point.read(arguments)) ? this._transformPoint(Point.read(arguments))
: this._transformCoordinates(src, srcOff, dst, dstOff, numPts); : this._transformCoordinates(src, srcOffset, dst, dstOffset, count);
}, },
_transformPoint: function(point, dest, dontNotify) { _transformPoint: function(point, dest, dontNotify) {
@ -2027,10 +2033,11 @@ var Matrix = Base.extend({
); );
}, },
_transformCoordinates: function(src, srcOff, dst, dstOff, numPts) { _transformCoordinates: function(src, srcOffset, dst, dstOffset, count) {
var i = srcOff, j = dstOff, var i = srcOffset,
srcEnd = srcOff + 2 * numPts; j = dstOffset,
while (i < srcEnd) { max = i + 2 * count;
while (i < max) {
var x = src[i++], var x = src[i++],
y = src[i++]; y = src[i++];
dst[j++] = x * this._a + y * this._b + this._tx; dst[j++] = x * this._a + y * this._b + this._tx;
@ -2736,6 +2743,10 @@ var Item = Base.extend(Callback, {
hasStroke: function() { hasStroke: function() {
return this.getStyle().hasStroke(); return this.getStyle().hasStroke();
},
hasShadow: function() {
return this.getStyle().hasShadow();
} }
}, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'], }, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'],
function(name) { function(name) {
@ -3251,7 +3262,10 @@ var Item = Base.extend(Callback, {
}, { }, {
importJSON: function(json) { importJSON: function(json) {
return this.addChild(Base.importJSON(json)); var res = Base.importJSON(json, this);
return res !== this
? this.addChild(res)
: res;
}, },
addChild: function(item, _preserve) { addChild: function(item, _preserve) {
@ -3387,6 +3401,8 @@ var Item = Base.extend(Callback, {
return removed; return removed;
}, },
clear: '#removeChildren',
reverseChildren: function() { reverseChildren: function() {
if (this._children) { if (this._children) {
this._children.reverse(); this._children.reverse();
@ -3561,43 +3577,49 @@ var Item = Base.extend(Callback, {
_setStyles: function(ctx) { _setStyles: function(ctx) {
var style = this._style, var style = this._style,
matrix = this._matrix,
strokeWidth = style.getStrokeWidth(),
fillColor = style.getFillColor(), fillColor = style.getFillColor(),
strokeColor = style.getStrokeColor(), strokeColor = style.getStrokeColor(),
shadowColor = style.getShadowColor(); shadowColor = style.getShadowColor();
if (fillColor) if (fillColor)
ctx.fillStyle = fillColor.toCanvasStyle(ctx, matrix); ctx.fillStyle = fillColor.toCanvasStyle(ctx);
if (strokeColor && strokeWidth > 0) { if (strokeColor) {
ctx.strokeStyle = strokeColor.toCanvasStyle(ctx, matrix); var strokeWidth = style.getStrokeWidth();
ctx.lineWidth = strokeWidth; if (strokeWidth > 0) {
var strokeJoin = style.getStrokeJoin(), ctx.strokeStyle = strokeColor.toCanvasStyle(ctx);
strokeCap = style.getStrokeCap(), ctx.lineWidth = strokeWidth;
miterLimit = style.getMiterLimit(), var strokeJoin = style.getStrokeJoin(),
dashArray = style.getDashArray(), strokeCap = style.getStrokeCap(),
dashOffset = style.getDashOffset(); miterLimit = style.getMiterLimit();
if (strokeJoin) if (strokeJoin)
ctx.lineJoin = strokeJoin; ctx.lineJoin = strokeJoin;
if (strokeCap) if (strokeCap)
ctx.lineCap = strokeCap; ctx.lineCap = strokeCap;
if (miterLimit) if (miterLimit)
ctx.miterLimit = miterLimit; ctx.miterLimit = miterLimit;
if (paper.support.nativeDash && dashArray && dashArray.length) { if (paper.support.nativeDash) {
if ('setLineDash' in ctx) { var dashArray = style.getDashArray(),
ctx.setLineDash(dashArray); dashOffset = style.getDashOffset();
ctx.lineDashOffset = dashOffset; if (dashArray && dashArray.length) {
} else { if ('setLineDash' in ctx) {
ctx.mozDash = dashArray; ctx.setLineDash(dashArray);
ctx.mozDashOffset = dashOffset; ctx.lineDashOffset = dashOffset;
} else {
ctx.mozDash = dashArray;
ctx.mozDashOffset = dashOffset;
}
}
} }
} }
} }
if (shadowColor) { if (shadowColor) {
ctx.shadowColor = shadowColor.toCanvasStyle(ctx); var shadowBlur = style.getShadowBlur();
ctx.shadowBlur = style.getShadowBlur(); if (shadowBlur > 0) {
var offset = this.getShadowOffset(); ctx.shadowColor = shadowColor.toCanvasStyle(ctx);
ctx.shadowOffsetX = offset.x; ctx.shadowBlur = shadowBlur;
ctx.shadowOffsetY = offset.y; var offset = this.getShadowOffset();
ctx.shadowOffsetX = offset.x;
ctx.shadowOffsetY = offset.y;
}
} }
}, },
@ -3894,8 +3916,8 @@ var Shape = Item.extend({
radius: this._radius, radius: this._radius,
insert: false insert: false
}); });
path.transform(this._matrix);
path.setStyle(this._style); path.setStyle(this._style);
path.transform(this._matrix);
if (insert || insert === undefined) if (insert || insert === undefined)
path.insertAbove(this); path.insertAbove(this);
return path; return path;
@ -3951,8 +3973,10 @@ var Shape = Item.extend({
} }
if (!clip && (hasFill || hasStroke)) { if (!clip && (hasFill || hasStroke)) {
this._setStyles(ctx); this._setStyles(ctx);
if (hasFill) if (hasFill) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (hasStroke) if (hasStroke)
ctx.stroke(); ctx.stroke();
} }
@ -5912,7 +5936,7 @@ var PathItem = Item.extend({
setPathData: function(data) { setPathData: function(data) {
var parts = data.match(/[a-z][^a-z]*/ig), var parts = data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig),
coords, coords,
relative = false, relative = false,
control, control,
@ -5934,18 +5958,15 @@ var PathItem = Item.extend({
); );
} }
if (this._type === 'path') this.clear();
this.removeSegments();
else
this.removeChildren();
for (var i = 0, l = parts.length; i < l; i++) { for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i], var part = parts[i],
cmd = part[0], cmd = part[0],
lower = cmd.toLowerCase(); lower = cmd.toLowerCase();
coords = part.slice(1).trim().split(/[\s,]+|(?=[+-])/); coords = part.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g);
var length = coords && coords.length;
relative = cmd === lower; relative = cmd === lower;
var length = coords.length;
switch (lower) { switch (lower) {
case 'm': case 'm':
case 'l': case 'l':
@ -6304,6 +6325,8 @@ var Path = PathItem.extend({
return removed; return removed;
}, },
clear: '#removeSegments',
isFullySelected: function() { isFullySelected: function() {
var length = this._segments.length; var length = this._segments.length;
return this._selected && length > 0 && this._selectedSegmentState return this._selected && length > 0 && this._selectedSegmentState
@ -6899,8 +6922,10 @@ var Path = PathItem.extend({
if (!clip && !compound && (hasFill || hasStroke)) { if (!clip && !compound && (hasFill || hasStroke)) {
this._setStyles(ctx); this._setStyles(ctx);
if (hasFill) if (hasFill) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (hasStroke) { if (hasStroke) {
if (dashLength) { if (dashLength) {
ctx.beginPath(); ctx.beginPath();
@ -7057,16 +7082,16 @@ var Path = PathItem.extend({
cubicCurveTo: function() { cubicCurveTo: function() {
var handle1 = Point.read(arguments), var handle1 = Point.read(arguments),
handle2 = Point.read(arguments), handle2 = Point.read(arguments),
to = Point.read(arguments); to = Point.read(arguments),
var current = getCurrentSegment(this); current = getCurrentSegment(this);
current.setHandleOut(handle1.subtract(current._point)); current.setHandleOut(handle1.subtract(current._point));
this._add([ new Segment(to, handle2.subtract(to)) ]); this._add([ new Segment(to, handle2.subtract(to)) ]);
}, },
quadraticCurveTo: function() { quadraticCurveTo: function() {
var handle = Point.read(arguments), var handle = Point.read(arguments),
to = Point.read(arguments); to = Point.read(arguments),
var current = getCurrentSegment(this)._point; current = getCurrentSegment(this)._point;
this.cubicCurveTo( this.cubicCurveTo(
handle.add(current.subtract(handle).multiply(1 / 3)), handle.add(current.subtract(handle).multiply(1 / 3)),
handle.add(to.subtract(handle).multiply(1 / 3)), handle.add(to.subtract(handle).multiply(1 / 3)),
@ -7145,25 +7170,41 @@ var Path = PathItem.extend({
this._add(segments); this._add(segments);
}, },
lineBy: function(vector) { lineBy: function() {
vector = Point.read(arguments); var to = Point.read(arguments),
var current = getCurrentSegment(this); current = getCurrentSegment(this)._point;
this.lineTo(current._point.add(vector)); this.lineTo(current.add(to));
}, },
curveBy: function(throughVector, toVector, parameter) { curveBy: function() {
throughVector = Point.read(throughVector); var through = Point.read(arguments),
toVector = Point.read(toVector); to = Point.read(arguments),
var current = getCurrentSegment(this)._point; parameter = Base.read(arguments),
this.curveTo(current.add(throughVector), current.add(toVector), current = getCurrentSegment(this)._point;
parameter); this.curveTo(current.add(through), current.add(to), parameter);
}, },
arcBy: function(throughVector, toVector) { cubicCurveBy: function() {
throughVector = Point.read(throughVector); var handle1 = Point.read(arguments),
toVector = Point.read(toVector); handle2 = Point.read(arguments),
var current = getCurrentSegment(this)._point; to = Point.read(arguments),
this.arcTo(current.add(throughVector), current.add(toVector)); current = getCurrentSegment(this)._point;
this.cubicCurveTo(current.add(handle1), current.add(handle2),
current.add(to));
},
quadraticCurveBy: function() {
var handle = Point.read(arguments),
to = Point.read(arguments),
current = getCurrentSegment(this)._point;
this.quadraticCurveTo(current.add(handle), current.add(to));
},
arcBy: function() {
var through = Point.read(arguments),
to = Point.read(arguments),
current = getCurrentSegment(this)._point;
this.arcTo(current.add(through), current.add(to));
}, },
closePath: function() { closePath: function() {
@ -7644,8 +7685,10 @@ var CompoundPath = PathItem.extend({
if (!param.clip) { if (!param.clip) {
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style; var style = this._style;
if (style.hasFill()) if (style.hasFill()) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (style.hasStroke()) if (style.hasStroke())
ctx.stroke(); ctx.stroke();
} }
@ -7674,13 +7717,15 @@ var CompoundPath = PathItem.extend({
} }
}; };
Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', 'arcTo',
'arcTo', 'lineBy', 'curveBy', 'arcBy'], function(key) { 'lineBy', 'cubicCurveBy', 'quadraticCurveBy', 'curveBy', 'arcBy'],
fields[key] = function() { function(key) {
var path = getCurrentPath(this); fields[key] = function() {
path[key].apply(path, arguments); var path = getCurrentPath(this);
}; path[key].apply(path, arguments);
}); };
}
);
return fields; return fields;
}); });
@ -8212,13 +8257,18 @@ var PointText = TextItem.extend({
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style, var style = this._style,
lines = this._lines, lines = this._lines,
leading = style.getLeading(); leading = style.getLeading(),
shadowColor = ctx.shadowColor;
ctx.font = style.getFontStyle(); ctx.font = style.getFontStyle();
ctx.textAlign = style.getJustification(); ctx.textAlign = style.getJustification();
for (var i = 0, l = lines.length; i < l; i++) { for (var i = 0, l = lines.length; i < l; i++) {
ctx.shadowColor = shadowColor;
var line = lines[i]; var line = lines[i];
if (style.hasFill()) if (style.hasFill()) {
ctx.fillText(line, 0, 0); ctx.fillText(line, 0, 0);
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (style.hasStroke()) if (style.hasStroke())
ctx.strokeText(line, 0, 0); ctx.strokeText(line, 0, 0);
ctx.translate(0, leading); ctx.translate(0, leading);
@ -8597,7 +8647,7 @@ var Color = Base.extend(new function() {
}, },
clone: function() { clone: function() {
return new Color(this._type, this._components.slice(), this._alpha); return new Color(this);
}, },
_convert: function(type) { _convert: function(type) {
@ -8685,23 +8735,21 @@ var Color = Base.extend(new function() {
+ components.join(',') + ')'; + components.join(',') + ')';
}, },
toCanvasStyle: function(ctx, matrix) { toCanvasStyle: function(ctx) {
if (this._canvasStyle) if (this._canvasStyle)
return this._canvasStyle; return this._canvasStyle;
if (this._type !== 'gradient') if (this._type !== 'gradient')
return this._canvasStyle = this.toCSS(); return this._canvasStyle = this.toCSS();
var components = this._components, var components = this._components,
translation = matrix ? matrix.getTranslation() : new Point(),
gradient = components[0], gradient = components[0],
stops = gradient._stops, stops = gradient._stops,
origin = components[1].subtract(translation), origin = components[1],
destination = components[2].subtract(translation), destination = components[2],
canvasGradient; canvasGradient;
if (gradient._radial) { if (gradient._radial) {
var radius = destination.getDistance(origin), var radius = destination.getDistance(origin),
highlight = components[3]; highlight = components[3];
if (highlight) { if (highlight) {
highlight = highlight.subtract(translation);
var vector = highlight.subtract(origin); var vector = highlight.subtract(origin);
if (vector.getLength() > radius) if (vector.getLength() > radius)
highlight = origin.add(vector.normalize(radius - 0.1)); highlight = origin.add(vector.normalize(radius - 0.1));
@ -9027,8 +9075,11 @@ var Style = Base.extend(new function() {
if (isColor) { if (isColor) {
if (old) if (old)
delete old._owner; delete old._owner;
if (value && value.constructor === Color) if (value && value.constructor === Color) {
if (value._owner)
value = value.clone();
value._owner = this._item; value._owner = this._item;
}
} }
this._values[key] = value; this._values[key] = value;
if (this._item) if (this._item)
@ -9118,6 +9169,10 @@ var Style = Base.extend(new function() {
return !!this.getStrokeColor() && this.getStrokeWidth() > 0; return !!this.getStrokeColor() && this.getStrokeWidth() > 0;
}, },
hasShadow: function() {
return !!this.getShadowColor() && this.getShadowBlur() > 0;
},
getLeading: function getLeading() { getLeading: function getLeading() {
var leading = getLeading.base.call(this); var leading = getLeading.base.call(this);
return leading != null ? leading : this.getFontSize() * 1.2; return leading != null ? leading : this.getFontSize() * 1.2;
@ -9377,18 +9432,10 @@ var DomEvent = {
}; };
DomEvent.requestAnimationFrame = new function() { DomEvent.requestAnimationFrame = new function() {
var part = 'equestAnimationFrame', var nativeRequest = DomElement.getPrefixValue(window,
request = window['r' + part] || window['webkitR' + part] 'requestAnimationFrame'),
|| window['mozR' + part] || window['oR' + part] requested = false,
|| window['msR' + part]; callbacks = [],
if (request) {
request(function(time) {
if (time == null)
request = null;
});
}
var callbacks = [],
focused = true, focused = true,
timer; timer;
@ -9401,24 +9448,36 @@ DomEvent.requestAnimationFrame = new function() {
} }
}); });
return function(callback, element) { function handleCallbacks() {
if (request) for (var i = callbacks.length - 1; i >= 0; i--) {
return request(callback, element); var entry = callbacks[i],
callbacks.push([callback, element]); func = entry[0],
if (timer) el = entry[1];
return; if (!el || (PaperScope.getAttribute(el, 'keepalive') == 'true'
timer = setInterval(function() { || focused) && DomElement.isInView(el)) {
for (var i = callbacks.length - 1; i >= 0; i--) { callbacks.splice(i, 1);
var entry = callbacks[i], func();
func = entry[0],
el = entry[1];
if (!el || (PaperScope.getAttribute(el, 'keepalive') == 'true'
|| focused) && DomElement.isInView(el)) {
callbacks.splice(i, 1);
func(Date.now());
}
} }
}, 1000 / 60); }
if (nativeRequest) {
if (callbacks.length) {
nativeRequest(handleCallbacks);
} else {
requested = false;
}
}
}
return function(callback, element) {
callbacks.push([callback, element]);
if (nativeRequest) {
if (!requested) {
nativeRequest(handleCallbacks);
requested = true;
}
} else if (!timer) {
timer = setInterval(handleCallbacks, 1000 / 60);
}
}; };
}; };
@ -10005,6 +10064,7 @@ var Key = new function() {
tool = scope && scope._tool; tool = scope && scope._tool;
keyMap[key] = down; keyMap[key] = down;
if (tool && tool.responds(type)) { if (tool && tool.responds(type)) {
paper = scope;
tool.fire(type, new KeyEvent(down, key, character, event)); tool.fire(type, new KeyEvent(down, key, character, event));
if (view) if (view)
view.draw(true); view.draw(true);
@ -10545,6 +10605,28 @@ var Tool = PaperScopeItem.extend({
}); });
var Http = {
request: function(method, url, callback) {
var xhr = new (window.ActiveXObject || XMLHttpRequest)(
'Microsoft.XMLHTTP');
xhr.open(method.toUpperCase(), url, true);
if ('overrideMimeType' in xhr)
xhr.overrideMimeType('text/plain');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
var status = xhr.status;
if (status === 0 || status === 200) {
callback.call(xhr, xhr.responseText);
} else {
throw new Error('Could not load ' + url + ' (Error '
+ status + ')');
}
}
};
return xhr.send(null);
}
};
var CanvasProvider = { var CanvasProvider = {
canvases: [], canvases: [],
@ -10920,13 +11002,13 @@ new function() {
return attrs; return attrs;
} }
function exportGroup(item) { function exportGroup(item, options) {
var attrs = getTransform(item), var attrs = getTransform(item),
children = item._children; children = item._children;
var node = createElement('g', attrs); var node = createElement('g', attrs);
for (var i = 0, l = children.length; i < l; i++) { for (var i = 0, l = children.length; i < l; i++) {
var child = children[i]; var child = children[i];
var childNode = exportSVG(child); var childNode = exportSVG(child, options);
if (childNode) { if (childNode) {
if (child.isClipMask()) { if (child.isClipMask()) {
var clip = createElement('clipPath'); var clip = createElement('clipPath');
@ -10954,7 +11036,12 @@ new function() {
return createElement('image', attrs); return createElement('image', attrs);
} }
function exportPath(item) { function exportPath(item, options) {
if (options.matchShapes) {
var shape = item.toShape(false);
if (shape)
return exportShape(shape, options);
}
var segments = item._segments, var segments = item._segments,
type, type,
attrs; attrs;
@ -10990,7 +11077,6 @@ new function() {
function exportShape(item) { function exportShape(item) {
var shape = item._shape, var shape = item._shape,
center = item.getPosition(true),
radius = item._radius, radius = item._radius,
attrs = getTransform(item, true, shape !== 'rectangle'); attrs = getTransform(item, true, shape !== 'rectangle');
if (shape === 'rectangle') { if (shape === 'rectangle') {
@ -11024,7 +11110,7 @@ new function() {
return createElement('path', attrs); return createElement('path', attrs);
} }
function exportPlacedSymbol(item) { function exportPlacedSymbol(item, options) {
var attrs = getTransform(item, true), var attrs = getTransform(item, true),
symbol = item.getSymbol(), symbol = item.getSymbol(),
symbolNode = getDefinition(symbol, 'symbol'), symbolNode = getDefinition(symbol, 'symbol'),
@ -11034,7 +11120,7 @@ new function() {
symbolNode = createElement('symbol', { symbolNode = createElement('symbol', {
viewBox: formatter.rectangle(bounds) viewBox: formatter.rectangle(bounds)
}); });
symbolNode.appendChild(exportSVG(definition)); symbolNode.appendChild(exportSVG(definition, options));
setDefinition(symbol, symbolNode, 'symbol'); setDefinition(symbol, symbolNode, 'symbol');
} }
attrs.href = '#' + symbolNode.id; attrs.href = '#' + symbolNode.id;
@ -11045,7 +11131,7 @@ new function() {
return createElement('use', attrs); return createElement('use', attrs);
} }
function exportGradient(color, item) { function exportGradient(color) {
var gradientNode = getDefinition(color, 'color'); var gradientNode = getDefinition(color, 'color');
if (!gradientNode) { if (!gradientNode) {
var gradient = color.getGradient(), var gradient = color.getGradient(),
@ -11169,29 +11255,31 @@ new function() {
} }
function exportDefinitions(node, options) { function exportDefinitions(node, options) {
if (!definitions) var svg = node,
return node;
var svg = node.nodeName.toLowerCase() === 'svg' && node,
defs = null; defs = null;
for (var i in definitions.svgs) { if (definitions) {
if (!defs) { svg = node.nodeName.toLowerCase() === 'svg' && node;
if (!svg) { for (var i in definitions.svgs) {
svg = createElement('svg'); if (!defs) {
svg.appendChild(node); if (!svg) {
svg = createElement('svg');
svg.appendChild(node);
}
defs = svg.insertBefore(createElement('defs'),
svg.firstChild);
} }
defs = svg.insertBefore(createElement('defs'), svg.firstChild); defs.appendChild(definitions.svgs[i]);
} }
defs.appendChild(definitions.svgs[i]); definitions = null;
} }
definitions = null;
return options.asString return options.asString
? new XMLSerializer().serializeToString(svg) ? new XMLSerializer().serializeToString(svg)
: svg; : svg;
} }
function exportSVG(item) { function exportSVG(item, options) {
var exporter = exporters[item._type], var exporter = exporters[item._type],
node = exporter && exporter(item, item._type); node = exporter && exporter(item, options);
if (node && item._data) if (node && item._data)
node.setAttribute('data-paper-data', JSON.stringify(item._data)); node.setAttribute('data-paper-data', JSON.stringify(item._data));
return node && applyStyle(item, node); return node && applyStyle(item, node);
@ -11207,7 +11295,7 @@ new function() {
Item.inject({ Item.inject({
exportSVG: function(options) { exportSVG: function(options) {
options = setOptions(options); options = setOptions(options);
return exportDefinitions(exportSVG(this), options); return exportDefinitions(exportSVG(this, options), options);
} }
}); });
@ -11226,7 +11314,7 @@ new function() {
'xmlns:xlink': 'http://www.w3.org/1999/xlink' 'xmlns:xlink': 'http://www.w3.org/1999/xlink'
}); });
for (var i = 0, l = layers.length; i < l; i++) for (var i = 0, l = layers.length; i < l; i++)
node.appendChild(exportSVG(layers[i])); node.appendChild(exportSVG(layers[i], options));
return exportDefinitions(node, options); return exportDefinitions(node, options);
} }
}); });
@ -11255,15 +11343,15 @@ new function() {
function getPoint(node, x, y, allowNull) { function getPoint(node, x, y, allowNull) {
x = getValue(node, x, false, allowNull); x = getValue(node, x, false, allowNull);
y = getValue(node, y, false, allowNull); y = getValue(node, y, false, allowNull);
return allowNull && x == null && y == null ? null return allowNull && (x == null || y == null) ? null
: new Point(x || 0, y || 0); : new Point(x, y);
} }
function getSize(node, w, h, allowNull) { function getSize(node, w, h, allowNull) {
w = getValue(node, w, false, allowNull); w = getValue(node, w, false, allowNull);
h = getValue(node, h, false, allowNull); h = getValue(node, h, false, allowNull);
return allowNull && w == null && h == null ? null return allowNull && (w == null || h == null) ? null
: new Size(w || 0, h || 0); : new Size(w, h);
} }
function convertValue(value, type, lookup) { function convertValue(value, type, lookup) {
@ -11280,7 +11368,7 @@ new function() {
: value; : value;
} }
function importGroup(node, type, options) { function importGroup(node, type, isRoot, options) {
var nodes = node.childNodes, var nodes = node.childNodes,
clip = type === 'clippath', clip = type === 'clippath',
item = new Group(), item = new Group(),
@ -11289,20 +11377,20 @@ new function() {
children = []; children = [];
if (!clip) { if (!clip) {
item._transformContent = false; item._transformContent = false;
item = applyAttributes(item, node); item = applyAttributes(item, node, isRoot);
project._currentStyle = item._style.clone(); project._currentStyle = item._style.clone();
} }
for (var i = 0, l = nodes.length; i < l; i++) { for (var i = 0, l = nodes.length; i < l; i++) {
var childNode = nodes[i], var childNode = nodes[i],
child; child;
if (childNode.nodeType === 1 if (childNode.nodeType === 1
&& (child = importSVG(childNode, options)) && (child = importSVG(childNode, false, options))
&& !(child instanceof Symbol)) && !(child instanceof Symbol))
children.push(child); children.push(child);
} }
item.addChildren(children); item.addChildren(children);
if (clip) if (clip)
item = applyAttributes(item.reduce(), node); item = applyAttributes(item.reduce(), node, isRoot);
project._currentStyle = currentStyle; project._currentStyle = currentStyle;
if (clip || type === 'defs') { if (clip || type === 'defs') {
item.remove(); item.remove();
@ -11356,8 +11444,8 @@ new function() {
} }
var importers = { var importers = {
'#document': function(node, type, options) { '#document': function(node, type, isRoot, options) {
return importSVG(node.childNodes[0], options); return importSVG(node.childNodes[0], isRoot, options);
}, },
g: importGroup, g: importGroup,
@ -11379,8 +11467,8 @@ new function() {
return raster; return raster;
}, },
symbol: function(node, type) { symbol: function(node, type, isRoot, options) {
return new Symbol(importGroup(node, type), true); return new Symbol(importGroup(node, type, isRoot, options), true);
}, },
defs: importGroup, defs: importGroup,
@ -11474,8 +11562,13 @@ new function() {
var attributes = Base.merge(Base.each(SVGStyles, function(entry) { var attributes = Base.merge(Base.each(SVGStyles, function(entry) {
this[entry.attribute] = function(item, value) { this[entry.attribute] = function(item, value) {
item[entry.set]( item[entry.set](convertValue(value, entry.type, entry.fromSVG));
convertValue(value, entry.type, entry.fromSVG)); if (entry.type === 'color' && item instanceof Shape) {
var color = item[entry.get]();
if (color)
color.transform(new Matrix().translate(
item.getPosition(true).negate()));
}
}; };
}, {}), { }, {}), {
id: function(item, value) { id: function(item, value) {
@ -11561,10 +11654,10 @@ new function() {
: value; : value;
} }
function applyAttributes(item, node) { function applyAttributes(item, node, isRoot) {
var styles = { var styles = {
node: DomElement.getStyles(node) || {}, node: DomElement.getStyles(node) || {},
parent: DomElement.getStyles(node.parentNode) || {} parent: !isRoot && DomElement.getStyles(node.parentNode) || {}
}; };
Base.each(attributes, function(apply, name) { Base.each(attributes, function(apply, name) {
var value = getAttribute(node, name, styles); var value = getAttribute(node, name, styles);
@ -11580,38 +11673,55 @@ new function() {
return match && definitions[match[1]]; return match && definitions[match[1]];
} }
function importSVG(node, options, clearDefs) { function importSVG(node, isRoot, options) {
if (!options) if (!options)
options = {}; options = {};
if (typeof node === 'string') if (typeof node === 'string') {
if (isRoot && !/^.*</.test(node)) {
if (typeof options === 'function')
options = { onLoad: options };
var scope = paper;
return Http.request('get', node, function(svg) {
paper = scope;
var item = importSVG(svg, isRoot, options),
onLoad = options.onLoad,
view = scope.project && scope.project.view;
if (onLoad)
onLoad.call(this, item);
view.draw(true);
});
}
node = new DOMParser().parseFromString(node, 'image/svg+xml'); node = new DOMParser().parseFromString(node, 'image/svg+xml');
}
var type = node.nodeName.toLowerCase(), var type = node.nodeName.toLowerCase(),
importer = importers[type], importer = importers[type],
item = importer && importer(node, type, options), item = importer && importer(node, type, isRoot, options),
data = type !== '#document' && node.getAttribute('data-paper-data'); data = type !== '#document' && node.getAttribute('data-paper-data');
if (options.expandShapes && item instanceof Shape) { if (item) {
item.remove(); if (!(item instanceof Group))
item = item.toPath(); item = applyAttributes(item, node, isRoot);
if (options.expandShapes && item instanceof Shape) {
item.remove();
item = item.toPath();
}
if (data)
item._data = JSON.parse(data);
} }
if (item && !(item instanceof Group)) if (isRoot)
item = applyAttributes(item, node);
if (item && data)
item._data = JSON.parse(data);
if (clearDefs)
definitions = {}; definitions = {};
return item; return item;
} }
Item.inject({ Item.inject({
importSVG: function(node, options) { importSVG: function(node, options) {
return this.addChild(importSVG(node, options, true)); return this.addChild(importSVG(node, true, options));
} }
}); });
Project.inject({ Project.inject({
importSVG: function(node, options) { importSVG: function(node, options) {
this.activate(); this.activate();
return importSVG(node, options, true); return importSVG(node, true, options);
} }
}); });
}; };
@ -11814,20 +11924,6 @@ paper.PaperScope.prototype.PaperScript = (function(root) {
return res; return res;
} }
function request(url, scope) {
var xhr = new (window.ActiveXObject || XMLHttpRequest)(
'Microsoft.XMLHTTP');
xhr.open('GET', url, true);
if (xhr.overrideMimeType)
xhr.overrideMimeType('text/plain');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
return evaluate(xhr.responseText, scope);
}
};
return xhr.send(null);
}
function load() { function load() {
var scripts = document.getElementsByTagName('script'); var scripts = document.getElementsByTagName('script');
for (var i = 0, l = scripts.length; i < l; i++) { for (var i = 0, l = scripts.length; i < l; i++) {
@ -11836,9 +11932,12 @@ paper.PaperScope.prototype.PaperScript = (function(root) {
&& !script.getAttribute('data-paper-ignore')) { && !script.getAttribute('data-paper-ignore')) {
var canvas = PaperScope.getAttribute(script, 'canvas'), var canvas = PaperScope.getAttribute(script, 'canvas'),
scope = PaperScope.get(canvas) scope = PaperScope.get(canvas)
|| new PaperScope(script).setup(canvas); || new PaperScope(script).setup(canvas),
if (script.src) { src = script.src;
request(script.src, scope); if (src) {
Http.request('get', src, function(code) {
evaluate(code, scope);
});
} else { } else {
evaluate(script.innerHTML, scope); evaluate(script.innerHTML, scope);
} }

File diff suppressed because one or more lines are too long

387
dist/paper-node.js vendored
View file

@ -1,5 +1,5 @@
/*! /*!
* Paper.js v0.9.10 - The Swiss Army Knife of Vector Graphics Scripting. * Paper.js v0.9.11 - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/ * http://paperjs.org/
* *
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey * Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
@ -9,7 +9,7 @@
* *
* All rights reserved. * All rights reserved.
* *
* Date: Tue Oct 29 21:56:00 2013 +0100 * Date: Sat Nov 2 21:26:32 2013 +0100
* *
*** ***
* *
@ -466,31 +466,33 @@ Base.inject({
: res; : res;
}, },
deserialize: function(obj, data) { deserialize: function(json, target, _data) {
var res = obj; var res = json;
data = data || {}; _data = _data || {};
if (Array.isArray(obj)) { if (Array.isArray(json)) {
var type = obj[0], var type = json[0],
isDictionary = type === 'dictionary'; isDictionary = type === 'dictionary';
if (!isDictionary) { if (!isDictionary) {
if (data.dictionary && obj.length == 1 && /^#/.test(type)) if (_data.dictionary && json.length == 1 && /^#/.test(type))
return data.dictionary[type]; return _data.dictionary[type];
type = Base.exports[type]; type = Base.exports[type];
} }
res = []; res = [];
for (var i = type ? 1 : 0, l = obj.length; i < l; i++) for (var i = type ? 1 : 0, l = json.length; i < l; i++)
res.push(Base.deserialize(obj[i], data)); res.push(Base.deserialize(json[i], null, _data));
if (isDictionary) { if (isDictionary) {
data.dictionary = res[0]; _data.dictionary = res[0];
} else if (type) { } else if (type) {
var args = res; var args = res;
res = Base.create(type.prototype); res = target instanceof type
? target
: Base.create(type.prototype);
type.apply(res, args); type.apply(res, args);
} }
} else if (Base.isPlainObject(obj)) { } else if (Base.isPlainObject(json)) {
res = {}; res = {};
for (var key in obj) for (var key in json)
res[key] = Base.deserialize(obj[key], data); res[key] = Base.deserialize(json[key], null, _data);
} }
return res; return res;
}, },
@ -499,9 +501,9 @@ Base.inject({
return JSON.stringify(Base.serialize(obj, options)); return JSON.stringify(Base.serialize(obj, options));
}, },
importJSON: function(json) { importJSON: function(json, target) {
return Base.deserialize( return Base.deserialize(
typeof json === 'string' ? JSON.parse(json) : json); typeof json === 'string' ? JSON.parse(json) : json, target);
}, },
splice: function(list, items, index, remove) { splice: function(list, items, index, remove) {
@ -682,7 +684,7 @@ var PaperScope = Base.extend({
} }
}, },
version: '0.9.10', version: '0.9.11',
getView: function() { getView: function() {
return this.project && this.project.view; return this.project && this.project.view;
@ -694,6 +696,10 @@ var PaperScope = Base.extend({
return this._tool; return this._tool;
}, },
getPaper: function() {
return this;
},
evaluate: function(code) { evaluate: function(code) {
var res = paper.PaperScript.evaluate(code, this); var res = paper.PaperScript.evaluate(code, this);
View.updateFocus(); View.updateFocus();
@ -2009,10 +2015,10 @@ var Matrix = Base.extend({
return !this._getDeterminant(); return !this._getDeterminant();
}, },
transform: function( src, srcOff, dst, dstOff, numPts) { transform: function( src, srcOffset, dst, dstOffset, count) {
return arguments.length < 5 return arguments.length < 5
? this._transformPoint(Point.read(arguments)) ? this._transformPoint(Point.read(arguments))
: this._transformCoordinates(src, srcOff, dst, dstOff, numPts); : this._transformCoordinates(src, srcOffset, dst, dstOffset, count);
}, },
_transformPoint: function(point, dest, dontNotify) { _transformPoint: function(point, dest, dontNotify) {
@ -2027,10 +2033,11 @@ var Matrix = Base.extend({
); );
}, },
_transformCoordinates: function(src, srcOff, dst, dstOff, numPts) { _transformCoordinates: function(src, srcOffset, dst, dstOffset, count) {
var i = srcOff, j = dstOff, var i = srcOffset,
srcEnd = srcOff + 2 * numPts; j = dstOffset,
while (i < srcEnd) { max = i + 2 * count;
while (i < max) {
var x = src[i++], var x = src[i++],
y = src[i++]; y = src[i++];
dst[j++] = x * this._a + y * this._b + this._tx; dst[j++] = x * this._a + y * this._b + this._tx;
@ -2736,6 +2743,10 @@ var Item = Base.extend(Callback, {
hasStroke: function() { hasStroke: function() {
return this.getStyle().hasStroke(); return this.getStyle().hasStroke();
},
hasShadow: function() {
return this.getStyle().hasShadow();
} }
}, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'], }, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'],
function(name) { function(name) {
@ -3251,7 +3262,10 @@ var Item = Base.extend(Callback, {
}, { }, {
importJSON: function(json) { importJSON: function(json) {
return this.addChild(Base.importJSON(json)); var res = Base.importJSON(json, this);
return res !== this
? this.addChild(res)
: res;
}, },
addChild: function(item, _preserve) { addChild: function(item, _preserve) {
@ -3387,6 +3401,8 @@ var Item = Base.extend(Callback, {
return removed; return removed;
}, },
clear: '#removeChildren',
reverseChildren: function() { reverseChildren: function() {
if (this._children) { if (this._children) {
this._children.reverse(); this._children.reverse();
@ -3561,43 +3577,49 @@ var Item = Base.extend(Callback, {
_setStyles: function(ctx) { _setStyles: function(ctx) {
var style = this._style, var style = this._style,
matrix = this._matrix,
strokeWidth = style.getStrokeWidth(),
fillColor = style.getFillColor(), fillColor = style.getFillColor(),
strokeColor = style.getStrokeColor(), strokeColor = style.getStrokeColor(),
shadowColor = style.getShadowColor(); shadowColor = style.getShadowColor();
if (fillColor) if (fillColor)
ctx.fillStyle = fillColor.toCanvasStyle(ctx, matrix); ctx.fillStyle = fillColor.toCanvasStyle(ctx);
if (strokeColor && strokeWidth > 0) { if (strokeColor) {
ctx.strokeStyle = strokeColor.toCanvasStyle(ctx, matrix); var strokeWidth = style.getStrokeWidth();
ctx.lineWidth = strokeWidth; if (strokeWidth > 0) {
var strokeJoin = style.getStrokeJoin(), ctx.strokeStyle = strokeColor.toCanvasStyle(ctx);
strokeCap = style.getStrokeCap(), ctx.lineWidth = strokeWidth;
miterLimit = style.getMiterLimit(), var strokeJoin = style.getStrokeJoin(),
dashArray = style.getDashArray(), strokeCap = style.getStrokeCap(),
dashOffset = style.getDashOffset(); miterLimit = style.getMiterLimit();
if (strokeJoin) if (strokeJoin)
ctx.lineJoin = strokeJoin; ctx.lineJoin = strokeJoin;
if (strokeCap) if (strokeCap)
ctx.lineCap = strokeCap; ctx.lineCap = strokeCap;
if (miterLimit) if (miterLimit)
ctx.miterLimit = miterLimit; ctx.miterLimit = miterLimit;
if (paper.support.nativeDash && dashArray && dashArray.length) { if (paper.support.nativeDash) {
if ('setLineDash' in ctx) { var dashArray = style.getDashArray(),
ctx.setLineDash(dashArray); dashOffset = style.getDashOffset();
ctx.lineDashOffset = dashOffset; if (dashArray && dashArray.length) {
} else { if ('setLineDash' in ctx) {
ctx.mozDash = dashArray; ctx.setLineDash(dashArray);
ctx.mozDashOffset = dashOffset; ctx.lineDashOffset = dashOffset;
} else {
ctx.mozDash = dashArray;
ctx.mozDashOffset = dashOffset;
}
}
} }
} }
} }
if (shadowColor) { if (shadowColor) {
ctx.shadowColor = shadowColor.toCanvasStyle(ctx); var shadowBlur = style.getShadowBlur();
ctx.shadowBlur = style.getShadowBlur(); if (shadowBlur > 0) {
var offset = this.getShadowOffset(); ctx.shadowColor = shadowColor.toCanvasStyle(ctx);
ctx.shadowOffsetX = offset.x; ctx.shadowBlur = shadowBlur;
ctx.shadowOffsetY = offset.y; var offset = this.getShadowOffset();
ctx.shadowOffsetX = offset.x;
ctx.shadowOffsetY = offset.y;
}
} }
}, },
@ -3894,8 +3916,8 @@ var Shape = Item.extend({
radius: this._radius, radius: this._radius,
insert: false insert: false
}); });
path.transform(this._matrix);
path.setStyle(this._style); path.setStyle(this._style);
path.transform(this._matrix);
if (insert || insert === undefined) if (insert || insert === undefined)
path.insertAbove(this); path.insertAbove(this);
return path; return path;
@ -3951,8 +3973,10 @@ var Shape = Item.extend({
} }
if (!clip && (hasFill || hasStroke)) { if (!clip && (hasFill || hasStroke)) {
this._setStyles(ctx); this._setStyles(ctx);
if (hasFill) if (hasFill) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (hasStroke) if (hasStroke)
ctx.stroke(); ctx.stroke();
} }
@ -5893,7 +5917,7 @@ var PathItem = Item.extend({
setPathData: function(data) { setPathData: function(data) {
var parts = data.match(/[a-z][^a-z]*/ig), var parts = data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig),
coords, coords,
relative = false, relative = false,
control, control,
@ -5915,18 +5939,15 @@ var PathItem = Item.extend({
); );
} }
if (this._type === 'path') this.clear();
this.removeSegments();
else
this.removeChildren();
for (var i = 0, l = parts.length; i < l; i++) { for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i], var part = parts[i],
cmd = part[0], cmd = part[0],
lower = cmd.toLowerCase(); lower = cmd.toLowerCase();
coords = part.slice(1).trim().split(/[\s,]+|(?=[+-])/); coords = part.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g);
var length = coords && coords.length;
relative = cmd === lower; relative = cmd === lower;
var length = coords.length;
switch (lower) { switch (lower) {
case 'm': case 'm':
case 'l': case 'l':
@ -6285,6 +6306,8 @@ var Path = PathItem.extend({
return removed; return removed;
}, },
clear: '#removeSegments',
isFullySelected: function() { isFullySelected: function() {
var length = this._segments.length; var length = this._segments.length;
return this._selected && length > 0 && this._selectedSegmentState return this._selected && length > 0 && this._selectedSegmentState
@ -6880,8 +6903,10 @@ var Path = PathItem.extend({
if (!clip && !compound && (hasFill || hasStroke)) { if (!clip && !compound && (hasFill || hasStroke)) {
this._setStyles(ctx); this._setStyles(ctx);
if (hasFill) if (hasFill) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (hasStroke) { if (hasStroke) {
if (dashLength) { if (dashLength) {
ctx.beginPath(); ctx.beginPath();
@ -7038,16 +7063,16 @@ var Path = PathItem.extend({
cubicCurveTo: function() { cubicCurveTo: function() {
var handle1 = Point.read(arguments), var handle1 = Point.read(arguments),
handle2 = Point.read(arguments), handle2 = Point.read(arguments),
to = Point.read(arguments); to = Point.read(arguments),
var current = getCurrentSegment(this); current = getCurrentSegment(this);
current.setHandleOut(handle1.subtract(current._point)); current.setHandleOut(handle1.subtract(current._point));
this._add([ new Segment(to, handle2.subtract(to)) ]); this._add([ new Segment(to, handle2.subtract(to)) ]);
}, },
quadraticCurveTo: function() { quadraticCurveTo: function() {
var handle = Point.read(arguments), var handle = Point.read(arguments),
to = Point.read(arguments); to = Point.read(arguments),
var current = getCurrentSegment(this)._point; current = getCurrentSegment(this)._point;
this.cubicCurveTo( this.cubicCurveTo(
handle.add(current.subtract(handle).multiply(1 / 3)), handle.add(current.subtract(handle).multiply(1 / 3)),
handle.add(to.subtract(handle).multiply(1 / 3)), handle.add(to.subtract(handle).multiply(1 / 3)),
@ -7126,25 +7151,41 @@ var Path = PathItem.extend({
this._add(segments); this._add(segments);
}, },
lineBy: function(vector) { lineBy: function() {
vector = Point.read(arguments); var to = Point.read(arguments),
var current = getCurrentSegment(this); current = getCurrentSegment(this)._point;
this.lineTo(current._point.add(vector)); this.lineTo(current.add(to));
}, },
curveBy: function(throughVector, toVector, parameter) { curveBy: function() {
throughVector = Point.read(throughVector); var through = Point.read(arguments),
toVector = Point.read(toVector); to = Point.read(arguments),
var current = getCurrentSegment(this)._point; parameter = Base.read(arguments),
this.curveTo(current.add(throughVector), current.add(toVector), current = getCurrentSegment(this)._point;
parameter); this.curveTo(current.add(through), current.add(to), parameter);
}, },
arcBy: function(throughVector, toVector) { cubicCurveBy: function() {
throughVector = Point.read(throughVector); var handle1 = Point.read(arguments),
toVector = Point.read(toVector); handle2 = Point.read(arguments),
var current = getCurrentSegment(this)._point; to = Point.read(arguments),
this.arcTo(current.add(throughVector), current.add(toVector)); current = getCurrentSegment(this)._point;
this.cubicCurveTo(current.add(handle1), current.add(handle2),
current.add(to));
},
quadraticCurveBy: function() {
var handle = Point.read(arguments),
to = Point.read(arguments),
current = getCurrentSegment(this)._point;
this.quadraticCurveTo(current.add(handle), current.add(to));
},
arcBy: function() {
var through = Point.read(arguments),
to = Point.read(arguments),
current = getCurrentSegment(this)._point;
this.arcTo(current.add(through), current.add(to));
}, },
closePath: function() { closePath: function() {
@ -7625,8 +7666,10 @@ var CompoundPath = PathItem.extend({
if (!param.clip) { if (!param.clip) {
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style; var style = this._style;
if (style.hasFill()) if (style.hasFill()) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (style.hasStroke()) if (style.hasStroke())
ctx.stroke(); ctx.stroke();
} }
@ -7655,13 +7698,15 @@ var CompoundPath = PathItem.extend({
} }
}; };
Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', 'arcTo',
'arcTo', 'lineBy', 'curveBy', 'arcBy'], function(key) { 'lineBy', 'cubicCurveBy', 'quadraticCurveBy', 'curveBy', 'arcBy'],
fields[key] = function() { function(key) {
var path = getCurrentPath(this); fields[key] = function() {
path[key].apply(path, arguments); var path = getCurrentPath(this);
}; path[key].apply(path, arguments);
}); };
}
);
return fields; return fields;
}); });
@ -8193,13 +8238,18 @@ var PointText = TextItem.extend({
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style, var style = this._style,
lines = this._lines, lines = this._lines,
leading = style.getLeading(); leading = style.getLeading(),
shadowColor = ctx.shadowColor;
ctx.font = style.getFontStyle(); ctx.font = style.getFontStyle();
ctx.textAlign = style.getJustification(); ctx.textAlign = style.getJustification();
for (var i = 0, l = lines.length; i < l; i++) { for (var i = 0, l = lines.length; i < l; i++) {
ctx.shadowColor = shadowColor;
var line = lines[i]; var line = lines[i];
if (style.hasFill()) if (style.hasFill()) {
ctx.fillText(line, 0, 0); ctx.fillText(line, 0, 0);
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (style.hasStroke()) if (style.hasStroke())
ctx.strokeText(line, 0, 0); ctx.strokeText(line, 0, 0);
ctx.translate(0, leading); ctx.translate(0, leading);
@ -8578,7 +8628,7 @@ var Color = Base.extend(new function() {
}, },
clone: function() { clone: function() {
return new Color(this._type, this._components.slice(), this._alpha); return new Color(this);
}, },
_convert: function(type) { _convert: function(type) {
@ -8666,23 +8716,21 @@ var Color = Base.extend(new function() {
+ components.join(',') + ')'; + components.join(',') + ')';
}, },
toCanvasStyle: function(ctx, matrix) { toCanvasStyle: function(ctx) {
if (this._canvasStyle) if (this._canvasStyle)
return this._canvasStyle; return this._canvasStyle;
if (this._type !== 'gradient') if (this._type !== 'gradient')
return this._canvasStyle = this.toCSS(); return this._canvasStyle = this.toCSS();
var components = this._components, var components = this._components,
translation = matrix ? matrix.getTranslation() : new Point(),
gradient = components[0], gradient = components[0],
stops = gradient._stops, stops = gradient._stops,
origin = components[1].subtract(translation), origin = components[1],
destination = components[2].subtract(translation), destination = components[2],
canvasGradient; canvasGradient;
if (gradient._radial) { if (gradient._radial) {
var radius = destination.getDistance(origin), var radius = destination.getDistance(origin),
highlight = components[3]; highlight = components[3];
if (highlight) { if (highlight) {
highlight = highlight.subtract(translation);
var vector = highlight.subtract(origin); var vector = highlight.subtract(origin);
if (vector.getLength() > radius) if (vector.getLength() > radius)
highlight = origin.add(vector.normalize(radius - 0.1)); highlight = origin.add(vector.normalize(radius - 0.1));
@ -9008,8 +9056,11 @@ var Style = Base.extend(new function() {
if (isColor) { if (isColor) {
if (old) if (old)
delete old._owner; delete old._owner;
if (value && value.constructor === Color) if (value && value.constructor === Color) {
if (value._owner)
value = value.clone();
value._owner = this._item; value._owner = this._item;
}
} }
this._values[key] = value; this._values[key] = value;
if (this._item) if (this._item)
@ -9099,6 +9150,10 @@ var Style = Base.extend(new function() {
return !!this.getStrokeColor() && this.getStrokeWidth() > 0; return !!this.getStrokeColor() && this.getStrokeWidth() > 0;
}, },
hasShadow: function() {
return !!this.getShadowColor() && this.getShadowBlur() > 0;
},
getLeading: function getLeading() { getLeading: function getLeading() {
var leading = getLeading.base.call(this); var leading = getLeading.base.call(this);
return leading != null ? leading : this.getFontSize() * 1.2; return leading != null ? leading : this.getFontSize() * 1.2;
@ -10109,13 +10164,13 @@ new function() {
return attrs; return attrs;
} }
function exportGroup(item) { function exportGroup(item, options) {
var attrs = getTransform(item), var attrs = getTransform(item),
children = item._children; children = item._children;
var node = createElement('g', attrs); var node = createElement('g', attrs);
for (var i = 0, l = children.length; i < l; i++) { for (var i = 0, l = children.length; i < l; i++) {
var child = children[i]; var child = children[i];
var childNode = exportSVG(child); var childNode = exportSVG(child, options);
if (childNode) { if (childNode) {
if (child.isClipMask()) { if (child.isClipMask()) {
var clip = createElement('clipPath'); var clip = createElement('clipPath');
@ -10143,7 +10198,12 @@ new function() {
return createElement('image', attrs); return createElement('image', attrs);
} }
function exportPath(item) { function exportPath(item, options) {
if (options.matchShapes) {
var shape = item.toShape(false);
if (shape)
return exportShape(shape, options);
}
var segments = item._segments, var segments = item._segments,
type, type,
attrs; attrs;
@ -10179,7 +10239,6 @@ new function() {
function exportShape(item) { function exportShape(item) {
var shape = item._shape, var shape = item._shape,
center = item.getPosition(true),
radius = item._radius, radius = item._radius,
attrs = getTransform(item, true, shape !== 'rectangle'); attrs = getTransform(item, true, shape !== 'rectangle');
if (shape === 'rectangle') { if (shape === 'rectangle') {
@ -10213,7 +10272,7 @@ new function() {
return createElement('path', attrs); return createElement('path', attrs);
} }
function exportPlacedSymbol(item) { function exportPlacedSymbol(item, options) {
var attrs = getTransform(item, true), var attrs = getTransform(item, true),
symbol = item.getSymbol(), symbol = item.getSymbol(),
symbolNode = getDefinition(symbol, 'symbol'), symbolNode = getDefinition(symbol, 'symbol'),
@ -10223,7 +10282,7 @@ new function() {
symbolNode = createElement('symbol', { symbolNode = createElement('symbol', {
viewBox: formatter.rectangle(bounds) viewBox: formatter.rectangle(bounds)
}); });
symbolNode.appendChild(exportSVG(definition)); symbolNode.appendChild(exportSVG(definition, options));
setDefinition(symbol, symbolNode, 'symbol'); setDefinition(symbol, symbolNode, 'symbol');
} }
attrs.href = '#' + symbolNode.id; attrs.href = '#' + symbolNode.id;
@ -10234,7 +10293,7 @@ new function() {
return createElement('use', attrs); return createElement('use', attrs);
} }
function exportGradient(color, item) { function exportGradient(color) {
var gradientNode = getDefinition(color, 'color'); var gradientNode = getDefinition(color, 'color');
if (!gradientNode) { if (!gradientNode) {
var gradient = color.getGradient(), var gradient = color.getGradient(),
@ -10358,29 +10417,31 @@ new function() {
} }
function exportDefinitions(node, options) { function exportDefinitions(node, options) {
if (!definitions) var svg = node,
return node;
var svg = node.nodeName.toLowerCase() === 'svg' && node,
defs = null; defs = null;
for (var i in definitions.svgs) { if (definitions) {
if (!defs) { svg = node.nodeName.toLowerCase() === 'svg' && node;
if (!svg) { for (var i in definitions.svgs) {
svg = createElement('svg'); if (!defs) {
svg.appendChild(node); if (!svg) {
svg = createElement('svg');
svg.appendChild(node);
}
defs = svg.insertBefore(createElement('defs'),
svg.firstChild);
} }
defs = svg.insertBefore(createElement('defs'), svg.firstChild); defs.appendChild(definitions.svgs[i]);
} }
defs.appendChild(definitions.svgs[i]); definitions = null;
} }
definitions = null;
return options.asString return options.asString
? new XMLSerializer().serializeToString(svg) ? new XMLSerializer().serializeToString(svg)
: svg; : svg;
} }
function exportSVG(item) { function exportSVG(item, options) {
var exporter = exporters[item._type], var exporter = exporters[item._type],
node = exporter && exporter(item, item._type); node = exporter && exporter(item, options);
if (node && item._data) if (node && item._data)
node.setAttribute('data-paper-data', JSON.stringify(item._data)); node.setAttribute('data-paper-data', JSON.stringify(item._data));
return node && applyStyle(item, node); return node && applyStyle(item, node);
@ -10396,7 +10457,7 @@ new function() {
Item.inject({ Item.inject({
exportSVG: function(options) { exportSVG: function(options) {
options = setOptions(options); options = setOptions(options);
return exportDefinitions(exportSVG(this), options); return exportDefinitions(exportSVG(this, options), options);
} }
}); });
@ -10415,7 +10476,7 @@ new function() {
'xmlns:xlink': 'http://www.w3.org/1999/xlink' 'xmlns:xlink': 'http://www.w3.org/1999/xlink'
}); });
for (var i = 0, l = layers.length; i < l; i++) for (var i = 0, l = layers.length; i < l; i++)
node.appendChild(exportSVG(layers[i])); node.appendChild(exportSVG(layers[i], options));
return exportDefinitions(node, options); return exportDefinitions(node, options);
} }
}); });
@ -10444,15 +10505,15 @@ new function() {
function getPoint(node, x, y, allowNull) { function getPoint(node, x, y, allowNull) {
x = getValue(node, x, false, allowNull); x = getValue(node, x, false, allowNull);
y = getValue(node, y, false, allowNull); y = getValue(node, y, false, allowNull);
return allowNull && x == null && y == null ? null return allowNull && (x == null || y == null) ? null
: new Point(x || 0, y || 0); : new Point(x, y);
} }
function getSize(node, w, h, allowNull) { function getSize(node, w, h, allowNull) {
w = getValue(node, w, false, allowNull); w = getValue(node, w, false, allowNull);
h = getValue(node, h, false, allowNull); h = getValue(node, h, false, allowNull);
return allowNull && w == null && h == null ? null return allowNull && (w == null || h == null) ? null
: new Size(w || 0, h || 0); : new Size(w, h);
} }
function convertValue(value, type, lookup) { function convertValue(value, type, lookup) {
@ -10469,7 +10530,7 @@ new function() {
: value; : value;
} }
function importGroup(node, type, options) { function importGroup(node, type, isRoot, options) {
var nodes = node.childNodes, var nodes = node.childNodes,
clip = type === 'clippath', clip = type === 'clippath',
item = new Group(), item = new Group(),
@ -10478,20 +10539,20 @@ new function() {
children = []; children = [];
if (!clip) { if (!clip) {
item._transformContent = false; item._transformContent = false;
item = applyAttributes(item, node); item = applyAttributes(item, node, isRoot);
project._currentStyle = item._style.clone(); project._currentStyle = item._style.clone();
} }
for (var i = 0, l = nodes.length; i < l; i++) { for (var i = 0, l = nodes.length; i < l; i++) {
var childNode = nodes[i], var childNode = nodes[i],
child; child;
if (childNode.nodeType === 1 if (childNode.nodeType === 1
&& (child = importSVG(childNode, options)) && (child = importSVG(childNode, false, options))
&& !(child instanceof Symbol)) && !(child instanceof Symbol))
children.push(child); children.push(child);
} }
item.addChildren(children); item.addChildren(children);
if (clip) if (clip)
item = applyAttributes(item.reduce(), node); item = applyAttributes(item.reduce(), node, isRoot);
project._currentStyle = currentStyle; project._currentStyle = currentStyle;
if (clip || type === 'defs') { if (clip || type === 'defs') {
item.remove(); item.remove();
@ -10545,8 +10606,8 @@ new function() {
} }
var importers = { var importers = {
'#document': function(node, type, options) { '#document': function(node, type, isRoot, options) {
return importSVG(node.childNodes[0], options); return importSVG(node.childNodes[0], isRoot, options);
}, },
g: importGroup, g: importGroup,
@ -10568,8 +10629,8 @@ new function() {
return raster; return raster;
}, },
symbol: function(node, type) { symbol: function(node, type, isRoot, options) {
return new Symbol(importGroup(node, type), true); return new Symbol(importGroup(node, type, isRoot, options), true);
}, },
defs: importGroup, defs: importGroup,
@ -10663,8 +10724,13 @@ new function() {
var attributes = Base.merge(Base.each(SVGStyles, function(entry) { var attributes = Base.merge(Base.each(SVGStyles, function(entry) {
this[entry.attribute] = function(item, value) { this[entry.attribute] = function(item, value) {
item[entry.set]( item[entry.set](convertValue(value, entry.type, entry.fromSVG));
convertValue(value, entry.type, entry.fromSVG)); if (entry.type === 'color' && item instanceof Shape) {
var color = item[entry.get]();
if (color)
color.transform(new Matrix().translate(
item.getPosition(true).negate()));
}
}; };
}, {}), { }, {}), {
id: function(item, value) { id: function(item, value) {
@ -10750,10 +10816,10 @@ new function() {
: value; : value;
} }
function applyAttributes(item, node) { function applyAttributes(item, node, isRoot) {
var styles = { var styles = {
node: DomElement.getStyles(node) || {}, node: DomElement.getStyles(node) || {},
parent: DomElement.getStyles(node.parentNode) || {} parent: !isRoot && DomElement.getStyles(node.parentNode) || {}
}; };
Base.each(attributes, function(apply, name) { Base.each(attributes, function(apply, name) {
var value = getAttribute(node, name, styles); var value = getAttribute(node, name, styles);
@ -10769,38 +10835,55 @@ new function() {
return match && definitions[match[1]]; return match && definitions[match[1]];
} }
function importSVG(node, options, clearDefs) { function importSVG(node, isRoot, options) {
if (!options) if (!options)
options = {}; options = {};
if (typeof node === 'string') if (typeof node === 'string') {
if (isRoot && !/^.*</.test(node)) {
if (typeof options === 'function')
options = { onLoad: options };
var scope = paper;
return Http.request('get', node, function(svg) {
paper = scope;
var item = importSVG(svg, isRoot, options),
onLoad = options.onLoad,
view = scope.project && scope.project.view;
if (onLoad)
onLoad.call(this, item);
view.draw(true);
});
}
node = new DOMParser().parseFromString(node, 'image/svg+xml'); node = new DOMParser().parseFromString(node, 'image/svg+xml');
}
var type = node.nodeName.toLowerCase(), var type = node.nodeName.toLowerCase(),
importer = importers[type], importer = importers[type],
item = importer && importer(node, type, options), item = importer && importer(node, type, isRoot, options),
data = type !== '#document' && node.getAttribute('data-paper-data'); data = type !== '#document' && node.getAttribute('data-paper-data');
if (options.expandShapes && item instanceof Shape) { if (item) {
item.remove(); if (!(item instanceof Group))
item = item.toPath(); item = applyAttributes(item, node, isRoot);
if (options.expandShapes && item instanceof Shape) {
item.remove();
item = item.toPath();
}
if (data)
item._data = JSON.parse(data);
} }
if (item && !(item instanceof Group)) if (isRoot)
item = applyAttributes(item, node);
if (item && data)
item._data = JSON.parse(data);
if (clearDefs)
definitions = {}; definitions = {};
return item; return item;
} }
Item.inject({ Item.inject({
importSVG: function(node, options) { importSVG: function(node, options) {
return this.addChild(importSVG(node, options, true)); return this.addChild(importSVG(node, true, options));
} }
}); });
Project.inject({ Project.inject({
importSVG: function(node, options) { importSVG: function(node, options) {
this.activate(); this.activate();
return importSVG(node, options, true); return importSVG(node, true, options);
} }
}); });
}; };

495
dist/paper.js vendored
View file

@ -1,5 +1,5 @@
/*! /*!
* Paper.js v0.9.10 - The Swiss Army Knife of Vector Graphics Scripting. * Paper.js v0.9.11 - The Swiss Army Knife of Vector Graphics Scripting.
* http://paperjs.org/ * http://paperjs.org/
* *
* Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey * Copyright (c) 2011 - 2013, Juerg Lehni & Jonathan Puckey
@ -9,7 +9,7 @@
* *
* All rights reserved. * All rights reserved.
* *
* Date: Tue Oct 29 21:56:00 2013 +0100 * Date: Sat Nov 2 21:26:32 2013 +0100
* *
*** ***
* *
@ -466,31 +466,33 @@ Base.inject({
: res; : res;
}, },
deserialize: function(obj, data) { deserialize: function(json, target, _data) {
var res = obj; var res = json;
data = data || {}; _data = _data || {};
if (Array.isArray(obj)) { if (Array.isArray(json)) {
var type = obj[0], var type = json[0],
isDictionary = type === 'dictionary'; isDictionary = type === 'dictionary';
if (!isDictionary) { if (!isDictionary) {
if (data.dictionary && obj.length == 1 && /^#/.test(type)) if (_data.dictionary && json.length == 1 && /^#/.test(type))
return data.dictionary[type]; return _data.dictionary[type];
type = Base.exports[type]; type = Base.exports[type];
} }
res = []; res = [];
for (var i = type ? 1 : 0, l = obj.length; i < l; i++) for (var i = type ? 1 : 0, l = json.length; i < l; i++)
res.push(Base.deserialize(obj[i], data)); res.push(Base.deserialize(json[i], null, _data));
if (isDictionary) { if (isDictionary) {
data.dictionary = res[0]; _data.dictionary = res[0];
} else if (type) { } else if (type) {
var args = res; var args = res;
res = Base.create(type.prototype); res = target instanceof type
? target
: Base.create(type.prototype);
type.apply(res, args); type.apply(res, args);
} }
} else if (Base.isPlainObject(obj)) { } else if (Base.isPlainObject(json)) {
res = {}; res = {};
for (var key in obj) for (var key in json)
res[key] = Base.deserialize(obj[key], data); res[key] = Base.deserialize(json[key], null, _data);
} }
return res; return res;
}, },
@ -499,9 +501,9 @@ Base.inject({
return JSON.stringify(Base.serialize(obj, options)); return JSON.stringify(Base.serialize(obj, options));
}, },
importJSON: function(json) { importJSON: function(json, target) {
return Base.deserialize( return Base.deserialize(
typeof json === 'string' ? JSON.parse(json) : json); typeof json === 'string' ? JSON.parse(json) : json, target);
}, },
splice: function(list, items, index, remove) { splice: function(list, items, index, remove) {
@ -682,7 +684,7 @@ var PaperScope = Base.extend({
} }
}, },
version: '0.9.10', version: '0.9.11',
getView: function() { getView: function() {
return this.project && this.project.view; return this.project && this.project.view;
@ -694,6 +696,10 @@ var PaperScope = Base.extend({
return this._tool; return this._tool;
}, },
getPaper: function() {
return this;
},
evaluate: function(code) { evaluate: function(code) {
var res = paper.PaperScript.evaluate(code, this); var res = paper.PaperScript.evaluate(code, this);
View.updateFocus(); View.updateFocus();
@ -2009,10 +2015,10 @@ var Matrix = Base.extend({
return !this._getDeterminant(); return !this._getDeterminant();
}, },
transform: function( src, srcOff, dst, dstOff, numPts) { transform: function( src, srcOffset, dst, dstOffset, count) {
return arguments.length < 5 return arguments.length < 5
? this._transformPoint(Point.read(arguments)) ? this._transformPoint(Point.read(arguments))
: this._transformCoordinates(src, srcOff, dst, dstOff, numPts); : this._transformCoordinates(src, srcOffset, dst, dstOffset, count);
}, },
_transformPoint: function(point, dest, dontNotify) { _transformPoint: function(point, dest, dontNotify) {
@ -2027,10 +2033,11 @@ var Matrix = Base.extend({
); );
}, },
_transformCoordinates: function(src, srcOff, dst, dstOff, numPts) { _transformCoordinates: function(src, srcOffset, dst, dstOffset, count) {
var i = srcOff, j = dstOff, var i = srcOffset,
srcEnd = srcOff + 2 * numPts; j = dstOffset,
while (i < srcEnd) { max = i + 2 * count;
while (i < max) {
var x = src[i++], var x = src[i++],
y = src[i++]; y = src[i++];
dst[j++] = x * this._a + y * this._b + this._tx; dst[j++] = x * this._a + y * this._b + this._tx;
@ -2736,6 +2743,10 @@ var Item = Base.extend(Callback, {
hasStroke: function() { hasStroke: function() {
return this.getStyle().hasStroke(); return this.getStyle().hasStroke();
},
hasShadow: function() {
return this.getStyle().hasShadow();
} }
}, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'], }, Base.each(['locked', 'visible', 'blendMode', 'opacity', 'guide'],
function(name) { function(name) {
@ -3251,7 +3262,10 @@ var Item = Base.extend(Callback, {
}, { }, {
importJSON: function(json) { importJSON: function(json) {
return this.addChild(Base.importJSON(json)); var res = Base.importJSON(json, this);
return res !== this
? this.addChild(res)
: res;
}, },
addChild: function(item, _preserve) { addChild: function(item, _preserve) {
@ -3387,6 +3401,8 @@ var Item = Base.extend(Callback, {
return removed; return removed;
}, },
clear: '#removeChildren',
reverseChildren: function() { reverseChildren: function() {
if (this._children) { if (this._children) {
this._children.reverse(); this._children.reverse();
@ -3561,43 +3577,49 @@ var Item = Base.extend(Callback, {
_setStyles: function(ctx) { _setStyles: function(ctx) {
var style = this._style, var style = this._style,
matrix = this._matrix,
strokeWidth = style.getStrokeWidth(),
fillColor = style.getFillColor(), fillColor = style.getFillColor(),
strokeColor = style.getStrokeColor(), strokeColor = style.getStrokeColor(),
shadowColor = style.getShadowColor(); shadowColor = style.getShadowColor();
if (fillColor) if (fillColor)
ctx.fillStyle = fillColor.toCanvasStyle(ctx, matrix); ctx.fillStyle = fillColor.toCanvasStyle(ctx);
if (strokeColor && strokeWidth > 0) { if (strokeColor) {
ctx.strokeStyle = strokeColor.toCanvasStyle(ctx, matrix); var strokeWidth = style.getStrokeWidth();
ctx.lineWidth = strokeWidth; if (strokeWidth > 0) {
var strokeJoin = style.getStrokeJoin(), ctx.strokeStyle = strokeColor.toCanvasStyle(ctx);
strokeCap = style.getStrokeCap(), ctx.lineWidth = strokeWidth;
miterLimit = style.getMiterLimit(), var strokeJoin = style.getStrokeJoin(),
dashArray = style.getDashArray(), strokeCap = style.getStrokeCap(),
dashOffset = style.getDashOffset(); miterLimit = style.getMiterLimit();
if (strokeJoin) if (strokeJoin)
ctx.lineJoin = strokeJoin; ctx.lineJoin = strokeJoin;
if (strokeCap) if (strokeCap)
ctx.lineCap = strokeCap; ctx.lineCap = strokeCap;
if (miterLimit) if (miterLimit)
ctx.miterLimit = miterLimit; ctx.miterLimit = miterLimit;
if (paper.support.nativeDash && dashArray && dashArray.length) { if (paper.support.nativeDash) {
if ('setLineDash' in ctx) { var dashArray = style.getDashArray(),
ctx.setLineDash(dashArray); dashOffset = style.getDashOffset();
ctx.lineDashOffset = dashOffset; if (dashArray && dashArray.length) {
} else { if ('setLineDash' in ctx) {
ctx.mozDash = dashArray; ctx.setLineDash(dashArray);
ctx.mozDashOffset = dashOffset; ctx.lineDashOffset = dashOffset;
} else {
ctx.mozDash = dashArray;
ctx.mozDashOffset = dashOffset;
}
}
} }
} }
} }
if (shadowColor) { if (shadowColor) {
ctx.shadowColor = shadowColor.toCanvasStyle(ctx); var shadowBlur = style.getShadowBlur();
ctx.shadowBlur = style.getShadowBlur(); if (shadowBlur > 0) {
var offset = this.getShadowOffset(); ctx.shadowColor = shadowColor.toCanvasStyle(ctx);
ctx.shadowOffsetX = offset.x; ctx.shadowBlur = shadowBlur;
ctx.shadowOffsetY = offset.y; var offset = this.getShadowOffset();
ctx.shadowOffsetX = offset.x;
ctx.shadowOffsetY = offset.y;
}
} }
}, },
@ -3894,8 +3916,8 @@ var Shape = Item.extend({
radius: this._radius, radius: this._radius,
insert: false insert: false
}); });
path.transform(this._matrix);
path.setStyle(this._style); path.setStyle(this._style);
path.transform(this._matrix);
if (insert || insert === undefined) if (insert || insert === undefined)
path.insertAbove(this); path.insertAbove(this);
return path; return path;
@ -3951,8 +3973,10 @@ var Shape = Item.extend({
} }
if (!clip && (hasFill || hasStroke)) { if (!clip && (hasFill || hasStroke)) {
this._setStyles(ctx); this._setStyles(ctx);
if (hasFill) if (hasFill) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (hasStroke) if (hasStroke)
ctx.stroke(); ctx.stroke();
} }
@ -5912,7 +5936,7 @@ var PathItem = Item.extend({
setPathData: function(data) { setPathData: function(data) {
var parts = data.match(/[a-z][^a-z]*/ig), var parts = data.match(/[mlhvcsqtaz][^mlhvcsqtaz]*/ig),
coords, coords,
relative = false, relative = false,
control, control,
@ -5934,18 +5958,15 @@ var PathItem = Item.extend({
); );
} }
if (this._type === 'path') this.clear();
this.removeSegments();
else
this.removeChildren();
for (var i = 0, l = parts.length; i < l; i++) { for (var i = 0, l = parts.length; i < l; i++) {
var part = parts[i], var part = parts[i],
cmd = part[0], cmd = part[0],
lower = cmd.toLowerCase(); lower = cmd.toLowerCase();
coords = part.slice(1).trim().split(/[\s,]+|(?=[+-])/); coords = part.match(/[+-]?(?:\d*\.\d+|\d+\.?)(?:[eE][+-]?\d+)?/g);
var length = coords && coords.length;
relative = cmd === lower; relative = cmd === lower;
var length = coords.length;
switch (lower) { switch (lower) {
case 'm': case 'm':
case 'l': case 'l':
@ -6304,6 +6325,8 @@ var Path = PathItem.extend({
return removed; return removed;
}, },
clear: '#removeSegments',
isFullySelected: function() { isFullySelected: function() {
var length = this._segments.length; var length = this._segments.length;
return this._selected && length > 0 && this._selectedSegmentState return this._selected && length > 0 && this._selectedSegmentState
@ -6899,8 +6922,10 @@ var Path = PathItem.extend({
if (!clip && !compound && (hasFill || hasStroke)) { if (!clip && !compound && (hasFill || hasStroke)) {
this._setStyles(ctx); this._setStyles(ctx);
if (hasFill) if (hasFill) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (hasStroke) { if (hasStroke) {
if (dashLength) { if (dashLength) {
ctx.beginPath(); ctx.beginPath();
@ -7057,16 +7082,16 @@ var Path = PathItem.extend({
cubicCurveTo: function() { cubicCurveTo: function() {
var handle1 = Point.read(arguments), var handle1 = Point.read(arguments),
handle2 = Point.read(arguments), handle2 = Point.read(arguments),
to = Point.read(arguments); to = Point.read(arguments),
var current = getCurrentSegment(this); current = getCurrentSegment(this);
current.setHandleOut(handle1.subtract(current._point)); current.setHandleOut(handle1.subtract(current._point));
this._add([ new Segment(to, handle2.subtract(to)) ]); this._add([ new Segment(to, handle2.subtract(to)) ]);
}, },
quadraticCurveTo: function() { quadraticCurveTo: function() {
var handle = Point.read(arguments), var handle = Point.read(arguments),
to = Point.read(arguments); to = Point.read(arguments),
var current = getCurrentSegment(this)._point; current = getCurrentSegment(this)._point;
this.cubicCurveTo( this.cubicCurveTo(
handle.add(current.subtract(handle).multiply(1 / 3)), handle.add(current.subtract(handle).multiply(1 / 3)),
handle.add(to.subtract(handle).multiply(1 / 3)), handle.add(to.subtract(handle).multiply(1 / 3)),
@ -7145,25 +7170,41 @@ var Path = PathItem.extend({
this._add(segments); this._add(segments);
}, },
lineBy: function(vector) { lineBy: function() {
vector = Point.read(arguments); var to = Point.read(arguments),
var current = getCurrentSegment(this); current = getCurrentSegment(this)._point;
this.lineTo(current._point.add(vector)); this.lineTo(current.add(to));
}, },
curveBy: function(throughVector, toVector, parameter) { curveBy: function() {
throughVector = Point.read(throughVector); var through = Point.read(arguments),
toVector = Point.read(toVector); to = Point.read(arguments),
var current = getCurrentSegment(this)._point; parameter = Base.read(arguments),
this.curveTo(current.add(throughVector), current.add(toVector), current = getCurrentSegment(this)._point;
parameter); this.curveTo(current.add(through), current.add(to), parameter);
}, },
arcBy: function(throughVector, toVector) { cubicCurveBy: function() {
throughVector = Point.read(throughVector); var handle1 = Point.read(arguments),
toVector = Point.read(toVector); handle2 = Point.read(arguments),
var current = getCurrentSegment(this)._point; to = Point.read(arguments),
this.arcTo(current.add(throughVector), current.add(toVector)); current = getCurrentSegment(this)._point;
this.cubicCurveTo(current.add(handle1), current.add(handle2),
current.add(to));
},
quadraticCurveBy: function() {
var handle = Point.read(arguments),
to = Point.read(arguments),
current = getCurrentSegment(this)._point;
this.quadraticCurveTo(current.add(handle), current.add(to));
},
arcBy: function() {
var through = Point.read(arguments),
to = Point.read(arguments),
current = getCurrentSegment(this)._point;
this.arcTo(current.add(through), current.add(to));
}, },
closePath: function() { closePath: function() {
@ -7644,8 +7685,10 @@ var CompoundPath = PathItem.extend({
if (!param.clip) { if (!param.clip) {
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style; var style = this._style;
if (style.hasFill()) if (style.hasFill()) {
ctx.fill(style.getWindingRule()); ctx.fill(style.getWindingRule());
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (style.hasStroke()) if (style.hasStroke())
ctx.stroke(); ctx.stroke();
} }
@ -7674,13 +7717,15 @@ var CompoundPath = PathItem.extend({
} }
}; };
Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo', 'arcTo',
'arcTo', 'lineBy', 'curveBy', 'arcBy'], function(key) { 'lineBy', 'cubicCurveBy', 'quadraticCurveBy', 'curveBy', 'arcBy'],
fields[key] = function() { function(key) {
var path = getCurrentPath(this); fields[key] = function() {
path[key].apply(path, arguments); var path = getCurrentPath(this);
}; path[key].apply(path, arguments);
}); };
}
);
return fields; return fields;
}); });
@ -8212,13 +8257,18 @@ var PointText = TextItem.extend({
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style, var style = this._style,
lines = this._lines, lines = this._lines,
leading = style.getLeading(); leading = style.getLeading(),
shadowColor = ctx.shadowColor;
ctx.font = style.getFontStyle(); ctx.font = style.getFontStyle();
ctx.textAlign = style.getJustification(); ctx.textAlign = style.getJustification();
for (var i = 0, l = lines.length; i < l; i++) { for (var i = 0, l = lines.length; i < l; i++) {
ctx.shadowColor = shadowColor;
var line = lines[i]; var line = lines[i];
if (style.hasFill()) if (style.hasFill()) {
ctx.fillText(line, 0, 0); ctx.fillText(line, 0, 0);
ctx.shadowColor = 'rgba(0,0,0,0)';
}
if (style.hasStroke()) if (style.hasStroke())
ctx.strokeText(line, 0, 0); ctx.strokeText(line, 0, 0);
ctx.translate(0, leading); ctx.translate(0, leading);
@ -8597,7 +8647,7 @@ var Color = Base.extend(new function() {
}, },
clone: function() { clone: function() {
return new Color(this._type, this._components.slice(), this._alpha); return new Color(this);
}, },
_convert: function(type) { _convert: function(type) {
@ -8685,23 +8735,21 @@ var Color = Base.extend(new function() {
+ components.join(',') + ')'; + components.join(',') + ')';
}, },
toCanvasStyle: function(ctx, matrix) { toCanvasStyle: function(ctx) {
if (this._canvasStyle) if (this._canvasStyle)
return this._canvasStyle; return this._canvasStyle;
if (this._type !== 'gradient') if (this._type !== 'gradient')
return this._canvasStyle = this.toCSS(); return this._canvasStyle = this.toCSS();
var components = this._components, var components = this._components,
translation = matrix ? matrix.getTranslation() : new Point(),
gradient = components[0], gradient = components[0],
stops = gradient._stops, stops = gradient._stops,
origin = components[1].subtract(translation), origin = components[1],
destination = components[2].subtract(translation), destination = components[2],
canvasGradient; canvasGradient;
if (gradient._radial) { if (gradient._radial) {
var radius = destination.getDistance(origin), var radius = destination.getDistance(origin),
highlight = components[3]; highlight = components[3];
if (highlight) { if (highlight) {
highlight = highlight.subtract(translation);
var vector = highlight.subtract(origin); var vector = highlight.subtract(origin);
if (vector.getLength() > radius) if (vector.getLength() > radius)
highlight = origin.add(vector.normalize(radius - 0.1)); highlight = origin.add(vector.normalize(radius - 0.1));
@ -9027,8 +9075,11 @@ var Style = Base.extend(new function() {
if (isColor) { if (isColor) {
if (old) if (old)
delete old._owner; delete old._owner;
if (value && value.constructor === Color) if (value && value.constructor === Color) {
if (value._owner)
value = value.clone();
value._owner = this._item; value._owner = this._item;
}
} }
this._values[key] = value; this._values[key] = value;
if (this._item) if (this._item)
@ -9118,6 +9169,10 @@ var Style = Base.extend(new function() {
return !!this.getStrokeColor() && this.getStrokeWidth() > 0; return !!this.getStrokeColor() && this.getStrokeWidth() > 0;
}, },
hasShadow: function() {
return !!this.getShadowColor() && this.getShadowBlur() > 0;
},
getLeading: function getLeading() { getLeading: function getLeading() {
var leading = getLeading.base.call(this); var leading = getLeading.base.call(this);
return leading != null ? leading : this.getFontSize() * 1.2; return leading != null ? leading : this.getFontSize() * 1.2;
@ -9377,18 +9432,10 @@ var DomEvent = {
}; };
DomEvent.requestAnimationFrame = new function() { DomEvent.requestAnimationFrame = new function() {
var part = 'equestAnimationFrame', var nativeRequest = DomElement.getPrefixValue(window,
request = window['r' + part] || window['webkitR' + part] 'requestAnimationFrame'),
|| window['mozR' + part] || window['oR' + part] requested = false,
|| window['msR' + part]; callbacks = [],
if (request) {
request(function(time) {
if (time == null)
request = null;
});
}
var callbacks = [],
focused = true, focused = true,
timer; timer;
@ -9401,24 +9448,36 @@ DomEvent.requestAnimationFrame = new function() {
} }
}); });
return function(callback, element) { function handleCallbacks() {
if (request) for (var i = callbacks.length - 1; i >= 0; i--) {
return request(callback, element); var entry = callbacks[i],
callbacks.push([callback, element]); func = entry[0],
if (timer) el = entry[1];
return; if (!el || (PaperScope.getAttribute(el, 'keepalive') == 'true'
timer = setInterval(function() { || focused) && DomElement.isInView(el)) {
for (var i = callbacks.length - 1; i >= 0; i--) { callbacks.splice(i, 1);
var entry = callbacks[i], func();
func = entry[0],
el = entry[1];
if (!el || (PaperScope.getAttribute(el, 'keepalive') == 'true'
|| focused) && DomElement.isInView(el)) {
callbacks.splice(i, 1);
func(Date.now());
}
} }
}, 1000 / 60); }
if (nativeRequest) {
if (callbacks.length) {
nativeRequest(handleCallbacks);
} else {
requested = false;
}
}
}
return function(callback, element) {
callbacks.push([callback, element]);
if (nativeRequest) {
if (!requested) {
nativeRequest(handleCallbacks);
requested = true;
}
} else if (!timer) {
timer = setInterval(handleCallbacks, 1000 / 60);
}
}; };
}; };
@ -10005,6 +10064,7 @@ var Key = new function() {
tool = scope && scope._tool; tool = scope && scope._tool;
keyMap[key] = down; keyMap[key] = down;
if (tool && tool.responds(type)) { if (tool && tool.responds(type)) {
paper = scope;
tool.fire(type, new KeyEvent(down, key, character, event)); tool.fire(type, new KeyEvent(down, key, character, event));
if (view) if (view)
view.draw(true); view.draw(true);
@ -10545,6 +10605,28 @@ var Tool = PaperScopeItem.extend({
}); });
var Http = {
request: function(method, url, callback) {
var xhr = new (window.ActiveXObject || XMLHttpRequest)(
'Microsoft.XMLHTTP');
xhr.open(method.toUpperCase(), url, true);
if ('overrideMimeType' in xhr)
xhr.overrideMimeType('text/plain');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
var status = xhr.status;
if (status === 0 || status === 200) {
callback.call(xhr, xhr.responseText);
} else {
throw new Error('Could not load ' + url + ' (Error '
+ status + ')');
}
}
};
return xhr.send(null);
}
};
var CanvasProvider = { var CanvasProvider = {
canvases: [], canvases: [],
@ -10920,13 +11002,13 @@ new function() {
return attrs; return attrs;
} }
function exportGroup(item) { function exportGroup(item, options) {
var attrs = getTransform(item), var attrs = getTransform(item),
children = item._children; children = item._children;
var node = createElement('g', attrs); var node = createElement('g', attrs);
for (var i = 0, l = children.length; i < l; i++) { for (var i = 0, l = children.length; i < l; i++) {
var child = children[i]; var child = children[i];
var childNode = exportSVG(child); var childNode = exportSVG(child, options);
if (childNode) { if (childNode) {
if (child.isClipMask()) { if (child.isClipMask()) {
var clip = createElement('clipPath'); var clip = createElement('clipPath');
@ -10954,7 +11036,12 @@ new function() {
return createElement('image', attrs); return createElement('image', attrs);
} }
function exportPath(item) { function exportPath(item, options) {
if (options.matchShapes) {
var shape = item.toShape(false);
if (shape)
return exportShape(shape, options);
}
var segments = item._segments, var segments = item._segments,
type, type,
attrs; attrs;
@ -10990,7 +11077,6 @@ new function() {
function exportShape(item) { function exportShape(item) {
var shape = item._shape, var shape = item._shape,
center = item.getPosition(true),
radius = item._radius, radius = item._radius,
attrs = getTransform(item, true, shape !== 'rectangle'); attrs = getTransform(item, true, shape !== 'rectangle');
if (shape === 'rectangle') { if (shape === 'rectangle') {
@ -11024,7 +11110,7 @@ new function() {
return createElement('path', attrs); return createElement('path', attrs);
} }
function exportPlacedSymbol(item) { function exportPlacedSymbol(item, options) {
var attrs = getTransform(item, true), var attrs = getTransform(item, true),
symbol = item.getSymbol(), symbol = item.getSymbol(),
symbolNode = getDefinition(symbol, 'symbol'), symbolNode = getDefinition(symbol, 'symbol'),
@ -11034,7 +11120,7 @@ new function() {
symbolNode = createElement('symbol', { symbolNode = createElement('symbol', {
viewBox: formatter.rectangle(bounds) viewBox: formatter.rectangle(bounds)
}); });
symbolNode.appendChild(exportSVG(definition)); symbolNode.appendChild(exportSVG(definition, options));
setDefinition(symbol, symbolNode, 'symbol'); setDefinition(symbol, symbolNode, 'symbol');
} }
attrs.href = '#' + symbolNode.id; attrs.href = '#' + symbolNode.id;
@ -11045,7 +11131,7 @@ new function() {
return createElement('use', attrs); return createElement('use', attrs);
} }
function exportGradient(color, item) { function exportGradient(color) {
var gradientNode = getDefinition(color, 'color'); var gradientNode = getDefinition(color, 'color');
if (!gradientNode) { if (!gradientNode) {
var gradient = color.getGradient(), var gradient = color.getGradient(),
@ -11169,29 +11255,31 @@ new function() {
} }
function exportDefinitions(node, options) { function exportDefinitions(node, options) {
if (!definitions) var svg = node,
return node;
var svg = node.nodeName.toLowerCase() === 'svg' && node,
defs = null; defs = null;
for (var i in definitions.svgs) { if (definitions) {
if (!defs) { svg = node.nodeName.toLowerCase() === 'svg' && node;
if (!svg) { for (var i in definitions.svgs) {
svg = createElement('svg'); if (!defs) {
svg.appendChild(node); if (!svg) {
svg = createElement('svg');
svg.appendChild(node);
}
defs = svg.insertBefore(createElement('defs'),
svg.firstChild);
} }
defs = svg.insertBefore(createElement('defs'), svg.firstChild); defs.appendChild(definitions.svgs[i]);
} }
defs.appendChild(definitions.svgs[i]); definitions = null;
} }
definitions = null;
return options.asString return options.asString
? new XMLSerializer().serializeToString(svg) ? new XMLSerializer().serializeToString(svg)
: svg; : svg;
} }
function exportSVG(item) { function exportSVG(item, options) {
var exporter = exporters[item._type], var exporter = exporters[item._type],
node = exporter && exporter(item, item._type); node = exporter && exporter(item, options);
if (node && item._data) if (node && item._data)
node.setAttribute('data-paper-data', JSON.stringify(item._data)); node.setAttribute('data-paper-data', JSON.stringify(item._data));
return node && applyStyle(item, node); return node && applyStyle(item, node);
@ -11207,7 +11295,7 @@ new function() {
Item.inject({ Item.inject({
exportSVG: function(options) { exportSVG: function(options) {
options = setOptions(options); options = setOptions(options);
return exportDefinitions(exportSVG(this), options); return exportDefinitions(exportSVG(this, options), options);
} }
}); });
@ -11226,7 +11314,7 @@ new function() {
'xmlns:xlink': 'http://www.w3.org/1999/xlink' 'xmlns:xlink': 'http://www.w3.org/1999/xlink'
}); });
for (var i = 0, l = layers.length; i < l; i++) for (var i = 0, l = layers.length; i < l; i++)
node.appendChild(exportSVG(layers[i])); node.appendChild(exportSVG(layers[i], options));
return exportDefinitions(node, options); return exportDefinitions(node, options);
} }
}); });
@ -11255,15 +11343,15 @@ new function() {
function getPoint(node, x, y, allowNull) { function getPoint(node, x, y, allowNull) {
x = getValue(node, x, false, allowNull); x = getValue(node, x, false, allowNull);
y = getValue(node, y, false, allowNull); y = getValue(node, y, false, allowNull);
return allowNull && x == null && y == null ? null return allowNull && (x == null || y == null) ? null
: new Point(x || 0, y || 0); : new Point(x, y);
} }
function getSize(node, w, h, allowNull) { function getSize(node, w, h, allowNull) {
w = getValue(node, w, false, allowNull); w = getValue(node, w, false, allowNull);
h = getValue(node, h, false, allowNull); h = getValue(node, h, false, allowNull);
return allowNull && w == null && h == null ? null return allowNull && (w == null || h == null) ? null
: new Size(w || 0, h || 0); : new Size(w, h);
} }
function convertValue(value, type, lookup) { function convertValue(value, type, lookup) {
@ -11280,7 +11368,7 @@ new function() {
: value; : value;
} }
function importGroup(node, type, options) { function importGroup(node, type, isRoot, options) {
var nodes = node.childNodes, var nodes = node.childNodes,
clip = type === 'clippath', clip = type === 'clippath',
item = new Group(), item = new Group(),
@ -11289,20 +11377,20 @@ new function() {
children = []; children = [];
if (!clip) { if (!clip) {
item._transformContent = false; item._transformContent = false;
item = applyAttributes(item, node); item = applyAttributes(item, node, isRoot);
project._currentStyle = item._style.clone(); project._currentStyle = item._style.clone();
} }
for (var i = 0, l = nodes.length; i < l; i++) { for (var i = 0, l = nodes.length; i < l; i++) {
var childNode = nodes[i], var childNode = nodes[i],
child; child;
if (childNode.nodeType === 1 if (childNode.nodeType === 1
&& (child = importSVG(childNode, options)) && (child = importSVG(childNode, false, options))
&& !(child instanceof Symbol)) && !(child instanceof Symbol))
children.push(child); children.push(child);
} }
item.addChildren(children); item.addChildren(children);
if (clip) if (clip)
item = applyAttributes(item.reduce(), node); item = applyAttributes(item.reduce(), node, isRoot);
project._currentStyle = currentStyle; project._currentStyle = currentStyle;
if (clip || type === 'defs') { if (clip || type === 'defs') {
item.remove(); item.remove();
@ -11356,8 +11444,8 @@ new function() {
} }
var importers = { var importers = {
'#document': function(node, type, options) { '#document': function(node, type, isRoot, options) {
return importSVG(node.childNodes[0], options); return importSVG(node.childNodes[0], isRoot, options);
}, },
g: importGroup, g: importGroup,
@ -11379,8 +11467,8 @@ new function() {
return raster; return raster;
}, },
symbol: function(node, type) { symbol: function(node, type, isRoot, options) {
return new Symbol(importGroup(node, type), true); return new Symbol(importGroup(node, type, isRoot, options), true);
}, },
defs: importGroup, defs: importGroup,
@ -11474,8 +11562,13 @@ new function() {
var attributes = Base.merge(Base.each(SVGStyles, function(entry) { var attributes = Base.merge(Base.each(SVGStyles, function(entry) {
this[entry.attribute] = function(item, value) { this[entry.attribute] = function(item, value) {
item[entry.set]( item[entry.set](convertValue(value, entry.type, entry.fromSVG));
convertValue(value, entry.type, entry.fromSVG)); if (entry.type === 'color' && item instanceof Shape) {
var color = item[entry.get]();
if (color)
color.transform(new Matrix().translate(
item.getPosition(true).negate()));
}
}; };
}, {}), { }, {}), {
id: function(item, value) { id: function(item, value) {
@ -11561,10 +11654,10 @@ new function() {
: value; : value;
} }
function applyAttributes(item, node) { function applyAttributes(item, node, isRoot) {
var styles = { var styles = {
node: DomElement.getStyles(node) || {}, node: DomElement.getStyles(node) || {},
parent: DomElement.getStyles(node.parentNode) || {} parent: !isRoot && DomElement.getStyles(node.parentNode) || {}
}; };
Base.each(attributes, function(apply, name) { Base.each(attributes, function(apply, name) {
var value = getAttribute(node, name, styles); var value = getAttribute(node, name, styles);
@ -11580,38 +11673,55 @@ new function() {
return match && definitions[match[1]]; return match && definitions[match[1]];
} }
function importSVG(node, options, clearDefs) { function importSVG(node, isRoot, options) {
if (!options) if (!options)
options = {}; options = {};
if (typeof node === 'string') if (typeof node === 'string') {
if (isRoot && !/^.*</.test(node)) {
if (typeof options === 'function')
options = { onLoad: options };
var scope = paper;
return Http.request('get', node, function(svg) {
paper = scope;
var item = importSVG(svg, isRoot, options),
onLoad = options.onLoad,
view = scope.project && scope.project.view;
if (onLoad)
onLoad.call(this, item);
view.draw(true);
});
}
node = new DOMParser().parseFromString(node, 'image/svg+xml'); node = new DOMParser().parseFromString(node, 'image/svg+xml');
}
var type = node.nodeName.toLowerCase(), var type = node.nodeName.toLowerCase(),
importer = importers[type], importer = importers[type],
item = importer && importer(node, type, options), item = importer && importer(node, type, isRoot, options),
data = type !== '#document' && node.getAttribute('data-paper-data'); data = type !== '#document' && node.getAttribute('data-paper-data');
if (options.expandShapes && item instanceof Shape) { if (item) {
item.remove(); if (!(item instanceof Group))
item = item.toPath(); item = applyAttributes(item, node, isRoot);
if (options.expandShapes && item instanceof Shape) {
item.remove();
item = item.toPath();
}
if (data)
item._data = JSON.parse(data);
} }
if (item && !(item instanceof Group)) if (isRoot)
item = applyAttributes(item, node);
if (item && data)
item._data = JSON.parse(data);
if (clearDefs)
definitions = {}; definitions = {};
return item; return item;
} }
Item.inject({ Item.inject({
importSVG: function(node, options) { importSVG: function(node, options) {
return this.addChild(importSVG(node, options, true)); return this.addChild(importSVG(node, true, options));
} }
}); });
Project.inject({ Project.inject({
importSVG: function(node, options) { importSVG: function(node, options) {
this.activate(); this.activate();
return importSVG(node, options, true); return importSVG(node, true, options);
} }
}); });
}; };
@ -11814,20 +11924,6 @@ paper.PaperScope.prototype.PaperScript = (function(root) {
return res; return res;
} }
function request(url, scope) {
var xhr = new (window.ActiveXObject || XMLHttpRequest)(
'Microsoft.XMLHTTP');
xhr.open('GET', url, true);
if (xhr.overrideMimeType)
xhr.overrideMimeType('text/plain');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
return evaluate(xhr.responseText, scope);
}
};
return xhr.send(null);
}
function load() { function load() {
var scripts = document.getElementsByTagName('script'); var scripts = document.getElementsByTagName('script');
for (var i = 0, l = scripts.length; i < l; i++) { for (var i = 0, l = scripts.length; i < l; i++) {
@ -11836,9 +11932,12 @@ paper.PaperScope.prototype.PaperScript = (function(root) {
&& !script.getAttribute('data-paper-ignore')) { && !script.getAttribute('data-paper-ignore')) {
var canvas = PaperScope.getAttribute(script, 'canvas'), var canvas = PaperScope.getAttribute(script, 'canvas'),
scope = PaperScope.get(canvas) scope = PaperScope.get(canvas)
|| new PaperScope(script).setup(canvas); || new PaperScope(script).setup(canvas),
if (script.src) { src = script.src;
request(script.src, scope); if (src) {
Http.request('get', src, function(code) {
evaluate(code, scope);
});
} else { } else {
evaluate(script.innerHTML, scope); evaluate(script.innerHTML, scope);
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "paper", "name": "paper",
"version": "0.9.10", "version": "0.9.11",
"description": "The Swiss Army Knife of Vector Graphics Scripting", "description": "The Swiss Army Knife of Vector Graphics Scripting",
"homepage": "http://paperjs.org", "homepage": "http://paperjs.org",
"repository": "git://github.com/paperjs/paper.js", "repository": "git://github.com/paperjs/paper.js",