mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-08-28 22:08:54 -04:00
Implement new and shorter segments array notation.
Supporting: - Closing paths by including `true` as the last entry - Nested segment arrays that can be passed to PathItem.create() and the CompoundPath constructor to create all sub-paths
This commit is contained in:
parent
13a68cec46
commit
e539633852
19 changed files with 201 additions and 154 deletions
|
@ -72,7 +72,7 @@
|
|||
"resemblejs": "^2.2.1",
|
||||
"run-sequence": "^1.2.2",
|
||||
"stats.js": "0.16.0",
|
||||
"straps": "^2.0.1"
|
||||
"straps": "^2.1.0"
|
||||
},
|
||||
"browser": {
|
||||
"canvas": false,
|
||||
|
|
|
@ -77,7 +77,7 @@ var ProxyContext = new function() {
|
|||
if (name === 'restore')
|
||||
this._indents--;
|
||||
console.log(this.getIndentation() + 'ctx.' + name + '('
|
||||
+ Array.prototype.slice.call(arguments, 0)
|
||||
+ Base.slice(arguments, 0)
|
||||
.map(stringify).join(', ')
|
||||
+ ');');
|
||||
if (name === 'save')
|
||||
|
|
|
@ -166,13 +166,13 @@ Base.inject(/** @lends Base# */{
|
|||
* @param {Array} list the list to read from, either an arguments object
|
||||
* or a normal array
|
||||
* @param {Number} start the index at which to start reading in the list
|
||||
* @param {Number} length the amount of elements that can be read
|
||||
* @param {Object} options `options.readNull` controls whether null is
|
||||
* returned or converted. `options.clone` controls whether passed
|
||||
* objects should be cloned if they are already provided in the
|
||||
* required type
|
||||
* @param {Number} length the amount of elements that can be read
|
||||
*/
|
||||
read: function(list, start, options, length) {
|
||||
read: function(list, start, options, amount) {
|
||||
// See if it's called directly on Base, and if so, read value and
|
||||
// return without object conversion.
|
||||
if (this === Base) {
|
||||
|
@ -182,24 +182,29 @@ Base.inject(/** @lends Base# */{
|
|||
}
|
||||
var proto = this.prototype,
|
||||
readIndex = proto._readIndex,
|
||||
index = start || readIndex && list.__index || 0;
|
||||
if (!length)
|
||||
length = list.length - index;
|
||||
var obj = list[index];
|
||||
begin = start || readIndex && list.__index || 0,
|
||||
length = list.length,
|
||||
obj = list[begin];
|
||||
amount = amount || length - begin;
|
||||
// When read() is called on a sub-class of which the object is
|
||||
// already an instance, or when there is only one value in the list
|
||||
// and it's null or undefined, return the obj.
|
||||
if (obj instanceof this
|
||||
|| options && options.readNull && obj == null && length <= 1) {
|
||||
|| options && options.readNull && obj == null && amount <= 1) {
|
||||
if (readIndex)
|
||||
list.__index = index + 1;
|
||||
list.__index = begin + 1;
|
||||
return obj && options && options.clone ? obj.clone() : obj;
|
||||
}
|
||||
// Otherwise, create a new object and read through its initialize
|
||||
// function.
|
||||
obj = Base.create(this.prototype);
|
||||
if (readIndex)
|
||||
obj.__read = true;
|
||||
obj = obj.initialize.apply(obj, index > 0 || length < list.length
|
||||
? Array.prototype.slice.call(list, index, index + length)
|
||||
: list) || obj;
|
||||
obj = obj.initialize.apply(obj, begin > 0 || begin + amount < length
|
||||
? Base.slice(list, begin, begin + amount)
|
||||
: list) || obj;
|
||||
if (readIndex) {
|
||||
list.__index = index + obj.__read;
|
||||
list.__index = begin + obj.__read;
|
||||
obj.__read = undefined;
|
||||
}
|
||||
return obj;
|
||||
|
@ -235,11 +240,14 @@ Base.inject(/** @lends Base# */{
|
|||
* returned or converted. `options.clone` controls whether passed
|
||||
* objects should be cloned if they are already provided in the
|
||||
* required type
|
||||
* @param {Number} amount the amount of elements that should be read
|
||||
*/
|
||||
readAll: function(list, start, options) {
|
||||
readList: function(list, start, options, amount) {
|
||||
var res = [],
|
||||
entry;
|
||||
for (var i = start || 0, l = list.length; i < l; i++) {
|
||||
entry,
|
||||
begin = start || 0,
|
||||
end = amount ? begin + amount : list.length;
|
||||
for (var i = begin; i < end; i++) {
|
||||
res.push(Array.isArray(entry = list[i])
|
||||
? this.read(entry, 0, options)
|
||||
: this.read(list, i, options, 1));
|
||||
|
@ -255,11 +263,16 @@ Base.inject(/** @lends Base# */{
|
|||
* various Path.Constructors.
|
||||
*
|
||||
* @param {Array} list the list to read from, either an arguments object
|
||||
* or a normal array
|
||||
* @param {Number} start the index at which to start reading in the list
|
||||
* or a normal array
|
||||
* @param {String} name the property name to read from
|
||||
* @param {Number} start the index at which to start reading in the list
|
||||
* @param {Object} options `options.readNull` controls whether null is
|
||||
* returned or converted. `options.clone` controls whether passed
|
||||
* objects should be cloned if they are already provided in the
|
||||
* required type
|
||||
* @param {Number} amount the amount of elements that can be read
|
||||
*/
|
||||
readNamed: function(list, name, start, options, length) {
|
||||
readNamed: function(list, name, start, options, amount) {
|
||||
var value = this.getNamed(list, name),
|
||||
hasObject = value !== undefined;
|
||||
if (hasObject) {
|
||||
|
@ -276,7 +289,7 @@ Base.inject(/** @lends Base# */{
|
|||
// shine through.
|
||||
filtered[name] = undefined;
|
||||
}
|
||||
return this.read(hasObject ? [value] : list, start, options, length);
|
||||
return this.read(hasObject ? [value] : list, start, options, amount);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -513,7 +526,7 @@ Base.inject(/** @lends Base# */{
|
|||
if (Base.isPlainObject(arg))
|
||||
arg.insert = false;
|
||||
}
|
||||
// When reusing an object, initialize it through #_set()
|
||||
// When reusing an object, initialize it through #set()
|
||||
// instead of the constructor function:
|
||||
(useTarget ? obj.set : ctor).apply(obj, args);
|
||||
// Clear target to only use it once.
|
||||
|
|
|
@ -80,7 +80,7 @@ var Emitter = {
|
|||
var handlers = this._callbacks && this._callbacks[type];
|
||||
if (!handlers)
|
||||
return false;
|
||||
var args = [].slice.call(arguments, 1),
|
||||
var args = Base.slice(arguments, 1),
|
||||
// Set the current target to `this` if the event object defines
|
||||
// #target but not #currentTarget.
|
||||
setTarget = event && event.target && !event.currentTarget;
|
||||
|
|
|
@ -74,8 +74,8 @@ var Group = Item.extend(/** @lends Group# */{
|
|||
* Creates a new Group item and places it at the top of the active layer.
|
||||
*
|
||||
* @name Group#initialize
|
||||
* @param {Object} object an object literal containing the properties to be
|
||||
* set on the group
|
||||
* @param {Object} object an object containing the properties to be set on
|
||||
* the group
|
||||
*
|
||||
* @example {@paperscript}
|
||||
* var path = new Path([100, 100], [100, 200]);
|
||||
|
|
|
@ -2328,24 +2328,21 @@ new function() { // Injection scope for hit-test functions shared with project
|
|||
* @return {Item[]} the inserted items, or `null` if inserted was not
|
||||
* possible
|
||||
*/
|
||||
insertChildren: function(index, items, _preserve, _proto) {
|
||||
insertChildren: function(index, items, _preserve) {
|
||||
// CompoundPath#insertChildren() requires _preserve and _type:
|
||||
// _preserve avoids changing of the children's path orientation
|
||||
// _proto enforces the prototype of the inserted items, as used by
|
||||
// CompoundPath#insertChildren()
|
||||
var children = this._children;
|
||||
if (children && items && items.length > 0) {
|
||||
// We need to clone items because it might be
|
||||
// an Item#children array. Also, we're removing elements if they
|
||||
// don't match _type. Use Array.prototype.slice because items can be
|
||||
// an arguments object.
|
||||
items = Array.prototype.slice.apply(items);
|
||||
// We need to clone items because it may be an Item#children array.
|
||||
// Also, we're removing elements if they don't match _type.
|
||||
// Use Base.slice() because items can be an arguments object.
|
||||
items = Base.slice(items);
|
||||
// Remove the items from their parents first, since they might be
|
||||
// inserted into their own parents, affecting indices.
|
||||
// Use the loop also to filter out wrong _type.
|
||||
// Use the loop also to filter invalid items.
|
||||
for (var i = items.length - 1; i >= 0; i--) {
|
||||
var item = items[i];
|
||||
if (!item || _proto && !(item instanceof _proto)) {
|
||||
if (!item) {
|
||||
items.splice(i, 1);
|
||||
} else {
|
||||
// Notify parent of change. Don't notify item itself yet,
|
||||
|
@ -3949,9 +3946,9 @@ new function() { // Injection scope for hit-test functions shared with project
|
|||
*
|
||||
* @name Item#on
|
||||
* @function
|
||||
* @param {Object} object an object literal containing one or more of the
|
||||
* following properties: {@values frame, mousedown, mouseup, mousedrag,
|
||||
* click, doubleclick, mousemove, mouseenter, mouseleave}
|
||||
* @param {Object} object an object containing one or more of the following
|
||||
* properties: {@values frame, mousedown, mouseup, mousedrag, click,
|
||||
* doubleclick, mousemove, mouseenter, mouseleave}
|
||||
* @return {Item} this item itself, so calls can be chained
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -4018,9 +4015,9 @@ new function() { // Injection scope for hit-test functions shared with project
|
|||
*
|
||||
* @name Item#off
|
||||
* @function
|
||||
* @param {Object} object an object literal containing one or more of the
|
||||
* following properties: {@values frame, mousedown, mouseup, mousedrag,
|
||||
* click, doubleclick, mousemove, mouseenter, mouseleave}
|
||||
* @param {Object} object an object containing one or more of the following
|
||||
* properties: {@values frame, mousedown, mouseup, mousedrag, click,
|
||||
* doubleclick, mousemove, mouseenter, mouseleave}
|
||||
* @return {Item} this item itself, so calls can be chained
|
||||
*/
|
||||
|
||||
|
|
|
@ -47,8 +47,8 @@ var Layer = Group.extend(/** @lends Layer# */{
|
|||
* so all newly created items will be placed within it.
|
||||
*
|
||||
* @name Layer#initialize
|
||||
* @param {Object} object an object literal containing the properties to be
|
||||
* set on the layer
|
||||
* @param {Object} object an object containing the properties to be set on
|
||||
* the layer
|
||||
*
|
||||
* @example {@paperscript}
|
||||
* var path = new Path([100, 100], [100, 200]);
|
||||
|
|
|
@ -408,8 +408,8 @@ statics: new function() {
|
|||
* object literal.
|
||||
*
|
||||
* @name Shape.Circle
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the shape's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* shape's attributes
|
||||
* @return {Shape} the newly created shape
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -481,8 +481,8 @@ statics: new function() {
|
|||
* object literal.
|
||||
*
|
||||
* @name Shape.Rectangle
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the shape's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* shape's attributes
|
||||
* @return {Shape} the newly created shape
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -541,8 +541,8 @@ statics: new function() {
|
|||
* object literal.
|
||||
*
|
||||
* @name Shape.Ellipse
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the shape's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* shape's attributes
|
||||
* @return {Shape} the newly created shape
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
|
|
@ -59,8 +59,8 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
|
|||
* at the top of the active layer.
|
||||
*
|
||||
* @name CompoundPath#initialize
|
||||
* @param {Object} object an object literal containing properties to
|
||||
* be set on the path
|
||||
* @param {Object} object an object containing properties to be set on the
|
||||
* path
|
||||
* @return {CompoundPath} the newly created path
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -107,31 +107,44 @@ var CompoundPath = PathItem.extend(/** @lends CompoundPath# */{
|
|||
},
|
||||
|
||||
insertChildren: function insertChildren(index, items, _preserve) {
|
||||
// Convert CompoundPath items in the children list by adding their
|
||||
// children to the list, replacing their parent.
|
||||
// If we're passed an array notation for a simple path, wrap it again
|
||||
// in an array to turn it into the array notation for a compound-path.
|
||||
var list = items,
|
||||
first = list[0];
|
||||
if (first && typeof first[0] === 'number')
|
||||
list = [list];
|
||||
// Perform some conversions depending on the type of item passed:
|
||||
// Convert array-notation to paths, and expand compound-paths in the
|
||||
// items list by adding their children to the it replacing their parent.
|
||||
for (var i = items.length - 1; i >= 0; i--) {
|
||||
var item = items[i];
|
||||
if (item instanceof CompoundPath) {
|
||||
// Clone the items array before modifying it, as it may be a
|
||||
// passed children array from another item.
|
||||
items = items.slice();
|
||||
items.splice.apply(items, [i, 1].concat(item.removeChildren()));
|
||||
var item = list[i];
|
||||
// Clone the list array before modifying it, as it may be a passed
|
||||
// children array from another item.
|
||||
if (list === items && !(item instanceof Path))
|
||||
list = Base.slice(list);
|
||||
if (Array.isArray(item)) {
|
||||
var path = new Path({ segments: item, insert: false });
|
||||
// Fix natural clockwise value, so it's not automatically
|
||||
// determined when inserted into the compound-path.
|
||||
// TODO: Remove reorientation code instead.
|
||||
path.setClockwise(path.isClockwise());
|
||||
list[i] = path;
|
||||
} else if (item instanceof CompoundPath) {
|
||||
list.splice.apply(list, [i, 1].concat(item.removeChildren()));
|
||||
item.remove();
|
||||
}
|
||||
}
|
||||
// Pass on 'path' for _type, to make sure that only paths are added as
|
||||
// children.
|
||||
items = insertChildren.base.call(this, index, items, _preserve, Path);
|
||||
list = insertChildren.base.call(this, index, list, _preserve);
|
||||
// All children except for the bottom one (first one in list) are set
|
||||
// to anti-clockwise orientation, so that they appear as holes, but
|
||||
// only if their orientation was not already specified before
|
||||
// (= _clockwise is defined).
|
||||
for (var i = 0, l = !_preserve && items && items.length; i < l; i++) {
|
||||
var item = items[i];
|
||||
for (var i = 0, l = !_preserve && list && list.length; i < l; i++) {
|
||||
var item = list[i];
|
||||
if (item._clockwise === undefined)
|
||||
item.setClockwise(item._index === 0);
|
||||
}
|
||||
return items;
|
||||
return list;
|
||||
},
|
||||
|
||||
// DOCS: reduce()
|
||||
|
|
|
@ -67,8 +67,8 @@ Path.inject({ statics: new function() {
|
|||
* literal.
|
||||
*
|
||||
* @name Path.Line
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the path's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* path's attributes
|
||||
* @return {Path} the newly created path
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -102,8 +102,8 @@ Path.inject({ statics: new function() {
|
|||
* object literal.
|
||||
*
|
||||
* @name Path.Circle
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the path's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* path's attributes
|
||||
* @return {Path} the newly created path
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -174,8 +174,8 @@ Path.inject({ statics: new function() {
|
|||
* object literal.
|
||||
*
|
||||
* @name Path.Rectangle
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the path's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* path's attributes
|
||||
* @return {Path} the newly created path
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -267,8 +267,8 @@ Path.inject({ statics: new function() {
|
|||
* object literal.
|
||||
*
|
||||
* @name Path.Ellipse
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the path's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* path's attributes
|
||||
* @return {Path} the newly created path
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -317,8 +317,8 @@ Path.inject({ statics: new function() {
|
|||
* object literal.
|
||||
*
|
||||
* @name Path.Arc
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the path's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* path's attributes
|
||||
* @return {Path} the newly created path
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -363,8 +363,8 @@ Path.inject({ statics: new function() {
|
|||
* described by an object literal.
|
||||
*
|
||||
* @name Path.RegularPolygon
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the path's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* path's attributes
|
||||
* @return {Path} the newly created path
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -417,8 +417,8 @@ Path.inject({ statics: new function() {
|
|||
* object literal.
|
||||
*
|
||||
* @name Path.Star
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the path's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* path's attributes
|
||||
* @return {Path} the newly created path
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
|
|
@ -51,8 +51,8 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* top of the active layer.
|
||||
*
|
||||
* @name Path#initialize
|
||||
* @param {Object} object an object literal containing properties to
|
||||
* be set on the path
|
||||
* @param {Object} object an object containing properties to be set on the
|
||||
* path
|
||||
* @return {Path} the newly created path
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
@ -178,13 +178,20 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
},
|
||||
|
||||
setSegments: function(segments) {
|
||||
var fullySelected = this.isFullySelected();
|
||||
var fullySelected = this.isFullySelected(),
|
||||
length = segments && segments.length;
|
||||
this._segments.length = 0;
|
||||
this._segmentSelection = 0;
|
||||
// Calculate new curves next time we call getCurves()
|
||||
this._curves = undefined;
|
||||
if (segments && segments.length > 0)
|
||||
this._add(Segment.readAll(segments));
|
||||
if (length) {
|
||||
var last = segments[length - 1];
|
||||
if (typeof last === 'boolean') {
|
||||
this.setClosed(last);
|
||||
length--;
|
||||
}
|
||||
this._add(Segment.readList(segments, 0, {}, length));
|
||||
}
|
||||
// Preserve fullySelected state.
|
||||
// TODO: Do we still need this?
|
||||
if (fullySelected)
|
||||
|
@ -326,14 +333,14 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
dy = curY - prevY;
|
||||
parts.push(
|
||||
dx === 0 ? 'v' + f.number(dy)
|
||||
: dy === 0 ? 'h' + f.number(dx)
|
||||
: dy === 0 ? 'h' + f.number(dx)
|
||||
: 'l' + f.pair(dx, dy));
|
||||
}
|
||||
} else {
|
||||
// c = relative curveto:
|
||||
parts.push('c' + f.pair(outX - prevX, outY - prevY)
|
||||
+ ' ' + f.pair(inX - prevX, inY - prevY)
|
||||
+ ' ' + f.pair(curX - prevX, curY - prevY));
|
||||
+ ' ' + f.pair( inX - prevX, inY - prevY)
|
||||
+ ' ' + f.pair(curX - prevX, curY - prevY));
|
||||
}
|
||||
}
|
||||
prevX = curX;
|
||||
|
@ -545,7 +552,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
add: function(segment1 /*, segment2, ... */) {
|
||||
return arguments.length > 1 && typeof segment1 !== 'number'
|
||||
// addSegments
|
||||
? this._add(Segment.readAll(arguments))
|
||||
? this._add(Segment.readList(arguments))
|
||||
// addSegment
|
||||
: this._add([ Segment.read(arguments) ])[0];
|
||||
},
|
||||
|
@ -589,7 +596,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
insert: function(index, segment1 /*, segment2, ... */) {
|
||||
return arguments.length > 2 && typeof segment1 !== 'number'
|
||||
// insertSegments
|
||||
? this._add(Segment.readAll(arguments, 1), index)
|
||||
? this._add(Segment.readList(arguments, 1), index)
|
||||
// insertSegment
|
||||
: this._add([ Segment.read(arguments, 1) ], index)[0];
|
||||
},
|
||||
|
@ -645,7 +652,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* path2.position.x += 30;
|
||||
*/
|
||||
addSegments: function(segments) {
|
||||
return this._add(Segment.readAll(segments));
|
||||
return this._add(Segment.readList(segments));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -659,7 +666,7 @@ var Path = PathItem.extend(/** @lends Path# */{
|
|||
* belongs to another path
|
||||
*/
|
||||
insertSegments: function(index, segments) {
|
||||
return this._add(Segment.readAll(segments), index);
|
||||
return this._add(Segment.readList(segments), index);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -34,15 +34,54 @@ var PathItem = Item.extend(/** @lends PathItem# */{
|
|||
* data describes a plain path or a compound-path with multiple
|
||||
* sub-paths.
|
||||
*
|
||||
* @name PathItem.create
|
||||
* @param {String} pathData the SVG path-data to parse
|
||||
* @return {Path|CompoundPath} the newly created path item
|
||||
*/
|
||||
create: function(pathData) {
|
||||
// If there are multiple moveTo commands or a closePath command
|
||||
// followed by other commands, we have a CompoundPath.
|
||||
var ctor = (pathData && pathData.match(/m/gi) || []).length > 1
|
||||
|| /z\s*\S+/i.test(pathData) ? CompoundPath : Path;
|
||||
return new ctor(pathData);
|
||||
|
||||
/**
|
||||
* Creates a path item from the given segments array, determining if the
|
||||
* array describes a plain path or a compound-path with multiple
|
||||
* sub-paths.
|
||||
*
|
||||
* @name PathItem.create
|
||||
* @param {Number[][]} segments the segments array to parse
|
||||
* @return {Path|CompoundPath} the newly created path item
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a path item from the given object, determining if the
|
||||
* contained information describes a plain path or a compound-path with
|
||||
* multiple sub-paths.
|
||||
*
|
||||
* @name PathItem.create
|
||||
* @param {Object} object an object containing the properties describing
|
||||
* the item to be created
|
||||
* @return {Path|CompoundPath} the newly created path item
|
||||
*/
|
||||
create: function(arg) {
|
||||
var data,
|
||||
segments,
|
||||
compound;
|
||||
if (Base.isPlainObject(arg)) {
|
||||
segments = arg.segments;
|
||||
data = arg.pathData;
|
||||
} else if (Array.isArray(arg)) {
|
||||
segments = arg;
|
||||
} else if (typeof arg === 'string') {
|
||||
data = arg;
|
||||
}
|
||||
if (segments) {
|
||||
var first = segments[0];
|
||||
compound = first && Array.isArray(first[0]);
|
||||
} else if (data) {
|
||||
// If there are multiple moveTo commands or a closePath command
|
||||
// followed by other commands, we have a CompoundPath.
|
||||
compound = (data.match(/m/gi) || []).length > 1
|
||||
|| /z\s*\S+/i.test(data);
|
||||
}
|
||||
var ctor = compound ? CompoundPath : Path;
|
||||
return new ctor(arg);
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -57,8 +57,8 @@ var Segment = Base.extend(/** @lends Segment# */{
|
|||
* Creates a new Segment object.
|
||||
*
|
||||
* @name Segment#initialize
|
||||
* @param {Object} object an object literal containing properties to
|
||||
* be set on the segment
|
||||
* @param {Object} object an object containing properties to be set on the
|
||||
* segment
|
||||
*
|
||||
* @example {@paperscript}
|
||||
* // Creating segments using object notation:
|
||||
|
@ -115,32 +115,31 @@ var Segment = Base.extend(/** @lends Segment# */{
|
|||
*/
|
||||
initialize: function Segment(arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||
var count = arguments.length,
|
||||
point, handleIn, handleOut,
|
||||
selection;
|
||||
// TODO: Use Point.read or Point.readNamed to read these?
|
||||
if (count === 0) {
|
||||
// Nothing
|
||||
} else if (count === 1) {
|
||||
// NOTE: This copies from existing segments through accessors.
|
||||
if (arg0 && 'point' in arg0) {
|
||||
point = arg0.point;
|
||||
handleIn = arg0.handleIn;
|
||||
handleOut = arg0.handleOut;
|
||||
selection = arg0.selection;
|
||||
point, handleIn, handleOut, selection;
|
||||
// TODO: Should we use Point.read() or Point.readNamed() to read these?
|
||||
if (count > 0) {
|
||||
if (arg0 == null || typeof arg0 === 'object') {
|
||||
// Handle undefined, null and passed objects:
|
||||
if (count === 1 && arg0 && 'point' in arg0) {
|
||||
// NOTE: This copies from segments through accessors.
|
||||
point = arg0.point;
|
||||
handleIn = arg0.handleIn;
|
||||
handleOut = arg0.handleOut;
|
||||
selection = arg0.selection;
|
||||
} else {
|
||||
// It doesn't matter if all of these arguments exist.
|
||||
// SegmentPoint() creates points with (0, 0) otherwise.
|
||||
point = arg0;
|
||||
handleIn = arg1;
|
||||
handleOut = arg2;
|
||||
selection = arg3;
|
||||
}
|
||||
} else {
|
||||
point = arg0;
|
||||
// Read points from the arguments list as a row of numbers.
|
||||
point = [ arg0, arg1 ];
|
||||
handleIn = arg2 !== undefined ? [ arg2, arg3 ] : null;
|
||||
handleOut = arg4 !== undefined ? [ arg4, arg5 ] : null;
|
||||
}
|
||||
} else if (arg0 == null || typeof arg0 === 'object') {
|
||||
// It doesn't matter if all of these arguments exist.
|
||||
// new SegmentPoint() produces creates points with (0, 0) otherwise.
|
||||
point = arg0;
|
||||
handleIn = arg1;
|
||||
handleOut = arg2;
|
||||
selection = arg3;
|
||||
} else { // Read points from the arguments list as a row of numbers
|
||||
point = arg0 !== undefined ? [ arg0, arg1 ] : null;
|
||||
handleIn = arg2 !== undefined ? [ arg2, arg3 ] : null;
|
||||
handleOut = arg4 !== undefined ? [ arg4, arg5 ] : null;
|
||||
}
|
||||
new SegmentPoint(point, this, '_point');
|
||||
new SegmentPoint(handleIn, this, '_handleIn');
|
||||
|
|
|
@ -483,8 +483,7 @@ var Color = Base.extend(new function() {
|
|||
*/
|
||||
initialize: function Color(arg) {
|
||||
// We are storing color internally as an array of components
|
||||
var slice = Array.prototype.slice,
|
||||
args = arguments,
|
||||
var args = arguments,
|
||||
reading = this.__read,
|
||||
read = 0,
|
||||
type,
|
||||
|
@ -512,7 +511,7 @@ var Color = Base.extend(new function() {
|
|||
if (reading)
|
||||
read = 1; // Will be increased below
|
||||
// Shift type out of the arguments, and process normally.
|
||||
args = slice.call(args, 1);
|
||||
args = Base.slice(args, 1);
|
||||
argType = typeof arg;
|
||||
}
|
||||
}
|
||||
|
@ -543,7 +542,7 @@ var Color = Base.extend(new function() {
|
|||
: 1;
|
||||
}
|
||||
if (values.length > length)
|
||||
values = slice.call(values, 0, length);
|
||||
values = Base.slice(values, 0, length);
|
||||
} else if (argType === 'string') {
|
||||
type = 'rgb';
|
||||
components = fromCSS(arg);
|
||||
|
|
|
@ -156,7 +156,7 @@ var Gradient = Base.extend(/** @lends Gradient# */{
|
|||
for (var i = 0, l = _stops.length; i < l; i++)
|
||||
_stops[i]._owner = undefined;
|
||||
}
|
||||
_stops = this._stops = GradientStop.readAll(stops, 0, { clone: true });
|
||||
_stops = this._stops = GradientStop.readList(stops, 0, { clone: true });
|
||||
// Now assign this gradient as the new gradients' owner.
|
||||
for (var i = 0, l = _stops.length; i < l; i++)
|
||||
_stops[i]._owner = this;
|
||||
|
|
|
@ -40,8 +40,8 @@ var PointText = TextItem.extend(/** @lends PointText# */{
|
|||
* literal.
|
||||
*
|
||||
* @name PointText#initialize
|
||||
* @param {Object} object an object literal containing properties
|
||||
* describing the path's attributes
|
||||
* @param {Object} object an object containing properties describing the
|
||||
* path's attributes
|
||||
* @return {PointText} the newly created point text
|
||||
*
|
||||
* @example {@paperscript}
|
||||
|
|
|
@ -39,7 +39,7 @@ var CanvasView = View.extend(/** @lends CanvasView# */{
|
|||
if (size.isZero())
|
||||
throw new Error(
|
||||
'Cannot create CanvasView with the provided argument: '
|
||||
+ [].slice.call(arguments, 1));
|
||||
+ Base.slice(arguments, 1));
|
||||
canvas = CanvasProvider.getCanvas(size);
|
||||
}
|
||||
var ctx = this._context = canvas.getContext('2d');
|
||||
|
|
|
@ -59,30 +59,9 @@ test('PathItem#create() with SVG path-data (#1101)', function() {
|
|||
return res;
|
||||
}
|
||||
|
||||
function create(data) {
|
||||
var first = data && data[0];
|
||||
if (first == null)
|
||||
return null;
|
||||
if (Array.isArray(first[0])) {
|
||||
return new CompoundPath(data.map(create));
|
||||
} else {
|
||||
var closed = data[data.length - 1];
|
||||
if (typeof closed === 'boolean') {
|
||||
data.length--;
|
||||
} else {
|
||||
closed = false;
|
||||
}
|
||||
var path = new Path({ segments: data, closed: closed });
|
||||
// Fix natural clockwise value, so it's not automatically determined
|
||||
// when inserted into the compound-path.
|
||||
path.clockwise = path.clockwise;
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
data.forEach(function(entry, i) {
|
||||
var path = PathItem.create(entry);
|
||||
// console.log(JSON.stringify(describe(path)));
|
||||
equals(path, create(expected[i]), 'data[' + i + ']');
|
||||
equals(path, PathItem.create(expected[i]), 'data[' + i + ']');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -133,7 +133,8 @@ test('Raster#getSubCanvas', function(assert) {
|
|||
255, 255, 255, 255
|
||||
];
|
||||
equals(function() {
|
||||
return Base.equals(Array.prototype.slice.call(ctx.getImageData(0, 0, 1, 2).data), expected);
|
||||
return Base.equals(Base.slice(ctx.getImageData(0, 0, 1, 2).data),
|
||||
expected);
|
||||
}, true);
|
||||
done();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue