2011-03-06 19:50:44 -05:00
|
|
|
/*
|
|
|
|
* Paper.js
|
|
|
|
*
|
|
|
|
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
|
|
|
|
* based on Scriptographer.org and designed to be largely API compatible.
|
|
|
|
* http://scriptographer.org/
|
|
|
|
*
|
|
|
|
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
|
|
|
|
* http://lehni.org/ & http://jonathanpuckey.com/
|
|
|
|
*
|
|
|
|
* All rights reserved. See LICENSE file for details.
|
|
|
|
*/
|
|
|
|
|
2011-03-04 08:34:31 -05:00
|
|
|
var CompoundPath = this.CompoundPath = PathItem.extend({
|
2011-03-03 07:23:46 -05:00
|
|
|
initialize: function(items) {
|
|
|
|
this.base();
|
|
|
|
this.children = [];
|
|
|
|
if (items) {
|
|
|
|
for (var i = 0, l = items.length; i < l; i++) {
|
|
|
|
this.appendTop(items[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-03-03 07:23:46 -05:00
|
|
|
// TODO: have getBounds of Group / Layer / CompoundPath use the same
|
|
|
|
// code (from a utility script?)
|
|
|
|
getBounds: function() {
|
|
|
|
if (this.children.length) {
|
2011-03-04 20:26:12 -05:00
|
|
|
var rect = this.children[0].getBounds();
|
2011-03-03 07:23:46 -05:00
|
|
|
var x1 = rect.x;
|
|
|
|
var y1 = rect.y;
|
|
|
|
var x2 = rect.x + rect.width;
|
|
|
|
var y2 = rect.y + rect.height;
|
|
|
|
for (var i = 1, l = this.children.length; i < l; i++) {
|
2011-03-04 20:26:12 -05:00
|
|
|
var rect2 = this.children[i].getBounds();
|
2011-03-03 07:23:46 -05:00
|
|
|
x1 = Math.min(rect2.x, x1);
|
|
|
|
y1 = Math.min(rect2.y, y1);
|
|
|
|
x2 = Math.max(rect2.x + rect2.width, x1 + x2 - x1);
|
|
|
|
y2 = Math.max(rect2.y + rect2.height, y1 + y2 - y1);
|
|
|
|
}
|
|
|
|
}
|
2011-03-06 13:45:56 -05:00
|
|
|
return Rectangle.create(x1, y1, x2 - x1, y2 - y1);
|
2011-03-03 07:23:46 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-03-03 07:23:46 -05:00
|
|
|
/**
|
|
|
|
* If this is a compound path with only one path inside,
|
|
|
|
* the path is moved outside and the compound path is erased.
|
|
|
|
* Otherwise, the compound path is returned unmodified.
|
|
|
|
*
|
|
|
|
* @return the simplified compound path.
|
|
|
|
*/
|
|
|
|
simplify: function() {
|
|
|
|
if (this.children.length == 1) {
|
|
|
|
var child = this.children[0];
|
|
|
|
child.moveAbove(this);
|
|
|
|
this.remove();
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
return this;
|
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-03-03 07:23:46 -05:00
|
|
|
smooth: function() {
|
|
|
|
for (var i = 0, l = this.children.length; i < l; i++) {
|
|
|
|
this.children[i].smooth();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
moveTo: function() {
|
|
|
|
var path = new Path();
|
|
|
|
this.appendTop(path);
|
|
|
|
path.moveTo.apply(path, arguments);
|
|
|
|
},
|
|
|
|
|
|
|
|
draw: function(ctx, param) {
|
|
|
|
var firstChild = this.children[0];
|
|
|
|
ctx.beginPath();
|
|
|
|
param.compound = true;
|
|
|
|
for (var i = 0, l = this.children.length; i < l; i++) {
|
|
|
|
Item.draw(this.children[i], ctx, param);
|
|
|
|
}
|
2011-03-04 20:37:02 -05:00
|
|
|
firstChild.setContextStyles(ctx);
|
2011-03-04 20:36:27 -05:00
|
|
|
var fillColor = firstChild.getFillColor(),
|
|
|
|
strokeColor = firstChild.getStrokeColor();
|
|
|
|
if (fillColor) {
|
|
|
|
ctx.fillStyle = fillColor.toCssString();
|
2011-03-03 07:23:46 -05:00
|
|
|
ctx.fill();
|
|
|
|
}
|
2011-03-04 20:36:27 -05:00
|
|
|
if (strokeColor) {
|
|
|
|
ctx.strokeStyle = strokeColor.toCssString();
|
2011-03-03 07:23:46 -05:00
|
|
|
ctx.stroke();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}, new function() {
|
2011-02-17 17:58:56 -05:00
|
|
|
|
2011-03-03 07:25:41 -05:00
|
|
|
function getCurrentPath(that) {
|
|
|
|
if (that.children.length) {
|
|
|
|
return that.children[that.children.length - 1];
|
2011-02-17 08:33:25 -05:00
|
|
|
} else {
|
2011-03-03 12:29:40 -05:00
|
|
|
throw new Error('Use a moveTo() command first');
|
2011-02-17 08:33:25 -05:00
|
|
|
}
|
|
|
|
}
|
2011-02-17 17:58:56 -05:00
|
|
|
|
2011-03-03 07:23:46 -05:00
|
|
|
var fields = {
|
2011-02-17 07:36:40 -05:00
|
|
|
moveBy: function() {
|
2011-02-24 11:13:41 -05:00
|
|
|
var point = arguments.length ? Point.read(arguments) : new Point();
|
|
|
|
var path = getCurrentPath(this);
|
|
|
|
var current = path.segments[path.segments.length - 1].point;
|
|
|
|
this.moveTo(current.add(point));
|
2011-02-17 18:01:18 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
closePath: function() {
|
2011-03-03 07:26:28 -05:00
|
|
|
var path = getCurrentPath(this);
|
2011-02-17 18:01:18 -05:00
|
|
|
path.setClosed(true);
|
2011-02-17 07:36:40 -05:00
|
|
|
}
|
2011-02-17 17:58:56 -05:00
|
|
|
};
|
2011-02-17 18:01:18 -05:00
|
|
|
|
2011-02-17 18:34:03 -05:00
|
|
|
Base.each(['lineTo', 'cubicCurveTo', 'quadraticCurveTo', 'curveTo',
|
|
|
|
'arcTo', 'lineBy', 'curveBy', 'arcBy'], function(key) {
|
|
|
|
fields[key] = function() {
|
2011-02-17 17:58:56 -05:00
|
|
|
var path = getCurrentPath(this);
|
2011-02-17 18:34:03 -05:00
|
|
|
path[key].apply(path, arguments);
|
2011-02-17 07:36:40 -05:00
|
|
|
};
|
2011-02-17 18:34:03 -05:00
|
|
|
});
|
2011-02-17 07:36:40 -05:00
|
|
|
|
2011-02-17 17:58:56 -05:00
|
|
|
return fields;
|
2011-03-03 07:19:43 -05:00
|
|
|
});
|