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
a90aa09bd7
3 changed files with 74 additions and 61 deletions
|
@ -15,19 +15,19 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var CompoundPath = this.CompoundPath = PathItem.extend({
|
var CompoundPath = this.CompoundPath = PathItem.extend({
|
||||||
// PORT: port the reversing of segments and keepDirection flag
|
initialize: function(paths) {
|
||||||
initialize: function(items, keepDirection) {
|
|
||||||
this.base();
|
this.base();
|
||||||
this._children = [];
|
this._children = [];
|
||||||
if (items) {
|
if (paths) {
|
||||||
for (var i = 0, l = items.length; i < l; i++) {
|
for (var i = 0, l = paths.length; i < l; i++) {
|
||||||
var item = items[i];
|
var path = paths[i];
|
||||||
// All paths except for the first one are reversed when
|
// All paths except for the top one (last one in list) are
|
||||||
// creating a compound path, so that they draw holes.
|
// set to clockwise orientation when creating a compound path,
|
||||||
// When keepDirection is set to true, child paths aren't reversed.
|
// so that they appear as holes, but only if their orientation
|
||||||
if (!keepDirection && i != l - 1)
|
// was not already specified before (= _clockwise is defined).
|
||||||
item.reverse();
|
if (path._clockwise === undefined)
|
||||||
this.appendTop(items[i]);
|
path.setClockwise(i < l - 1);
|
||||||
|
this.appendTop(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -34,6 +34,8 @@ var Path = this.Path = PathItem.extend({
|
||||||
delete this._bounds;
|
delete this._bounds;
|
||||||
delete this._position;
|
delete this._position;
|
||||||
delete this._strokeBounds;
|
delete this._strokeBounds;
|
||||||
|
// Clockwise state becomes undefined as soon as geometry changes.
|
||||||
|
delete this._clockwise;
|
||||||
} else if (flags & ChangeFlags.STROKE) {
|
} else if (flags & ChangeFlags.STROKE) {
|
||||||
delete this._strokeBounds;
|
delete this._strokeBounds;
|
||||||
}
|
}
|
||||||
|
@ -302,20 +304,66 @@ var Path = this.Path = PathItem.extend({
|
||||||
// TODO: curvesToPoints([maxPointDistance[, flatness]])
|
// TODO: curvesToPoints([maxPointDistance[, flatness]])
|
||||||
// TODO: reduceSegments([flatness])
|
// TODO: reduceSegments([flatness])
|
||||||
// TODO: split(offset) / split(location) / split(index[, parameter])
|
// TODO: split(offset) / split(location) / split(index[, parameter])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the path is oriented clock-wise, false otherwise.
|
||||||
|
*/
|
||||||
|
isClockwise: function() {
|
||||||
|
if (this._clockwise !== undefined)
|
||||||
|
return this._clockwise;
|
||||||
|
var sum = 0,
|
||||||
|
xPre, yPre;
|
||||||
|
function edge(x, y) {
|
||||||
|
if (xPre !== undefined)
|
||||||
|
sum += (xPre - x) * (y + yPre);
|
||||||
|
xPre = x;
|
||||||
|
yPre = y;
|
||||||
|
}
|
||||||
|
// Method derived from:
|
||||||
|
// http://stackoverflow.com/questions/1165647
|
||||||
|
// We treat the curve points and handles as the outline of a polygon of
|
||||||
|
// which we determine the orientation using the method of calculating
|
||||||
|
// the sum over the edges. This will work even with non-convex polygons,
|
||||||
|
// telling you whether it's mostly clockwise
|
||||||
|
for (var i = 0, l = this._segments.length; i < l; i++) {
|
||||||
|
var seg1 = this._segments[i],
|
||||||
|
seg2 = this._segments[i + 1 < l ? i + 1 : 0],
|
||||||
|
point1 = seg1._point,
|
||||||
|
handle1 = seg1._handleOut,
|
||||||
|
handle2 = seg2._handleIn,
|
||||||
|
point2 = seg2._point;
|
||||||
|
edge(point1._x, point1._y);
|
||||||
|
edge(point1._x + handle1._x, point1._y + handle1._y);
|
||||||
|
edge(point2._x + handle2._x, point2._y + handle2._y);
|
||||||
|
edge(point2._x, point2._y);
|
||||||
|
}
|
||||||
|
return this._clockwise = sum > 0;
|
||||||
|
},
|
||||||
|
|
||||||
|
setClockwise: function(clockwise) {
|
||||||
|
// On-the-fly conversion to boolean:
|
||||||
|
if (this.isClockwise() != (clockwise = !!clockwise)) {
|
||||||
|
// Only revers the path if its clockwise orientation is not the same
|
||||||
|
// as what it is now demanded to be.
|
||||||
|
this.reverse();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverses the segments of the path.
|
* Reverses the segments of the path.
|
||||||
*/
|
*/
|
||||||
reverse: function() {
|
reverse: function() {
|
||||||
var segments = this._segments;
|
this._segments.reverse();
|
||||||
segments.reverse();
|
|
||||||
// Reverse the handles:
|
// Reverse the handles:
|
||||||
for (var i = 0, l = segments.length; i < l; i++) {
|
for (var i = 0, l = this._segments.length; i < l; i++) {
|
||||||
var segment = segments[i];
|
var segment = this._segments[i];
|
||||||
var handleIn = segment._handleIn;
|
var handleIn = segment._handleIn;
|
||||||
segment._handleIn = segment._handleOut;
|
segment._handleIn = segment._handleOut;
|
||||||
segment._handleOut = handleIn;
|
segment._handleOut = handleIn;
|
||||||
}
|
}
|
||||||
|
// Flip clockwise state if it's defined
|
||||||
|
if (this._clockwise !== undefined)
|
||||||
|
this._clockwise = !this._clockwise;
|
||||||
},
|
},
|
||||||
|
|
||||||
join: function(path) {
|
join: function(path) {
|
||||||
|
@ -356,31 +404,6 @@ var Path = this.Path = PathItem.extend({
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
getOrientation: function() {
|
|
||||||
var sum = 0;
|
|
||||||
var xPre, yPre;
|
|
||||||
function edge(x, y) {
|
|
||||||
if (xPre !== undefined) {
|
|
||||||
sum += (xPre - x) * (y + yPre);
|
|
||||||
}
|
|
||||||
xPre = x;
|
|
||||||
yPre = y;
|
|
||||||
}
|
|
||||||
for (var i = 0, l = this._segments.length; i < l; i++) {
|
|
||||||
var seg1 = this._segments[i];
|
|
||||||
var seg2 = this._segments[i + 1 < l ? i + 1 : 0];
|
|
||||||
var point1 = seg1._point;
|
|
||||||
var handle1 = seg1._handleOut;
|
|
||||||
var handle2 = seg2._handleIn;
|
|
||||||
var point2 = seg2._point;
|
|
||||||
edge(point1._x, point1._y);
|
|
||||||
edge(point1._x + handle1._x, point1._y + handle1._y);
|
|
||||||
edge(point2._x + handle2._x, point2._y + handle2._y);
|
|
||||||
edge(point2._x, point2._y);
|
|
||||||
}
|
|
||||||
return sum;
|
|
||||||
},
|
|
||||||
|
|
||||||
getLength: function() {
|
getLength: function() {
|
||||||
if (this._length == null) {
|
if (this._length == null) {
|
||||||
var curves = this.getCurves();
|
var curves = this.getCurves();
|
||||||
|
|
|
@ -25,9 +25,8 @@ var ToolHandler = this.ToolHandler = Base.extend({
|
||||||
this._firstMove = true;
|
this._firstMove = true;
|
||||||
this._count = 0;
|
this._count = 0;
|
||||||
this._downCount = 0;
|
this._downCount = 0;
|
||||||
for (var i in handlers) {
|
for (var i in handlers)
|
||||||
this[i] = handlers[i];
|
this[i] = handlers[i];
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,10 +58,8 @@ var ToolHandler = this.ToolHandler = Base.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
getFixedDistance: function() {
|
getFixedDistance: function() {
|
||||||
if (this._minDistance == this._maxDistance) {
|
return this._minDistance == this._maxDistance
|
||||||
return this._minDistance;
|
? this._minDistance : null;
|
||||||
}
|
|
||||||
return null;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
setFixedDistance: function(distance) {
|
setFixedDistance: function(distance) {
|
||||||
|
@ -77,9 +74,8 @@ var ToolHandler = this.ToolHandler = Base.extend({
|
||||||
var minDist = minDistance != null ? minDistance : 0;
|
var minDist = minDistance != null ? minDistance : 0;
|
||||||
var vector = pt.subtract(this._point);
|
var vector = pt.subtract(this._point);
|
||||||
var distance = vector.getLength();
|
var distance = vector.getLength();
|
||||||
if (distance < minDist) {
|
if (distance < minDist)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
// Produce a new point on the way to pt if pt is further away
|
// Produce a new point on the way to pt if pt is further away
|
||||||
// than maxDistance
|
// than maxDistance
|
||||||
var maxDist = maxDistance != null ? maxDistance : 0;
|
var maxDist = maxDistance != null ? maxDistance : 0;
|
||||||
|
@ -91,9 +87,8 @@ var ToolHandler = this.ToolHandler = Base.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (needsChange && pt.equals(this._point)) {
|
if (needsChange && pt.equals(this._point))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this._lastPoint = this._point;
|
this._lastPoint = this._point;
|
||||||
this._point = pt;
|
this._point = pt;
|
||||||
|
@ -118,9 +113,8 @@ var ToolHandler = this.ToolHandler = Base.extend({
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'mousedown':
|
case 'mousedown':
|
||||||
this.updateEvent(type, pt, null, null, true, false, false);
|
this.updateEvent(type, pt, null, null, true, false, false);
|
||||||
if (this.onMouseDown) {
|
if (this.onMouseDown)
|
||||||
this.onMouseDown(new ToolEvent(this, type, event));
|
this.onMouseDown(new ToolEvent(this, type, event));
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'mousedrag':
|
case 'mousedrag':
|
||||||
// In order for idleInterval drag events to work, we need to not
|
// In order for idleInterval drag events to work, we need to not
|
||||||
|
@ -135,9 +129,8 @@ var ToolHandler = this.ToolHandler = Base.extend({
|
||||||
matchMaxDistance = false;
|
matchMaxDistance = false;
|
||||||
while (this.updateEvent(type, pt, this.minDistance,
|
while (this.updateEvent(type, pt, this.minDistance,
|
||||||
this.maxDistance, false, needsChange, matchMaxDistance)) {
|
this.maxDistance, false, needsChange, matchMaxDistance)) {
|
||||||
if (this.onMouseDrag) {
|
if (this.onMouseDrag)
|
||||||
this.onMouseDrag(new ToolEvent(this, type, event));
|
this.onMouseDrag(new ToolEvent(this, type, event));
|
||||||
}
|
|
||||||
needsChange = true;
|
needsChange = true;
|
||||||
matchMaxDistance = true;
|
matchMaxDistance = true;
|
||||||
}
|
}
|
||||||
|
@ -148,15 +141,13 @@ var ToolHandler = this.ToolHandler = Base.extend({
|
||||||
if ((this._point.x != pt.x || this._point.y != pt.y)
|
if ((this._point.x != pt.x || this._point.y != pt.y)
|
||||||
&& this.updateEvent('mousedrag', pt, this.minDistance,
|
&& this.updateEvent('mousedrag', pt, this.minDistance,
|
||||||
this.maxDistance, false, false, false)) {
|
this.maxDistance, false, false, false)) {
|
||||||
if (this.onMouseDrag) {
|
if (this.onMouseDrag)
|
||||||
this.onMouseDrag(new ToolEvent(this, type, event));
|
this.onMouseDrag(new ToolEvent(this, type, event));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this.updateEvent(type, pt, null, this.maxDistance, false,
|
this.updateEvent(type, pt, null, this.maxDistance, false,
|
||||||
false, false);
|
false, false);
|
||||||
if (this.onMouseUp) {
|
if (this.onMouseUp)
|
||||||
this.onMouseUp(new ToolEvent(this, type, event));
|
this.onMouseUp(new ToolEvent(this, type, event));
|
||||||
}
|
|
||||||
// Start with new values for 'mousemove'
|
// Start with new values for 'mousemove'
|
||||||
this.updateEvent(type, pt, null, null, true, false, false);
|
this.updateEvent(type, pt, null, null, true, false, false);
|
||||||
this._firstMove = true;
|
this._firstMove = true;
|
||||||
|
@ -164,9 +155,8 @@ var ToolHandler = this.ToolHandler = Base.extend({
|
||||||
case 'mousemove':
|
case 'mousemove':
|
||||||
while (this.updateEvent(type, pt, this.minDistance,
|
while (this.updateEvent(type, pt, this.minDistance,
|
||||||
this.maxDistance, this._firstMove, true, false)) {
|
this.maxDistance, this._firstMove, true, false)) {
|
||||||
if (this.onMouseMove) {
|
if (this.onMouseMove)
|
||||||
this.onMouseMove(new ToolEvent(this, type, event));
|
this.onMouseMove(new ToolEvent(this, type, event));
|
||||||
}
|
|
||||||
this._firstMove = false;
|
this._firstMove = false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue