mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-20 22:39:50 -05:00
Merge remote branch 'origin/master'
This commit is contained in:
commit
5e80be7402
12 changed files with 128 additions and 54 deletions
|
@ -57,7 +57,7 @@ var GradientColor = this.GradientColor = Color.extend({
|
|||
},
|
||||
|
||||
setOrigin: function(origin) {
|
||||
// PORT: add clone to Scriptographer
|
||||
// PORT: Add clone to Scriptographer
|
||||
origin = Point.read(arguments).clone();
|
||||
this._origin = origin;
|
||||
if (this._destination)
|
||||
|
@ -76,7 +76,7 @@ var GradientColor = this.GradientColor = Color.extend({
|
|||
},
|
||||
|
||||
setDestination: function(destination) {
|
||||
// PORT: add clone to Scriptographer
|
||||
// PORT: Add clone to Scriptographer
|
||||
destination = Point.read(arguments).clone();
|
||||
this._destination = destination;
|
||||
this._radius = this._destination.getDistance(this._origin);
|
||||
|
@ -94,7 +94,7 @@ var GradientColor = this.GradientColor = Color.extend({
|
|||
},
|
||||
|
||||
setHilite: function(hilite) {
|
||||
// PORT: add clone to Scriptographer
|
||||
// PORT: Add clone to Scriptographer
|
||||
hilite = Point.read(arguments).clone();
|
||||
var vector = hilite.subtract(this._origin);
|
||||
if (vector.getLength() > this._radius) {
|
||||
|
|
|
@ -591,11 +591,11 @@ var Item = this.Item = Base.extend({
|
|||
* @ignore
|
||||
*/
|
||||
isEditable: function() {
|
||||
var parent = this;
|
||||
while (parent) {
|
||||
if (!parent.visible || parent.locked)
|
||||
var item = this;
|
||||
while (item) {
|
||||
if (!item.visible || item.locked)
|
||||
return false;
|
||||
parent = parent._parent;
|
||||
item = item._parent;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
@ -607,6 +607,32 @@ var Item = this.Item = Base.extend({
|
|||
*/
|
||||
// TODO: isValid / checkValid
|
||||
|
||||
/**
|
||||
* Returns -1 if 'this' is above 'item', 1 if below, 0 if their order is not
|
||||
* defined in such a way, e.g. if one is a descendant of the other.
|
||||
*/
|
||||
_getOrder: function(item) {
|
||||
// Private method that produces a list of anchestors, starting with the
|
||||
// root and ending with the actual element as the last entry.
|
||||
function getList(item) {
|
||||
var list = [];
|
||||
do {
|
||||
list.unshift(item);
|
||||
} while (item = item._parent)
|
||||
return list;
|
||||
}
|
||||
var list1 = getList(this),
|
||||
list2 = getList(item);
|
||||
for (var i = 0, l = Math.min(list1.length, list2.length); i < l; i++) {
|
||||
if (list1[i] != list2[i]) {
|
||||
// Found the position in the parents list where the two start
|
||||
// to differ. Look at who's above who.
|
||||
return list1[i]._index < list2[i]._index ? 1 : -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if this item is above the specified item in the stacking order
|
||||
* of the project.
|
||||
|
@ -614,7 +640,9 @@ var Item = this.Item = Base.extend({
|
|||
* @param {Item} item The item to check against
|
||||
* @return {boolean} {@true if it is above the specified item}
|
||||
*/
|
||||
// TODO: isAbove
|
||||
isAbove: function(item) {
|
||||
return this._getOrder(item) == -1;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if the item is below the specified item in the stacking order of
|
||||
|
@ -623,7 +651,9 @@ var Item = this.Item = Base.extend({
|
|||
* @param {Item} item The item to check against
|
||||
* @return {boolean} {@true if it is below the specified item}
|
||||
*/
|
||||
// TODO: isBelow
|
||||
isBelow: function(item) {
|
||||
return this._getOrder(item) == 1;
|
||||
},
|
||||
|
||||
/**
|
||||
* {@grouptitle Hierarchy Tests}
|
||||
|
@ -652,6 +682,7 @@ var Item = this.Item = Base.extend({
|
|||
* @param {Item} item The item to check against
|
||||
* @return {boolean} {@true if it is inside the specified item}
|
||||
*/
|
||||
// TODO: Consider naming this isInside?
|
||||
isDescendant: function(item) {
|
||||
var parent = this;
|
||||
while (parent = parent._parent) {
|
||||
|
@ -668,6 +699,7 @@ var Item = this.Item = Base.extend({
|
|||
* @return {boolean} {@true if the item is an ancestor of the specified
|
||||
* item}
|
||||
*/
|
||||
// TODO: Consider naming this contains?
|
||||
isAncestor: function(item) {
|
||||
return item ? item.isDescendant(this) : false;
|
||||
},
|
||||
|
|
|
@ -125,7 +125,8 @@ var PathStyle = this.PathStyle = Base.extend(new function() {
|
|||
&& style.equals(childStyle))) {
|
||||
// If there is another item with a different style,
|
||||
// the style is not defined:
|
||||
// PORT: Change this in Sg (currently returns null)
|
||||
// PORT: Change this in Scriptographer
|
||||
// (currently returns null)
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -93,13 +93,19 @@ if (window.tests) {
|
|||
'test/tests/Point.js',
|
||||
'test/tests/Size.js',
|
||||
'test/tests/Rectangle.js',
|
||||
|
||||
'test/tests/Color.js',
|
||||
|
||||
'test/tests/Project.js',
|
||||
|
||||
'test/tests/Item.js',
|
||||
'test/tests/Item_Cloning.js',
|
||||
'test/tests/Item_Order.js',
|
||||
|
||||
'test/tests/Layer.js',
|
||||
'test/tests/Group.js',
|
||||
'test/tests/Segment.js',
|
||||
|
||||
'test/tests/Path.js',
|
||||
'test/tests/PathStyle.js',
|
||||
'test/tests/Path_Shapes.js',
|
||||
|
@ -108,6 +114,7 @@ if (window.tests) {
|
|||
'test/tests/Path_Bounds.js',
|
||||
'test/tests/Path_Length.js',
|
||||
'test/tests/CompoundPath.js',
|
||||
|
||||
'test/tests/PlacedSymbol.js'
|
||||
);
|
||||
}
|
||||
|
|
|
@ -241,7 +241,7 @@ var Curve = this.Curve = Base.extend({
|
|||
&& this._segment2._handleIn.isZero();
|
||||
},
|
||||
|
||||
// PORT: Add support for start parameter to Sg
|
||||
// PORT: Add support for start parameter to Scriptographer
|
||||
// DOCS: document Curve#getParameter(length, start)
|
||||
/**
|
||||
* @param {Number} length
|
||||
|
@ -328,7 +328,7 @@ var Curve = this.Curve = Base.extend({
|
|||
x, y;
|
||||
|
||||
// Handle special case at beginning / end of curve
|
||||
// PORT: Change in Sg too, so 0.000000000001 won't be
|
||||
// PORT: Change in Scriptographer too, so 0.000000000001 won't be
|
||||
// required anymore
|
||||
if (t == 0 || t == 1) {
|
||||
var point;
|
||||
|
|
|
@ -275,7 +275,7 @@ var Path = this.Path = PathItem.extend({
|
|||
this._project._selectItem(this, count == 1);
|
||||
},
|
||||
|
||||
// PORT: Add support for adding multiple segments at once to Sg
|
||||
// PORT: Add support for adding multiple segments at once to Scriptographer
|
||||
// DOCS: find a way to document the variable segment parameters of Path#add
|
||||
/**
|
||||
* Adds one or more segments to the end of the segment list of this path.
|
||||
|
@ -293,7 +293,7 @@ var Path = this.Path = PathItem.extend({
|
|||
: this._add([ Segment.read(arguments) ])[0];
|
||||
},
|
||||
|
||||
// PORT: Add support for adding multiple segments at once to Sg
|
||||
// PORT: Add support for adding multiple segments at once to Scriptographer
|
||||
/**
|
||||
* Inserts one or more segments at a given index in the list of this path's
|
||||
* segments.
|
||||
|
@ -311,17 +311,17 @@ var Path = this.Path = PathItem.extend({
|
|||
: this._add([ Segment.read(arguments, 1) ], index)[0];
|
||||
},
|
||||
|
||||
// PORT: Add to Sg
|
||||
// PORT: Add to Scriptographer
|
||||
addSegment: function(segment) {
|
||||
return this._add([ Segment.read(arguments) ])[0];
|
||||
},
|
||||
|
||||
// PORT: Add to Sg
|
||||
// PORT: Add to Scriptographer
|
||||
insertSegment: function(index, segment) {
|
||||
return this._add([ Segment.read(arguments, 1) ], index)[0];
|
||||
},
|
||||
|
||||
// PORT: Add to Sg
|
||||
// PORT: Add to Scriptographer
|
||||
/**
|
||||
* Adds an array of segments (or types that can be converted to segments)
|
||||
* to the end of the {@link #segments} array.
|
||||
|
@ -340,7 +340,7 @@ var Path = this.Path = PathItem.extend({
|
|||
return this._add(Segment.readAll(segments));
|
||||
},
|
||||
|
||||
// PORT: Add to Sg
|
||||
// PORT: Add to Scriptographer
|
||||
/**
|
||||
* Inserts an array of segments at a given index in the path's
|
||||
* {@link #segments} array.
|
||||
|
@ -355,7 +355,7 @@ var Path = this.Path = PathItem.extend({
|
|||
return this._add(Segment.readAll(segments), index);
|
||||
},
|
||||
|
||||
// PORT: Add to Sg
|
||||
// PORT: Add to Scriptographer
|
||||
/**
|
||||
* Removes the segment at the specified index of the path's
|
||||
* {@link #segments} array.
|
||||
|
@ -368,7 +368,7 @@ var Path = this.Path = PathItem.extend({
|
|||
return segments[0] || null;
|
||||
},
|
||||
|
||||
// PORT: Add to Sg
|
||||
// PORT: Add to Scriptographer
|
||||
/**
|
||||
* Removes the segments from the specified 'from' index to the specified
|
||||
* 'to' index from the path's {@link #segments} array.
|
||||
|
@ -592,7 +592,7 @@ var Path = this.Path = PathItem.extend({
|
|||
},
|
||||
|
||||
// TODO: getLocationAt(point, precision)
|
||||
// PORT: Rename functions and add new isParameter argument in Sg
|
||||
// PORT: Rename functions and add new isParameter argument in Scriptographer
|
||||
// DOCS: document Path#getLocationAt
|
||||
/**
|
||||
* @param {Number} offset
|
||||
|
|
|
@ -41,6 +41,14 @@ var Project = this.Project = Base.extend({
|
|||
// Push it onto this._scope.projects and set index:
|
||||
this._index = this._scope.projects.push(this) - 1;
|
||||
this._currentStyle = PathStyle.create(null);
|
||||
this.setCurrentStyle({
|
||||
strokeWidth: 1,
|
||||
strokeCap: 'butt',
|
||||
strokeJoin: 'miter',
|
||||
miterLimit: 10,
|
||||
dashOffset: 0,
|
||||
dashArray: []
|
||||
});
|
||||
this._selectedItems = {};
|
||||
this._selectedItemCount = 0;
|
||||
// Activate straight away so paper.project is set, as required by
|
||||
|
|
|
@ -21,7 +21,7 @@ var Event = this.Event = Base.extend({
|
|||
this.event = event;
|
||||
},
|
||||
|
||||
// PORT: Add to Sg
|
||||
// PORT: Add to Scriptographer
|
||||
preventDefault: function() {
|
||||
DomEvent.preventDefault(this.event);
|
||||
},
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
* All rights reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
* @name Key
|
||||
*/
|
||||
var Key = this.Key = new function() {
|
||||
// TODO: make sure the keys are called the same as in Scriptographer
|
||||
// Missing: tab, cancel, clear, page-down, page-up, comma, minus, period,
|
||||
|
@ -76,7 +72,7 @@ var Key = this.Key = new function() {
|
|||
// Call the onKeyDown or onKeyUp handler if present
|
||||
// When the handler function returns false, prevent the
|
||||
// default behaviour of the key event:
|
||||
// PORT: Add to Sg
|
||||
// PORT: Add to Scriptographer
|
||||
var keyEvent = new KeyEvent(down, key, character, event);
|
||||
if (tool[handler](keyEvent) === false)
|
||||
keyEvent.preventDefault();
|
||||
|
@ -131,25 +127,8 @@ var Key = this.Key = new function() {
|
|||
});
|
||||
|
||||
return {
|
||||
/** @lends Key */
|
||||
|
||||
modifiers: modifiers,
|
||||
|
||||
/**
|
||||
* Checks whether the specified key is pressed.
|
||||
*
|
||||
* @example
|
||||
* function onMouseDown(event) {
|
||||
* if(Key.isDown('shift')) {
|
||||
* console.log('The shift key is currently pressed.')
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param {String} key One of: 'backspace', 'enter', 'shift', 'control',
|
||||
* 'option', 'pause', 'caps-lock', 'escape', 'space', 'end', 'home',
|
||||
* 'left', 'up', 'right', 'down', 'delete', 'command'
|
||||
* @return {boolean} {@true if the key is pressed}
|
||||
*/
|
||||
isDown: function(key) {
|
||||
return !!keyMap[key];
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@ function cloneAndCompare(item) {
|
|||
}
|
||||
|
||||
test('Path#clone()', function() {
|
||||
var proj = paper.project;
|
||||
var path = new Path([10, 20], [30, 40]);
|
||||
path.closed = true;
|
||||
path.name = 'test';
|
||||
|
@ -45,7 +44,6 @@ test('Path#clone() with GradientColor', function() {
|
|||
var gradient = new Gradient(colors, 'radial');
|
||||
var color = new GradientColor(gradient, [0, 0], [20, 20], [10, 10]);
|
||||
|
||||
var proj = paper.project;
|
||||
var path = new Path([10, 20], [30, 40]);
|
||||
path.fillColor = color;
|
||||
cloneAndCompare(path);
|
||||
|
|
43
test/tests/Item_Order.js
Normal file
43
test/tests/Item_Order.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
test('Item Order', function() {
|
||||
var line = new Path();
|
||||
line.add([0, 0], [100, 100]);
|
||||
line.name = 'line';
|
||||
|
||||
var circle = new Path.Circle([50, 50], 50);
|
||||
circle.name = 'circle';
|
||||
|
||||
var group = new Group([circle]);
|
||||
group.name = 'group';
|
||||
|
||||
equals(function() {
|
||||
return circle.isAbove(line);
|
||||
}, true);
|
||||
equals(function() {
|
||||
return line.isBelow(circle);
|
||||
}, true);
|
||||
|
||||
equals(function() {
|
||||
return group.isAbove(line);
|
||||
}, true);
|
||||
equals(function() {
|
||||
return line.isBelow(group);
|
||||
}, true);
|
||||
|
||||
|
||||
equals(function() {
|
||||
return group.isAncestor(circle);
|
||||
}, true);
|
||||
|
||||
equals(function() {
|
||||
return circle.isDescendant(group);
|
||||
}, true);
|
||||
|
||||
|
||||
equals(function() {
|
||||
return group.isAbove(circle);
|
||||
}, false);
|
||||
|
||||
equals(function() {
|
||||
return group.isBelow(circle);
|
||||
}, false);
|
||||
});
|
|
@ -3,17 +3,23 @@ module('Path Style');
|
|||
test('style defaults', function() {
|
||||
var path = new Path();
|
||||
equals(function() {
|
||||
return path.strokeCap == 'butt';
|
||||
}, true);
|
||||
return path.strokeWidth;
|
||||
}, 1);
|
||||
equals(function() {
|
||||
return path.strokeJoin == 'miter';
|
||||
}, true);
|
||||
return path.strokeCap;
|
||||
}, 'butt');
|
||||
equals(function() {
|
||||
return path.miterLimit == 10;
|
||||
}, true);
|
||||
return path.strokeJoin;
|
||||
}, 'miter');
|
||||
equals(function() {
|
||||
return path.strokeWidth == 1;
|
||||
}, true);
|
||||
return path.miterLimit;
|
||||
}, 10);
|
||||
equals(function() {
|
||||
return path.dashOffset;
|
||||
}, 0);
|
||||
equals(function() {
|
||||
return path.dashArray + '';
|
||||
}, [] + '');
|
||||
});
|
||||
|
||||
test('currentStyle', function() {
|
||||
|
|
Loading…
Reference in a new issue