Bump version to v0.9.12

This commit is contained in:
Jürg Lehni 2013-11-14 14:46:54 +01:00
parent 8f4b70a7d3
commit 3da3161a33
8 changed files with 570 additions and 322 deletions

View file

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

212
dist/paper-core.js vendored
View file

@ -1,5 +1,5 @@
/*! /*!
* Paper.js v0.9.11 - The Swiss Army Knife of Vector Graphics Scripting. * Paper.js v0.9.12 - 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: Sat Nov 2 21:26:32 2013 +0100 * Date: Thu Nov 14 14:42:28 2013 +0100
* *
*** ***
* *
@ -684,7 +684,7 @@ var PaperScope = Base.extend({
} }
}, },
version: '0.9.11', version: '0.9.12',
getView: function() { getView: function() {
return this.project && this.project.view; return this.project && this.project.view;
@ -2420,12 +2420,13 @@ var Project = PaperScopeItem.extend({
return Base.importJSON(json); return Base.importJSON(json);
}, },
draw: function(ctx, matrix) { draw: function(ctx, matrix, ratio) {
this._drawCount++; this._drawCount++;
ctx.save(); ctx.save();
matrix.applyToContext(ctx); matrix.applyToContext(ctx);
var param = Base.merge({ var param = Base.merge({
offset: new Point(0, 0), offset: new Point(0, 0),
ratio: ratio,
transforms: [matrix], transforms: [matrix],
trackTransforms: true trackTransforms: true
}); });
@ -2861,6 +2862,8 @@ var Item = Base.extend(Callback, {
setMatrix: function(matrix) { setMatrix: function(matrix) {
this._matrix.initialize(matrix); this._matrix.initialize(matrix);
if (this._transformContent)
this.applyMatrix(true);
this._changed(5); this._changed(5);
}, },
@ -3649,7 +3652,7 @@ var Item = Base.extend(Callback, {
itemOffset = param.offset = bounds.getTopLeft().floor(); itemOffset = param.offset = bounds.getTopLeft().floor();
mainCtx = ctx; mainCtx = ctx;
ctx = CanvasProvider.getContext( ctx = CanvasProvider.getContext(
bounds.getSize().ceil().add(new Size(1, 1))); bounds.getSize().ceil().add(new Size(1, 1)), param.ratio);
} }
ctx.save(); ctx.save();
if (direct) { if (direct) {
@ -3670,7 +3673,7 @@ var Item = Base.extend(Callback, {
ctx.clip(); ctx.clip();
if (!direct) { if (!direct) {
BlendMode.process(blendMode, ctx, mainCtx, opacity, BlendMode.process(blendMode, ctx, mainCtx, opacity,
itemOffset.subtract(prevOffset)); itemOffset.subtract(prevOffset).multiply(param.ratio));
CanvasProvider.release(ctx); CanvasProvider.release(ctx);
param.offset = prevOffset; param.offset = prevOffset;
} }
@ -5942,19 +5945,19 @@ var PathItem = Item.extend({
control, control,
current = new Point(); current = new Point();
function getCoord(index, coord, update) { function getCoord(index, coord, isCurrent) {
var val = parseFloat(coords[index]); var val = parseFloat(coords[index]);
if (relative) if (relative)
val += current[coord]; val += current[coord];
if (update) if (isCurrent)
current[coord] = val; current[coord] = val;
return val; return val;
} }
function getPoint(index, update) { function getPoint(index, isCurrent) {
return new Point( return new Point(
getCoord(index, 'x', update), getCoord(index, 'x', isCurrent),
getCoord(index + 1, 'y', update) getCoord(index + 1, 'y', isCurrent)
); );
} }
@ -5973,6 +5976,7 @@ var PathItem = Item.extend({
for (var j = 0; j < length; j += 2) for (var j = 0; j < length; j += 2)
this[j === 0 && lower === 'm' ? 'moveTo' : 'lineTo']( this[j === 0 && lower === 'm' ? 'moveTo' : 'lineTo'](
getPoint(j, true)); getPoint(j, true));
control = current;
break; break;
case 'h': case 'h':
case 'v': case 'v':
@ -5981,6 +5985,7 @@ var PathItem = Item.extend({
getCoord(j, coord, true); getCoord(j, coord, true);
this.lineTo(current); this.lineTo(current);
} }
control = current;
break; break;
case 'c': case 'c':
for (var j = 0; j < length; j += 6) { for (var j = 0; j < length; j += 6) {
@ -6075,9 +6080,8 @@ var Path = PathItem.extend({
delete this._length; delete this._length;
delete this._clockwise; delete this._clockwise;
if (this._curves) { if (this._curves) {
for (var i = 0, l = this._curves.length; i < l; i++) { for (var i = 0, l = this._curves.length; i < l; i++)
this._curves[i]._changed(5); this._curves[i]._changed(5);
}
} }
} else if (flags & 8) { } else if (flags & 8) {
delete this._bounds; delete this._bounds;
@ -6916,7 +6920,6 @@ var Path = PathItem.extend({
if (hasFill || hasStroke && !dashLength || compound || clip) if (hasFill || hasStroke && !dashLength || compound || clip)
drawSegments(ctx, this); drawSegments(ctx, this);
if (this._closed) if (this._closed)
ctx.closePath(); ctx.closePath();
@ -7678,10 +7681,12 @@ var CompoundPath = PathItem.extend({
var children = this._children; var children = this._children;
if (children.length === 0) if (children.length === 0)
return; return;
ctx.beginPath(); ctx.beginPath();
param = param.extend({ compound: true }); param = param.extend({ compound: true });
for (var i = 0, l = children.length; i < l; i++) for (var i = 0, l = children.length; i < l; i++)
children[i].draw(ctx, param); children[i].draw(ctx, param);
if (!param.clip) { if (!param.clip) {
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style; var style = this._style;
@ -9513,10 +9518,9 @@ var View = Base.extend(Callback, {
if (size.isNaN()) if (size.isNaN())
size = DomElement.getSize(element); size = DomElement.getSize(element);
} }
element.width = size.width; this._setViewSize(size);
element.height = size.height;
if (PaperScope.hasAttribute(element, 'stats') if (PaperScope.hasAttribute(element, 'stats')
&& typeof Stats === 'object') { && typeof Stats !== 'undefined') {
this._stats = new Stats(); this._stats = new Stats();
var stats = this._stats.domElement, var stats = this._stats.domElement,
style = stats.style, style = stats.style,
@ -9528,8 +9532,7 @@ var View = Base.extend(Callback, {
} }
View._views.push(this); View._views.push(this);
View._viewsById[this._id] = this; View._viewsById[this._id] = this;
this._viewSize = new LinkedSize(size.width, size.height, this._viewSize = size;
this, 'setViewSize');
this._matrix = new Matrix(); this._matrix = new Matrix();
this._zoom = 1; this._zoom = 1;
if (!View._focused) if (!View._focused)
@ -9655,7 +9658,8 @@ var View = Base.extend(Callback, {
}, },
getViewSize: function() { getViewSize: function() {
return this._viewSize; var size = this._viewSize;
return new LinkedSize(size.width, size.height, this, 'setViewSize');
}, },
setViewSize: function(size) { setViewSize: function(size) {
@ -9663,9 +9667,8 @@ var View = Base.extend(Callback, {
var delta = size.subtract(this._viewSize); var delta = size.subtract(this._viewSize);
if (delta.isZero()) if (delta.isZero())
return; return;
this._element.width = size.width; this._viewSize.set(size.width, size.height);
this._element.height = size.height; this._setViewSize(size);
this._viewSize.set(size.width, size.height, true);
this._bounds = null; this._bounds = null;
this.fire('resize', { this.fire('resize', {
size: size, size: size,
@ -9674,6 +9677,12 @@ var View = Base.extend(Callback, {
this._redraw(); this._redraw();
}, },
_setViewSize: function(size) {
var element = this._element;
element.width = size.width;
element.height = size.height;
},
getBounds: function() { getBounds: function() {
if (!this._bounds) if (!this._bounds)
this._bounds = this._matrix.inverted()._transformBounds( this._bounds = this._matrix.inverted()._transformBounds(
@ -9848,34 +9857,44 @@ var CanvasView = View.extend({
var size = Size.read(arguments); var size = Size.read(arguments);
if (size.isZero()) if (size.isZero())
throw new Error( throw new Error(
'Cannot create CanvasView with the provided arguments: ' 'Cannot create CanvasView with the provided argument: '
+ arguments); + canvas);
canvas = CanvasProvider.getCanvas(size); canvas = CanvasProvider.getCanvas(size);
} }
var ctx = this._context = canvas.getContext('2d'); this._context = canvas.getContext('2d');
this._eventCounters = {}; this._eventCounters = {};
var ratio = (window.devicePixelRatio || 1) / (DomElement.getPrefixValue( this._ratio = 1;
ctx, 'backingStorePixelRatio') || 1); if (PaperScope.getAttribute(canvas, 'hidpi') !== 'off') {
if (ratio > 1) { var deviceRatio = window.devicePixelRatio || 1,
var width = canvas.clientWidth, backingStoreRatio = DomElement.getPrefixValue(this._context,
height = canvas.clientHeight, 'backingStorePixelRatio') || 1;
style = canvas.style; this._ratio = deviceRatio / backingStoreRatio;
canvas.width = width * ratio;
canvas.height = height * ratio;
style.width = width + 'px';
style.height = height + 'px';
ctx.scale(ratio, ratio);
} }
View.call(this, canvas); View.call(this, canvas);
}, },
_setViewSize: function(size) {
var width = size.width,
height = size.height,
ratio = this._ratio,
element = this._element,
style = element.style;
element.width = width * ratio;
element.height = height * ratio;
if (ratio !== 1) {
style.width = width + 'px';
style.height = height + 'px';
this._context.scale(ratio, ratio);
}
},
draw: function(checkRedraw) { draw: function(checkRedraw) {
if (checkRedraw && !this._project._needsRedraw) if (checkRedraw && !this._project._needsRedraw)
return false; return false;
var ctx = this._context, var ctx = this._context,
size = this._viewSize; size = this._viewSize;
ctx.clearRect(0, 0, size._width + 1, size._height + 1); ctx.clearRect(0, 0, size.width + 1, size.height + 1);
this._project.draw(ctx, this._matrix); this._project.draw(ctx, this._matrix, this._ratio);
this._project._needsRedraw = false; this._project._needsRedraw = false;
return true; return true;
} }
@ -10412,25 +10431,36 @@ var Http = {
var CanvasProvider = { var CanvasProvider = {
canvases: [], canvases: [],
getCanvas: function(width, height) { getCanvas: function(width, height, ratio) {
var size = height === undefined ? width : new Size(width, height), var canvas,
canvas,
init = true; init = true;
if (typeof width === 'object') {
ratio = height;
height = width.height;
width = width.width;
}
if (!ratio) {
ratio = 1;
} else if (ratio !== 1) {
width *= ratio;
height *= ratio;
}
if (this.canvases.length) { if (this.canvases.length) {
canvas = this.canvases.pop(); canvas = this.canvases.pop();
} else { } else {
canvas = document.createElement('canvas'); canvas = document.createElement('canvas');
} }
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
ctx.save(); if (canvas.width === width && canvas.height === height) {
if (canvas.width === size.width && canvas.height === size.height) {
if (init) if (init)
ctx.clearRect(0, 0, size.width + 1, size.height + 1); ctx.clearRect(0, 0, width + 1, height + 1);
} else { } else {
canvas.width = size.width; canvas.width = width;
canvas.height = size.height; canvas.height = height;
} }
ctx.save();
if (ratio !== 1)
ctx.scale(ratio, ratio);
return canvas; return canvas;
}, },
@ -11152,12 +11182,12 @@ new function() {
function importGroup(node, type, isRoot, options) { function importGroup(node, type, isRoot, options) {
var nodes = node.childNodes, var nodes = node.childNodes,
clip = type === 'clippath', isClip = type === 'clippath',
item = new Group(), item = new Group(),
project = item._project, project = item._project,
currentStyle = project._currentStyle, currentStyle = project._currentStyle,
children = []; children = [];
if (!clip) { if (!isClip) {
item._transformContent = false; item._transformContent = false;
item = applyAttributes(item, node, isRoot); item = applyAttributes(item, node, isRoot);
project._currentStyle = item._style.clone(); project._currentStyle = item._style.clone();
@ -11171,10 +11201,10 @@ new function() {
children.push(child); children.push(child);
} }
item.addChildren(children); item.addChildren(children);
if (clip) if (isClip)
item = applyAttributes(item.reduce(), node, isRoot); item = applyAttributes(item.reduce(), node, isRoot);
project._currentStyle = currentStyle; project._currentStyle = currentStyle;
if (clip || type === 'defs') { if (isClip || type === 'defs') {
item.remove(); item.remove();
item = null; item = null;
} }
@ -11226,10 +11256,23 @@ new function() {
} }
var importers = { var importers = {
'#document': function(node, type, isRoot, options) { '#document': function (node, type, isRoot, options) {
return importSVG(node.childNodes[0], isRoot, options); var nodes = node.childNodes;
for (var i = 0, l = nodes.length; i < l; i++) {
var child = nodes[i];
if (child.nodeType === 1) {
var next = child.nextSibling;
document.body.appendChild(child);
var item = importSVG(child, isRoot, options);
if (next) {
node.insertBefore(child, next);
} else {
node.appendChild(child);
}
return item;
}
}
}, },
g: importGroup, g: importGroup,
svg: importGroup, svg: importGroup,
clippath: importGroup, clippath: importGroup,
@ -11455,30 +11498,48 @@ new function() {
return match && definitions[match[1]]; return match && definitions[match[1]];
} }
function importSVG(node, isRoot, options) { function importSVG(source, isRoot, options) {
if (!options) if (!source)
return null;
if (!options) {
options = {}; options = {};
if (typeof node === 'string') { } else if (typeof options === 'function') {
if (isRoot && !/^.*</.test(node)) { options = { onLoad: options };
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');
} }
var node = source,
scope = paper;
function onLoadCallback(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);
}
if (isRoot) {
if (typeof source === 'string' && !/^.*</.test(source)) {
return Http.request('get', source, onLoadCallback);
} else if (typeof File !== 'undefined' && source instanceof File) {
var reader = new FileReader();
reader.onload = function() {
onLoadCallback(reader.result);
};
return reader.readAsText(source);
}
}
if (typeof source === 'string')
node = new DOMParser().parseFromString(source, 'image/svg+xml');
if (!node.nodeName)
throw new Error('Unsupported SVG source: ' + source);
var type = node.nodeName.toLowerCase(), var type = node.nodeName.toLowerCase(),
importer = importers[type], importer = importers[type],
item = importer && importer(node, type, isRoot, options), item = importer && importer(node, type, isRoot, options) || null,
data = type !== '#document' && node.getAttribute('data-paper-data'); data = node.getAttribute && node.getAttribute('data-paper-data');
if (item) { if (item) {
if (!(item instanceof Group)) if (!(item instanceof Group))
item = applyAttributes(item, node, isRoot); item = applyAttributes(item, node, isRoot);
@ -11514,6 +11575,7 @@ paper = new (PaperScope.inject(Base.merge(Base.exports, {
Numerical: Numerical, Numerical: Numerical,
DomElement: DomElement, DomElement: DomElement,
DomEvent: DomEvent, DomEvent: DomEvent,
Http: Http,
Key: Key Key: Key
})))(); })))();

File diff suppressed because one or more lines are too long

216
dist/paper-full.js vendored
View file

@ -1,5 +1,5 @@
/*! /*!
* Paper.js v0.9.11 - The Swiss Army Knife of Vector Graphics Scripting. * Paper.js v0.9.12 - 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: Sat Nov 2 21:26:32 2013 +0100 * Date: Thu Nov 14 14:42:28 2013 +0100
* *
*** ***
* *
@ -684,7 +684,7 @@ var PaperScope = Base.extend({
} }
}, },
version: '0.9.11', version: '0.9.12',
getView: function() { getView: function() {
return this.project && this.project.view; return this.project && this.project.view;
@ -2420,12 +2420,13 @@ var Project = PaperScopeItem.extend({
return Base.importJSON(json); return Base.importJSON(json);
}, },
draw: function(ctx, matrix) { draw: function(ctx, matrix, ratio) {
this._drawCount++; this._drawCount++;
ctx.save(); ctx.save();
matrix.applyToContext(ctx); matrix.applyToContext(ctx);
var param = Base.merge({ var param = Base.merge({
offset: new Point(0, 0), offset: new Point(0, 0),
ratio: ratio,
transforms: [matrix], transforms: [matrix],
trackTransforms: true trackTransforms: true
}); });
@ -2861,6 +2862,8 @@ var Item = Base.extend(Callback, {
setMatrix: function(matrix) { setMatrix: function(matrix) {
this._matrix.initialize(matrix); this._matrix.initialize(matrix);
if (this._transformContent)
this.applyMatrix(true);
this._changed(5); this._changed(5);
}, },
@ -3649,7 +3652,7 @@ var Item = Base.extend(Callback, {
itemOffset = param.offset = bounds.getTopLeft().floor(); itemOffset = param.offset = bounds.getTopLeft().floor();
mainCtx = ctx; mainCtx = ctx;
ctx = CanvasProvider.getContext( ctx = CanvasProvider.getContext(
bounds.getSize().ceil().add(new Size(1, 1))); bounds.getSize().ceil().add(new Size(1, 1)), param.ratio);
} }
ctx.save(); ctx.save();
if (direct) { if (direct) {
@ -3670,7 +3673,7 @@ var Item = Base.extend(Callback, {
ctx.clip(); ctx.clip();
if (!direct) { if (!direct) {
BlendMode.process(blendMode, ctx, mainCtx, opacity, BlendMode.process(blendMode, ctx, mainCtx, opacity,
itemOffset.subtract(prevOffset)); itemOffset.subtract(prevOffset).multiply(param.ratio));
CanvasProvider.release(ctx); CanvasProvider.release(ctx);
param.offset = prevOffset; param.offset = prevOffset;
} }
@ -5942,19 +5945,19 @@ var PathItem = Item.extend({
control, control,
current = new Point(); current = new Point();
function getCoord(index, coord, update) { function getCoord(index, coord, isCurrent) {
var val = parseFloat(coords[index]); var val = parseFloat(coords[index]);
if (relative) if (relative)
val += current[coord]; val += current[coord];
if (update) if (isCurrent)
current[coord] = val; current[coord] = val;
return val; return val;
} }
function getPoint(index, update) { function getPoint(index, isCurrent) {
return new Point( return new Point(
getCoord(index, 'x', update), getCoord(index, 'x', isCurrent),
getCoord(index + 1, 'y', update) getCoord(index + 1, 'y', isCurrent)
); );
} }
@ -5973,6 +5976,7 @@ var PathItem = Item.extend({
for (var j = 0; j < length; j += 2) for (var j = 0; j < length; j += 2)
this[j === 0 && lower === 'm' ? 'moveTo' : 'lineTo']( this[j === 0 && lower === 'm' ? 'moveTo' : 'lineTo'](
getPoint(j, true)); getPoint(j, true));
control = current;
break; break;
case 'h': case 'h':
case 'v': case 'v':
@ -5981,6 +5985,7 @@ var PathItem = Item.extend({
getCoord(j, coord, true); getCoord(j, coord, true);
this.lineTo(current); this.lineTo(current);
} }
control = current;
break; break;
case 'c': case 'c':
for (var j = 0; j < length; j += 6) { for (var j = 0; j < length; j += 6) {
@ -6075,9 +6080,8 @@ var Path = PathItem.extend({
delete this._length; delete this._length;
delete this._clockwise; delete this._clockwise;
if (this._curves) { if (this._curves) {
for (var i = 0, l = this._curves.length; i < l; i++) { for (var i = 0, l = this._curves.length; i < l; i++)
this._curves[i]._changed(5); this._curves[i]._changed(5);
}
} }
} else if (flags & 8) { } else if (flags & 8) {
delete this._bounds; delete this._bounds;
@ -6916,7 +6920,6 @@ var Path = PathItem.extend({
if (hasFill || hasStroke && !dashLength || compound || clip) if (hasFill || hasStroke && !dashLength || compound || clip)
drawSegments(ctx, this); drawSegments(ctx, this);
if (this._closed) if (this._closed)
ctx.closePath(); ctx.closePath();
@ -7678,10 +7681,12 @@ var CompoundPath = PathItem.extend({
var children = this._children; var children = this._children;
if (children.length === 0) if (children.length === 0)
return; return;
ctx.beginPath(); ctx.beginPath();
param = param.extend({ compound: true }); param = param.extend({ compound: true });
for (var i = 0, l = children.length; i < l; i++) for (var i = 0, l = children.length; i < l; i++)
children[i].draw(ctx, param); children[i].draw(ctx, param);
if (!param.clip) { if (!param.clip) {
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style; var style = this._style;
@ -9513,10 +9518,9 @@ var View = Base.extend(Callback, {
if (size.isNaN()) if (size.isNaN())
size = DomElement.getSize(element); size = DomElement.getSize(element);
} }
element.width = size.width; this._setViewSize(size);
element.height = size.height;
if (PaperScope.hasAttribute(element, 'stats') if (PaperScope.hasAttribute(element, 'stats')
&& typeof Stats === 'object') { && typeof Stats !== 'undefined') {
this._stats = new Stats(); this._stats = new Stats();
var stats = this._stats.domElement, var stats = this._stats.domElement,
style = stats.style, style = stats.style,
@ -9528,8 +9532,7 @@ var View = Base.extend(Callback, {
} }
View._views.push(this); View._views.push(this);
View._viewsById[this._id] = this; View._viewsById[this._id] = this;
this._viewSize = new LinkedSize(size.width, size.height, this._viewSize = size;
this, 'setViewSize');
this._matrix = new Matrix(); this._matrix = new Matrix();
this._zoom = 1; this._zoom = 1;
if (!View._focused) if (!View._focused)
@ -9655,7 +9658,8 @@ var View = Base.extend(Callback, {
}, },
getViewSize: function() { getViewSize: function() {
return this._viewSize; var size = this._viewSize;
return new LinkedSize(size.width, size.height, this, 'setViewSize');
}, },
setViewSize: function(size) { setViewSize: function(size) {
@ -9663,9 +9667,8 @@ var View = Base.extend(Callback, {
var delta = size.subtract(this._viewSize); var delta = size.subtract(this._viewSize);
if (delta.isZero()) if (delta.isZero())
return; return;
this._element.width = size.width; this._viewSize.set(size.width, size.height);
this._element.height = size.height; this._setViewSize(size);
this._viewSize.set(size.width, size.height, true);
this._bounds = null; this._bounds = null;
this.fire('resize', { this.fire('resize', {
size: size, size: size,
@ -9674,6 +9677,12 @@ var View = Base.extend(Callback, {
this._redraw(); this._redraw();
}, },
_setViewSize: function(size) {
var element = this._element;
element.width = size.width;
element.height = size.height;
},
getBounds: function() { getBounds: function() {
if (!this._bounds) if (!this._bounds)
this._bounds = this._matrix.inverted()._transformBounds( this._bounds = this._matrix.inverted()._transformBounds(
@ -9848,34 +9857,44 @@ var CanvasView = View.extend({
var size = Size.read(arguments); var size = Size.read(arguments);
if (size.isZero()) if (size.isZero())
throw new Error( throw new Error(
'Cannot create CanvasView with the provided arguments: ' 'Cannot create CanvasView with the provided argument: '
+ arguments); + canvas);
canvas = CanvasProvider.getCanvas(size); canvas = CanvasProvider.getCanvas(size);
} }
var ctx = this._context = canvas.getContext('2d'); this._context = canvas.getContext('2d');
this._eventCounters = {}; this._eventCounters = {};
var ratio = (window.devicePixelRatio || 1) / (DomElement.getPrefixValue( this._ratio = 1;
ctx, 'backingStorePixelRatio') || 1); if (PaperScope.getAttribute(canvas, 'hidpi') !== 'off') {
if (ratio > 1) { var deviceRatio = window.devicePixelRatio || 1,
var width = canvas.clientWidth, backingStoreRatio = DomElement.getPrefixValue(this._context,
height = canvas.clientHeight, 'backingStorePixelRatio') || 1;
style = canvas.style; this._ratio = deviceRatio / backingStoreRatio;
canvas.width = width * ratio;
canvas.height = height * ratio;
style.width = width + 'px';
style.height = height + 'px';
ctx.scale(ratio, ratio);
} }
View.call(this, canvas); View.call(this, canvas);
}, },
_setViewSize: function(size) {
var width = size.width,
height = size.height,
ratio = this._ratio,
element = this._element,
style = element.style;
element.width = width * ratio;
element.height = height * ratio;
if (ratio !== 1) {
style.width = width + 'px';
style.height = height + 'px';
this._context.scale(ratio, ratio);
}
},
draw: function(checkRedraw) { draw: function(checkRedraw) {
if (checkRedraw && !this._project._needsRedraw) if (checkRedraw && !this._project._needsRedraw)
return false; return false;
var ctx = this._context, var ctx = this._context,
size = this._viewSize; size = this._viewSize;
ctx.clearRect(0, 0, size._width + 1, size._height + 1); ctx.clearRect(0, 0, size.width + 1, size.height + 1);
this._project.draw(ctx, this._matrix); this._project.draw(ctx, this._matrix, this._ratio);
this._project._needsRedraw = false; this._project._needsRedraw = false;
return true; return true;
} }
@ -10630,25 +10649,36 @@ var Http = {
var CanvasProvider = { var CanvasProvider = {
canvases: [], canvases: [],
getCanvas: function(width, height) { getCanvas: function(width, height, ratio) {
var size = height === undefined ? width : new Size(width, height), var canvas,
canvas,
init = true; init = true;
if (typeof width === 'object') {
ratio = height;
height = width.height;
width = width.width;
}
if (!ratio) {
ratio = 1;
} else if (ratio !== 1) {
width *= ratio;
height *= ratio;
}
if (this.canvases.length) { if (this.canvases.length) {
canvas = this.canvases.pop(); canvas = this.canvases.pop();
} else { } else {
canvas = document.createElement('canvas'); canvas = document.createElement('canvas');
} }
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
ctx.save(); if (canvas.width === width && canvas.height === height) {
if (canvas.width === size.width && canvas.height === size.height) {
if (init) if (init)
ctx.clearRect(0, 0, size.width + 1, size.height + 1); ctx.clearRect(0, 0, width + 1, height + 1);
} else { } else {
canvas.width = size.width; canvas.width = width;
canvas.height = size.height; canvas.height = height;
} }
ctx.save();
if (ratio !== 1)
ctx.scale(ratio, ratio);
return canvas; return canvas;
}, },
@ -11370,12 +11400,12 @@ new function() {
function importGroup(node, type, isRoot, options) { function importGroup(node, type, isRoot, options) {
var nodes = node.childNodes, var nodes = node.childNodes,
clip = type === 'clippath', isClip = type === 'clippath',
item = new Group(), item = new Group(),
project = item._project, project = item._project,
currentStyle = project._currentStyle, currentStyle = project._currentStyle,
children = []; children = [];
if (!clip) { if (!isClip) {
item._transformContent = false; item._transformContent = false;
item = applyAttributes(item, node, isRoot); item = applyAttributes(item, node, isRoot);
project._currentStyle = item._style.clone(); project._currentStyle = item._style.clone();
@ -11389,10 +11419,10 @@ new function() {
children.push(child); children.push(child);
} }
item.addChildren(children); item.addChildren(children);
if (clip) if (isClip)
item = applyAttributes(item.reduce(), node, isRoot); item = applyAttributes(item.reduce(), node, isRoot);
project._currentStyle = currentStyle; project._currentStyle = currentStyle;
if (clip || type === 'defs') { if (isClip || type === 'defs') {
item.remove(); item.remove();
item = null; item = null;
} }
@ -11444,10 +11474,23 @@ new function() {
} }
var importers = { var importers = {
'#document': function(node, type, isRoot, options) { '#document': function (node, type, isRoot, options) {
return importSVG(node.childNodes[0], isRoot, options); var nodes = node.childNodes;
for (var i = 0, l = nodes.length; i < l; i++) {
var child = nodes[i];
if (child.nodeType === 1) {
var next = child.nextSibling;
document.body.appendChild(child);
var item = importSVG(child, isRoot, options);
if (next) {
node.insertBefore(child, next);
} else {
node.appendChild(child);
}
return item;
}
}
}, },
g: importGroup, g: importGroup,
svg: importGroup, svg: importGroup,
clippath: importGroup, clippath: importGroup,
@ -11673,30 +11716,48 @@ new function() {
return match && definitions[match[1]]; return match && definitions[match[1]];
} }
function importSVG(node, isRoot, options) { function importSVG(source, isRoot, options) {
if (!options) if (!source)
return null;
if (!options) {
options = {}; options = {};
if (typeof node === 'string') { } else if (typeof options === 'function') {
if (isRoot && !/^.*</.test(node)) { options = { onLoad: options };
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');
} }
var node = source,
scope = paper;
function onLoadCallback(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);
}
if (isRoot) {
if (typeof source === 'string' && !/^.*</.test(source)) {
return Http.request('get', source, onLoadCallback);
} else if (typeof File !== 'undefined' && source instanceof File) {
var reader = new FileReader();
reader.onload = function() {
onLoadCallback(reader.result);
};
return reader.readAsText(source);
}
}
if (typeof source === 'string')
node = new DOMParser().parseFromString(source, 'image/svg+xml');
if (!node.nodeName)
throw new Error('Unsupported SVG source: ' + source);
var type = node.nodeName.toLowerCase(), var type = node.nodeName.toLowerCase(),
importer = importers[type], importer = importers[type],
item = importer && importer(node, type, isRoot, options), item = importer && importer(node, type, isRoot, options) || null,
data = type !== '#document' && node.getAttribute('data-paper-data'); data = node.getAttribute && node.getAttribute('data-paper-data');
if (item) { if (item) {
if (!(item instanceof Group)) if (!(item instanceof Group))
item = applyAttributes(item, node, isRoot); item = applyAttributes(item, node, isRoot);
@ -11732,6 +11793,7 @@ paper = new (PaperScope.inject(Base.merge(Base.exports, {
Numerical: Numerical, Numerical: Numerical,
DomElement: DomElement, DomElement: DomElement,
DomEvent: DomEvent, DomEvent: DomEvent,
Http: Http,
Key: Key Key: Key
})))(); })))();
@ -11764,7 +11826,7 @@ paper.PaperScope.prototype.PaperScript = (function(root) {
}; };
var fields = Base.each( var fields = Base.each(
'add,subtract,multiply,divide,modulo,negate'.split(','), ['add', 'subtract', 'multiply', 'divide', 'modulo', 'negate'],
function(name) { function(name) {
this['_' + name] = '#' + name; this['_' + name] = '#' + name;
}, },
@ -11935,7 +11997,7 @@ paper.PaperScope.prototype.PaperScript = (function(root) {
|| new PaperScope(script).setup(canvas), || new PaperScope(script).setup(canvas),
src = script.src; src = script.src;
if (src) { if (src) {
Http.request('get', src, function(code) { paper.Http.request('get', src, function(code) {
evaluate(code, scope); evaluate(code, scope);
}); });
} else { } else {

File diff suppressed because one or more lines are too long

210
dist/paper-node.js vendored
View file

@ -1,5 +1,5 @@
/*! /*!
* Paper.js v0.9.11 - The Swiss Army Knife of Vector Graphics Scripting. * Paper.js v0.9.12 - 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: Sat Nov 2 21:26:32 2013 +0100 * Date: Thu Nov 14 14:42:28 2013 +0100
* *
*** ***
* *
@ -684,7 +684,7 @@ var PaperScope = Base.extend({
} }
}, },
version: '0.9.11', version: '0.9.12',
getView: function() { getView: function() {
return this.project && this.project.view; return this.project && this.project.view;
@ -2420,12 +2420,13 @@ var Project = PaperScopeItem.extend({
return Base.importJSON(json); return Base.importJSON(json);
}, },
draw: function(ctx, matrix) { draw: function(ctx, matrix, ratio) {
this._drawCount++; this._drawCount++;
ctx.save(); ctx.save();
matrix.applyToContext(ctx); matrix.applyToContext(ctx);
var param = Base.merge({ var param = Base.merge({
offset: new Point(0, 0), offset: new Point(0, 0),
ratio: ratio,
transforms: [matrix], transforms: [matrix],
trackTransforms: true trackTransforms: true
}); });
@ -2861,6 +2862,8 @@ var Item = Base.extend(Callback, {
setMatrix: function(matrix) { setMatrix: function(matrix) {
this._matrix.initialize(matrix); this._matrix.initialize(matrix);
if (this._transformContent)
this.applyMatrix(true);
this._changed(5); this._changed(5);
}, },
@ -3649,7 +3652,7 @@ var Item = Base.extend(Callback, {
itemOffset = param.offset = bounds.getTopLeft().floor(); itemOffset = param.offset = bounds.getTopLeft().floor();
mainCtx = ctx; mainCtx = ctx;
ctx = CanvasProvider.getContext( ctx = CanvasProvider.getContext(
bounds.getSize().ceil().add(new Size(1, 1))); bounds.getSize().ceil().add(new Size(1, 1)), param.ratio);
} }
ctx.save(); ctx.save();
if (direct) { if (direct) {
@ -3670,7 +3673,7 @@ var Item = Base.extend(Callback, {
ctx.clip(); ctx.clip();
if (!direct) { if (!direct) {
BlendMode.process(blendMode, ctx, mainCtx, opacity, BlendMode.process(blendMode, ctx, mainCtx, opacity,
itemOffset.subtract(prevOffset)); itemOffset.subtract(prevOffset).multiply(param.ratio));
CanvasProvider.release(ctx); CanvasProvider.release(ctx);
param.offset = prevOffset; param.offset = prevOffset;
} }
@ -5923,19 +5926,19 @@ var PathItem = Item.extend({
control, control,
current = new Point(); current = new Point();
function getCoord(index, coord, update) { function getCoord(index, coord, isCurrent) {
var val = parseFloat(coords[index]); var val = parseFloat(coords[index]);
if (relative) if (relative)
val += current[coord]; val += current[coord];
if (update) if (isCurrent)
current[coord] = val; current[coord] = val;
return val; return val;
} }
function getPoint(index, update) { function getPoint(index, isCurrent) {
return new Point( return new Point(
getCoord(index, 'x', update), getCoord(index, 'x', isCurrent),
getCoord(index + 1, 'y', update) getCoord(index + 1, 'y', isCurrent)
); );
} }
@ -5954,6 +5957,7 @@ var PathItem = Item.extend({
for (var j = 0; j < length; j += 2) for (var j = 0; j < length; j += 2)
this[j === 0 && lower === 'm' ? 'moveTo' : 'lineTo']( this[j === 0 && lower === 'm' ? 'moveTo' : 'lineTo'](
getPoint(j, true)); getPoint(j, true));
control = current;
break; break;
case 'h': case 'h':
case 'v': case 'v':
@ -5962,6 +5966,7 @@ var PathItem = Item.extend({
getCoord(j, coord, true); getCoord(j, coord, true);
this.lineTo(current); this.lineTo(current);
} }
control = current;
break; break;
case 'c': case 'c':
for (var j = 0; j < length; j += 6) { for (var j = 0; j < length; j += 6) {
@ -6056,9 +6061,8 @@ var Path = PathItem.extend({
delete this._length; delete this._length;
delete this._clockwise; delete this._clockwise;
if (this._curves) { if (this._curves) {
for (var i = 0, l = this._curves.length; i < l; i++) { for (var i = 0, l = this._curves.length; i < l; i++)
this._curves[i]._changed(5); this._curves[i]._changed(5);
}
} }
} else if (flags & 8) { } else if (flags & 8) {
delete this._bounds; delete this._bounds;
@ -6897,7 +6901,6 @@ var Path = PathItem.extend({
if (hasFill || hasStroke && !dashLength || compound || clip) if (hasFill || hasStroke && !dashLength || compound || clip)
drawSegments(ctx, this); drawSegments(ctx, this);
if (this._closed) if (this._closed)
ctx.closePath(); ctx.closePath();
@ -7659,10 +7662,12 @@ var CompoundPath = PathItem.extend({
var children = this._children; var children = this._children;
if (children.length === 0) if (children.length === 0)
return; return;
ctx.beginPath(); ctx.beginPath();
param = param.extend({ compound: true }); param = param.extend({ compound: true });
for (var i = 0, l = children.length; i < l; i++) for (var i = 0, l = children.length; i < l; i++)
children[i].draw(ctx, param); children[i].draw(ctx, param);
if (!param.clip) { if (!param.clip) {
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style; var style = this._style;
@ -9392,8 +9397,7 @@ var View = Base.extend(Callback, {
size = new Size(element.width, element.height); size = new Size(element.width, element.height);
View._views.push(this); View._views.push(this);
View._viewsById[this._id] = this; View._viewsById[this._id] = this;
this._viewSize = new LinkedSize(size.width, size.height, this._viewSize = size;
this, 'setViewSize');
this._matrix = new Matrix(); this._matrix = new Matrix();
this._zoom = 1; this._zoom = 1;
if (!View._focused) if (!View._focused)
@ -9504,7 +9508,8 @@ var View = Base.extend(Callback, {
}, },
getViewSize: function() { getViewSize: function() {
return this._viewSize; var size = this._viewSize;
return new LinkedSize(size.width, size.height, this, 'setViewSize');
}, },
setViewSize: function(size) { setViewSize: function(size) {
@ -9512,9 +9517,8 @@ var View = Base.extend(Callback, {
var delta = size.subtract(this._viewSize); var delta = size.subtract(this._viewSize);
if (delta.isZero()) if (delta.isZero())
return; return;
this._element.width = size.width; this._viewSize.set(size.width, size.height);
this._element.height = size.height; this._setViewSize(size);
this._viewSize.set(size.width, size.height, true);
this._bounds = null; this._bounds = null;
this.fire('resize', { this.fire('resize', {
size: size, size: size,
@ -9523,6 +9527,12 @@ var View = Base.extend(Callback, {
this._redraw(); this._redraw();
}, },
_setViewSize: function(size) {
var element = this._element;
element.width = size.width;
element.height = size.height;
},
getBounds: function() { getBounds: function() {
if (!this._bounds) if (!this._bounds)
this._bounds = this._matrix.inverted()._transformBounds( this._bounds = this._matrix.inverted()._transformBounds(
@ -9590,34 +9600,44 @@ var CanvasView = View.extend({
var size = Size.read(arguments); var size = Size.read(arguments);
if (size.isZero()) if (size.isZero())
throw new Error( throw new Error(
'Cannot create CanvasView with the provided arguments: ' 'Cannot create CanvasView with the provided argument: '
+ arguments); + canvas);
canvas = CanvasProvider.getCanvas(size); canvas = CanvasProvider.getCanvas(size);
} }
var ctx = this._context = canvas.getContext('2d'); this._context = canvas.getContext('2d');
this._eventCounters = {}; this._eventCounters = {};
var ratio = (window.devicePixelRatio || 1) / (DomElement.getPrefixValue( this._ratio = 1;
ctx, 'backingStorePixelRatio') || 1); if (PaperScope.getAttribute(canvas, 'hidpi') !== 'off') {
if (ratio > 1) { var deviceRatio = window.devicePixelRatio || 1,
var width = canvas.clientWidth, backingStoreRatio = DomElement.getPrefixValue(this._context,
height = canvas.clientHeight, 'backingStorePixelRatio') || 1;
style = canvas.style; this._ratio = deviceRatio / backingStoreRatio;
canvas.width = width * ratio;
canvas.height = height * ratio;
style.width = width + 'px';
style.height = height + 'px';
ctx.scale(ratio, ratio);
} }
View.call(this, canvas); View.call(this, canvas);
}, },
_setViewSize: function(size) {
var width = size.width,
height = size.height,
ratio = this._ratio,
element = this._element,
style = element.style;
element.width = width * ratio;
element.height = height * ratio;
if (ratio !== 1) {
style.width = width + 'px';
style.height = height + 'px';
this._context.scale(ratio, ratio);
}
},
draw: function(checkRedraw) { draw: function(checkRedraw) {
if (checkRedraw && !this._project._needsRedraw) if (checkRedraw && !this._project._needsRedraw)
return false; return false;
var ctx = this._context, var ctx = this._context,
size = this._viewSize; size = this._viewSize;
ctx.clearRect(0, 0, size._width + 1, size._height + 1); ctx.clearRect(0, 0, size.width + 1, size.height + 1);
this._project.draw(ctx, this._matrix); this._project.draw(ctx, this._matrix, this._ratio);
this._project._needsRedraw = false; this._project._needsRedraw = false;
return true; return true;
} }
@ -9791,26 +9811,37 @@ CanvasView.inject(new function() {
var CanvasProvider = { var CanvasProvider = {
canvases: [], canvases: [],
getCanvas: function(width, height) { getCanvas: function(width, height, ratio) {
var size = height === undefined ? width : new Size(width, height), var canvas,
canvas,
init = true; init = true;
if (typeof width === 'object') {
ratio = height;
height = width.height;
width = width.width;
}
if (!ratio) {
ratio = 1;
} else if (ratio !== 1) {
width *= ratio;
height *= ratio;
}
if (this.canvases.length) { if (this.canvases.length) {
canvas = this.canvases.pop(); canvas = this.canvases.pop();
} else { } else {
canvas = new Canvas(size.width, size.height); canvas = new Canvas(width, height);
init = false; init = false;
} }
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
ctx.save(); if (canvas.width === width && canvas.height === height) {
if (canvas.width === size.width && canvas.height === size.height) {
if (init) if (init)
ctx.clearRect(0, 0, size.width + 1, size.height + 1); ctx.clearRect(0, 0, width + 1, height + 1);
} else { } else {
canvas.width = size.width; canvas.width = width;
canvas.height = size.height; canvas.height = height;
} }
ctx.save();
if (ratio !== 1)
ctx.scale(ratio, ratio);
return canvas; return canvas;
}, },
@ -10532,12 +10563,12 @@ new function() {
function importGroup(node, type, isRoot, options) { function importGroup(node, type, isRoot, options) {
var nodes = node.childNodes, var nodes = node.childNodes,
clip = type === 'clippath', isClip = type === 'clippath',
item = new Group(), item = new Group(),
project = item._project, project = item._project,
currentStyle = project._currentStyle, currentStyle = project._currentStyle,
children = []; children = [];
if (!clip) { if (!isClip) {
item._transformContent = false; item._transformContent = false;
item = applyAttributes(item, node, isRoot); item = applyAttributes(item, node, isRoot);
project._currentStyle = item._style.clone(); project._currentStyle = item._style.clone();
@ -10551,10 +10582,10 @@ new function() {
children.push(child); children.push(child);
} }
item.addChildren(children); item.addChildren(children);
if (clip) if (isClip)
item = applyAttributes(item.reduce(), node, isRoot); item = applyAttributes(item.reduce(), node, isRoot);
project._currentStyle = currentStyle; project._currentStyle = currentStyle;
if (clip || type === 'defs') { if (isClip || type === 'defs') {
item.remove(); item.remove();
item = null; item = null;
} }
@ -10606,10 +10637,23 @@ new function() {
} }
var importers = { var importers = {
'#document': function(node, type, isRoot, options) { '#document': function (node, type, isRoot, options) {
return importSVG(node.childNodes[0], isRoot, options); var nodes = node.childNodes;
for (var i = 0, l = nodes.length; i < l; i++) {
var child = nodes[i];
if (child.nodeType === 1) {
var next = child.nextSibling;
document.body.appendChild(child);
var item = importSVG(child, isRoot, options);
if (next) {
node.insertBefore(child, next);
} else {
node.appendChild(child);
}
return item;
}
}
}, },
g: importGroup, g: importGroup,
svg: importGroup, svg: importGroup,
clippath: importGroup, clippath: importGroup,
@ -10835,30 +10879,48 @@ new function() {
return match && definitions[match[1]]; return match && definitions[match[1]];
} }
function importSVG(node, isRoot, options) { function importSVG(source, isRoot, options) {
if (!options) if (!source)
return null;
if (!options) {
options = {}; options = {};
if (typeof node === 'string') { } else if (typeof options === 'function') {
if (isRoot && !/^.*</.test(node)) { options = { onLoad: options };
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');
} }
var node = source,
scope = paper;
function onLoadCallback(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);
}
if (isRoot) {
if (typeof source === 'string' && !/^.*</.test(source)) {
return Http.request('get', source, onLoadCallback);
} else if (typeof File !== 'undefined' && source instanceof File) {
var reader = new FileReader();
reader.onload = function() {
onLoadCallback(reader.result);
};
return reader.readAsText(source);
}
}
if (typeof source === 'string')
node = new DOMParser().parseFromString(source, 'image/svg+xml');
if (!node.nodeName)
throw new Error('Unsupported SVG source: ' + source);
var type = node.nodeName.toLowerCase(), var type = node.nodeName.toLowerCase(),
importer = importers[type], importer = importers[type],
item = importer && importer(node, type, isRoot, options), item = importer && importer(node, type, isRoot, options) || null,
data = type !== '#document' && node.getAttribute('data-paper-data'); data = node.getAttribute && node.getAttribute('data-paper-data');
if (item) { if (item) {
if (!(item instanceof Group)) if (!(item instanceof Group))
item = applyAttributes(item, node, isRoot); item = applyAttributes(item, node, isRoot);
@ -10926,7 +10988,7 @@ paper.PaperScope.prototype.PaperScript = (function(root) {
}; };
var fields = Base.each( var fields = Base.each(
'add,subtract,multiply,divide,modulo,negate'.split(','), ['add', 'subtract', 'multiply', 'divide', 'modulo', 'negate'],
function(name) { function(name) {
this['_' + name] = '#' + name; this['_' + name] = '#' + name;
}, },

216
dist/paper.js vendored
View file

@ -1,5 +1,5 @@
/*! /*!
* Paper.js v0.9.11 - The Swiss Army Knife of Vector Graphics Scripting. * Paper.js v0.9.12 - 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: Sat Nov 2 21:26:32 2013 +0100 * Date: Thu Nov 14 14:42:28 2013 +0100
* *
*** ***
* *
@ -684,7 +684,7 @@ var PaperScope = Base.extend({
} }
}, },
version: '0.9.11', version: '0.9.12',
getView: function() { getView: function() {
return this.project && this.project.view; return this.project && this.project.view;
@ -2420,12 +2420,13 @@ var Project = PaperScopeItem.extend({
return Base.importJSON(json); return Base.importJSON(json);
}, },
draw: function(ctx, matrix) { draw: function(ctx, matrix, ratio) {
this._drawCount++; this._drawCount++;
ctx.save(); ctx.save();
matrix.applyToContext(ctx); matrix.applyToContext(ctx);
var param = Base.merge({ var param = Base.merge({
offset: new Point(0, 0), offset: new Point(0, 0),
ratio: ratio,
transforms: [matrix], transforms: [matrix],
trackTransforms: true trackTransforms: true
}); });
@ -2861,6 +2862,8 @@ var Item = Base.extend(Callback, {
setMatrix: function(matrix) { setMatrix: function(matrix) {
this._matrix.initialize(matrix); this._matrix.initialize(matrix);
if (this._transformContent)
this.applyMatrix(true);
this._changed(5); this._changed(5);
}, },
@ -3649,7 +3652,7 @@ var Item = Base.extend(Callback, {
itemOffset = param.offset = bounds.getTopLeft().floor(); itemOffset = param.offset = bounds.getTopLeft().floor();
mainCtx = ctx; mainCtx = ctx;
ctx = CanvasProvider.getContext( ctx = CanvasProvider.getContext(
bounds.getSize().ceil().add(new Size(1, 1))); bounds.getSize().ceil().add(new Size(1, 1)), param.ratio);
} }
ctx.save(); ctx.save();
if (direct) { if (direct) {
@ -3670,7 +3673,7 @@ var Item = Base.extend(Callback, {
ctx.clip(); ctx.clip();
if (!direct) { if (!direct) {
BlendMode.process(blendMode, ctx, mainCtx, opacity, BlendMode.process(blendMode, ctx, mainCtx, opacity,
itemOffset.subtract(prevOffset)); itemOffset.subtract(prevOffset).multiply(param.ratio));
CanvasProvider.release(ctx); CanvasProvider.release(ctx);
param.offset = prevOffset; param.offset = prevOffset;
} }
@ -5942,19 +5945,19 @@ var PathItem = Item.extend({
control, control,
current = new Point(); current = new Point();
function getCoord(index, coord, update) { function getCoord(index, coord, isCurrent) {
var val = parseFloat(coords[index]); var val = parseFloat(coords[index]);
if (relative) if (relative)
val += current[coord]; val += current[coord];
if (update) if (isCurrent)
current[coord] = val; current[coord] = val;
return val; return val;
} }
function getPoint(index, update) { function getPoint(index, isCurrent) {
return new Point( return new Point(
getCoord(index, 'x', update), getCoord(index, 'x', isCurrent),
getCoord(index + 1, 'y', update) getCoord(index + 1, 'y', isCurrent)
); );
} }
@ -5973,6 +5976,7 @@ var PathItem = Item.extend({
for (var j = 0; j < length; j += 2) for (var j = 0; j < length; j += 2)
this[j === 0 && lower === 'm' ? 'moveTo' : 'lineTo']( this[j === 0 && lower === 'm' ? 'moveTo' : 'lineTo'](
getPoint(j, true)); getPoint(j, true));
control = current;
break; break;
case 'h': case 'h':
case 'v': case 'v':
@ -5981,6 +5985,7 @@ var PathItem = Item.extend({
getCoord(j, coord, true); getCoord(j, coord, true);
this.lineTo(current); this.lineTo(current);
} }
control = current;
break; break;
case 'c': case 'c':
for (var j = 0; j < length; j += 6) { for (var j = 0; j < length; j += 6) {
@ -6075,9 +6080,8 @@ var Path = PathItem.extend({
delete this._length; delete this._length;
delete this._clockwise; delete this._clockwise;
if (this._curves) { if (this._curves) {
for (var i = 0, l = this._curves.length; i < l; i++) { for (var i = 0, l = this._curves.length; i < l; i++)
this._curves[i]._changed(5); this._curves[i]._changed(5);
}
} }
} else if (flags & 8) { } else if (flags & 8) {
delete this._bounds; delete this._bounds;
@ -6916,7 +6920,6 @@ var Path = PathItem.extend({
if (hasFill || hasStroke && !dashLength || compound || clip) if (hasFill || hasStroke && !dashLength || compound || clip)
drawSegments(ctx, this); drawSegments(ctx, this);
if (this._closed) if (this._closed)
ctx.closePath(); ctx.closePath();
@ -7678,10 +7681,12 @@ var CompoundPath = PathItem.extend({
var children = this._children; var children = this._children;
if (children.length === 0) if (children.length === 0)
return; return;
ctx.beginPath(); ctx.beginPath();
param = param.extend({ compound: true }); param = param.extend({ compound: true });
for (var i = 0, l = children.length; i < l; i++) for (var i = 0, l = children.length; i < l; i++)
children[i].draw(ctx, param); children[i].draw(ctx, param);
if (!param.clip) { if (!param.clip) {
this._setStyles(ctx); this._setStyles(ctx);
var style = this._style; var style = this._style;
@ -9513,10 +9518,9 @@ var View = Base.extend(Callback, {
if (size.isNaN()) if (size.isNaN())
size = DomElement.getSize(element); size = DomElement.getSize(element);
} }
element.width = size.width; this._setViewSize(size);
element.height = size.height;
if (PaperScope.hasAttribute(element, 'stats') if (PaperScope.hasAttribute(element, 'stats')
&& typeof Stats === 'object') { && typeof Stats !== 'undefined') {
this._stats = new Stats(); this._stats = new Stats();
var stats = this._stats.domElement, var stats = this._stats.domElement,
style = stats.style, style = stats.style,
@ -9528,8 +9532,7 @@ var View = Base.extend(Callback, {
} }
View._views.push(this); View._views.push(this);
View._viewsById[this._id] = this; View._viewsById[this._id] = this;
this._viewSize = new LinkedSize(size.width, size.height, this._viewSize = size;
this, 'setViewSize');
this._matrix = new Matrix(); this._matrix = new Matrix();
this._zoom = 1; this._zoom = 1;
if (!View._focused) if (!View._focused)
@ -9655,7 +9658,8 @@ var View = Base.extend(Callback, {
}, },
getViewSize: function() { getViewSize: function() {
return this._viewSize; var size = this._viewSize;
return new LinkedSize(size.width, size.height, this, 'setViewSize');
}, },
setViewSize: function(size) { setViewSize: function(size) {
@ -9663,9 +9667,8 @@ var View = Base.extend(Callback, {
var delta = size.subtract(this._viewSize); var delta = size.subtract(this._viewSize);
if (delta.isZero()) if (delta.isZero())
return; return;
this._element.width = size.width; this._viewSize.set(size.width, size.height);
this._element.height = size.height; this._setViewSize(size);
this._viewSize.set(size.width, size.height, true);
this._bounds = null; this._bounds = null;
this.fire('resize', { this.fire('resize', {
size: size, size: size,
@ -9674,6 +9677,12 @@ var View = Base.extend(Callback, {
this._redraw(); this._redraw();
}, },
_setViewSize: function(size) {
var element = this._element;
element.width = size.width;
element.height = size.height;
},
getBounds: function() { getBounds: function() {
if (!this._bounds) if (!this._bounds)
this._bounds = this._matrix.inverted()._transformBounds( this._bounds = this._matrix.inverted()._transformBounds(
@ -9848,34 +9857,44 @@ var CanvasView = View.extend({
var size = Size.read(arguments); var size = Size.read(arguments);
if (size.isZero()) if (size.isZero())
throw new Error( throw new Error(
'Cannot create CanvasView with the provided arguments: ' 'Cannot create CanvasView with the provided argument: '
+ arguments); + canvas);
canvas = CanvasProvider.getCanvas(size); canvas = CanvasProvider.getCanvas(size);
} }
var ctx = this._context = canvas.getContext('2d'); this._context = canvas.getContext('2d');
this._eventCounters = {}; this._eventCounters = {};
var ratio = (window.devicePixelRatio || 1) / (DomElement.getPrefixValue( this._ratio = 1;
ctx, 'backingStorePixelRatio') || 1); if (PaperScope.getAttribute(canvas, 'hidpi') !== 'off') {
if (ratio > 1) { var deviceRatio = window.devicePixelRatio || 1,
var width = canvas.clientWidth, backingStoreRatio = DomElement.getPrefixValue(this._context,
height = canvas.clientHeight, 'backingStorePixelRatio') || 1;
style = canvas.style; this._ratio = deviceRatio / backingStoreRatio;
canvas.width = width * ratio;
canvas.height = height * ratio;
style.width = width + 'px';
style.height = height + 'px';
ctx.scale(ratio, ratio);
} }
View.call(this, canvas); View.call(this, canvas);
}, },
_setViewSize: function(size) {
var width = size.width,
height = size.height,
ratio = this._ratio,
element = this._element,
style = element.style;
element.width = width * ratio;
element.height = height * ratio;
if (ratio !== 1) {
style.width = width + 'px';
style.height = height + 'px';
this._context.scale(ratio, ratio);
}
},
draw: function(checkRedraw) { draw: function(checkRedraw) {
if (checkRedraw && !this._project._needsRedraw) if (checkRedraw && !this._project._needsRedraw)
return false; return false;
var ctx = this._context, var ctx = this._context,
size = this._viewSize; size = this._viewSize;
ctx.clearRect(0, 0, size._width + 1, size._height + 1); ctx.clearRect(0, 0, size.width + 1, size.height + 1);
this._project.draw(ctx, this._matrix); this._project.draw(ctx, this._matrix, this._ratio);
this._project._needsRedraw = false; this._project._needsRedraw = false;
return true; return true;
} }
@ -10630,25 +10649,36 @@ var Http = {
var CanvasProvider = { var CanvasProvider = {
canvases: [], canvases: [],
getCanvas: function(width, height) { getCanvas: function(width, height, ratio) {
var size = height === undefined ? width : new Size(width, height), var canvas,
canvas,
init = true; init = true;
if (typeof width === 'object') {
ratio = height;
height = width.height;
width = width.width;
}
if (!ratio) {
ratio = 1;
} else if (ratio !== 1) {
width *= ratio;
height *= ratio;
}
if (this.canvases.length) { if (this.canvases.length) {
canvas = this.canvases.pop(); canvas = this.canvases.pop();
} else { } else {
canvas = document.createElement('canvas'); canvas = document.createElement('canvas');
} }
var ctx = canvas.getContext('2d'); var ctx = canvas.getContext('2d');
ctx.save(); if (canvas.width === width && canvas.height === height) {
if (canvas.width === size.width && canvas.height === size.height) {
if (init) if (init)
ctx.clearRect(0, 0, size.width + 1, size.height + 1); ctx.clearRect(0, 0, width + 1, height + 1);
} else { } else {
canvas.width = size.width; canvas.width = width;
canvas.height = size.height; canvas.height = height;
} }
ctx.save();
if (ratio !== 1)
ctx.scale(ratio, ratio);
return canvas; return canvas;
}, },
@ -11370,12 +11400,12 @@ new function() {
function importGroup(node, type, isRoot, options) { function importGroup(node, type, isRoot, options) {
var nodes = node.childNodes, var nodes = node.childNodes,
clip = type === 'clippath', isClip = type === 'clippath',
item = new Group(), item = new Group(),
project = item._project, project = item._project,
currentStyle = project._currentStyle, currentStyle = project._currentStyle,
children = []; children = [];
if (!clip) { if (!isClip) {
item._transformContent = false; item._transformContent = false;
item = applyAttributes(item, node, isRoot); item = applyAttributes(item, node, isRoot);
project._currentStyle = item._style.clone(); project._currentStyle = item._style.clone();
@ -11389,10 +11419,10 @@ new function() {
children.push(child); children.push(child);
} }
item.addChildren(children); item.addChildren(children);
if (clip) if (isClip)
item = applyAttributes(item.reduce(), node, isRoot); item = applyAttributes(item.reduce(), node, isRoot);
project._currentStyle = currentStyle; project._currentStyle = currentStyle;
if (clip || type === 'defs') { if (isClip || type === 'defs') {
item.remove(); item.remove();
item = null; item = null;
} }
@ -11444,10 +11474,23 @@ new function() {
} }
var importers = { var importers = {
'#document': function(node, type, isRoot, options) { '#document': function (node, type, isRoot, options) {
return importSVG(node.childNodes[0], isRoot, options); var nodes = node.childNodes;
for (var i = 0, l = nodes.length; i < l; i++) {
var child = nodes[i];
if (child.nodeType === 1) {
var next = child.nextSibling;
document.body.appendChild(child);
var item = importSVG(child, isRoot, options);
if (next) {
node.insertBefore(child, next);
} else {
node.appendChild(child);
}
return item;
}
}
}, },
g: importGroup, g: importGroup,
svg: importGroup, svg: importGroup,
clippath: importGroup, clippath: importGroup,
@ -11673,30 +11716,48 @@ new function() {
return match && definitions[match[1]]; return match && definitions[match[1]];
} }
function importSVG(node, isRoot, options) { function importSVG(source, isRoot, options) {
if (!options) if (!source)
return null;
if (!options) {
options = {}; options = {};
if (typeof node === 'string') { } else if (typeof options === 'function') {
if (isRoot && !/^.*</.test(node)) { options = { onLoad: options };
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');
} }
var node = source,
scope = paper;
function onLoadCallback(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);
}
if (isRoot) {
if (typeof source === 'string' && !/^.*</.test(source)) {
return Http.request('get', source, onLoadCallback);
} else if (typeof File !== 'undefined' && source instanceof File) {
var reader = new FileReader();
reader.onload = function() {
onLoadCallback(reader.result);
};
return reader.readAsText(source);
}
}
if (typeof source === 'string')
node = new DOMParser().parseFromString(source, 'image/svg+xml');
if (!node.nodeName)
throw new Error('Unsupported SVG source: ' + source);
var type = node.nodeName.toLowerCase(), var type = node.nodeName.toLowerCase(),
importer = importers[type], importer = importers[type],
item = importer && importer(node, type, isRoot, options), item = importer && importer(node, type, isRoot, options) || null,
data = type !== '#document' && node.getAttribute('data-paper-data'); data = node.getAttribute && node.getAttribute('data-paper-data');
if (item) { if (item) {
if (!(item instanceof Group)) if (!(item instanceof Group))
item = applyAttributes(item, node, isRoot); item = applyAttributes(item, node, isRoot);
@ -11732,6 +11793,7 @@ paper = new (PaperScope.inject(Base.merge(Base.exports, {
Numerical: Numerical, Numerical: Numerical,
DomElement: DomElement, DomElement: DomElement,
DomEvent: DomEvent, DomEvent: DomEvent,
Http: Http,
Key: Key Key: Key
})))(); })))();
@ -11764,7 +11826,7 @@ paper.PaperScope.prototype.PaperScript = (function(root) {
}; };
var fields = Base.each( var fields = Base.each(
'add,subtract,multiply,divide,modulo,negate'.split(','), ['add', 'subtract', 'multiply', 'divide', 'modulo', 'negate'],
function(name) { function(name) {
this['_' + name] = '#' + name; this['_' + name] = '#' + name;
}, },
@ -11935,7 +11997,7 @@ paper.PaperScope.prototype.PaperScript = (function(root) {
|| new PaperScope(script).setup(canvas), || new PaperScope(script).setup(canvas),
src = script.src; src = script.src;
if (src) { if (src) {
Http.request('get', src, function(code) { paper.Http.request('get', src, function(code) {
evaluate(code, scope); evaluate(code, scope);
}); });
} else { } else {

View file

@ -1,6 +1,6 @@
{ {
"name": "paper", "name": "paper",
"version": "0.9.11", "version": "0.9.12",
"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",