2011-03-06 19:50:44 -05:00
|
|
|
/*
|
|
|
|
* Paper.js
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-03-06 19:50:44 -05:00
|
|
|
* This file is part of Paper.js, a JavaScript Vector Graphics Library,
|
|
|
|
* based on Scriptographer.org and designed to be largely API compatible.
|
2011-03-07 20:41:50 -05:00
|
|
|
* http://paperjs.org/
|
2011-03-06 19:50:44 -05:00
|
|
|
* http://scriptographer.org/
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-03-06 19:50:44 -05:00
|
|
|
* Copyright (c) 2011, Juerg Lehni & Jonathan Puckey
|
|
|
|
* http://lehni.org/ & http://jonathanpuckey.com/
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-07-01 06:17:45 -04:00
|
|
|
* Distributed under the MIT license. See LICENSE file for details.
|
|
|
|
*
|
2011-03-07 20:41:50 -05:00
|
|
|
* All rights reserved.
|
2011-03-06 19:50:44 -05:00
|
|
|
*/
|
|
|
|
|
2011-06-22 18:56:05 -04:00
|
|
|
/**
|
|
|
|
* @name Segment
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-27 09:07:08 -04:00
|
|
|
* @class The Segment object represents the points of a path through which its
|
|
|
|
* {@link Curve} objects pass. The segments of a path can be accessed through
|
|
|
|
* its {@link Path#segments} array.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-27 09:07:08 -04:00
|
|
|
* Each segment consists of an anchor point ({@link Segment#point}) and
|
|
|
|
* optionaly an incoming and an outgoing handle ({@link Segment#handleIn} and
|
|
|
|
* {@link Segment#handleOut}), describing the tangents of the two {@link Curve}
|
|
|
|
* objects that are connected by this segment.
|
2011-06-22 18:56:05 -04:00
|
|
|
*/
|
|
|
|
var Segment = this.Segment = Base.extend(/** @lends Segment# */{
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* Creates a new Segment object.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-30 13:42:17 -04:00
|
|
|
* @param {Point} [point={x: 0, y: 0}] the anchor point of the segment
|
|
|
|
* @param {Point} [handleIn={x: 0, y: 0}] the handle point relative to the
|
|
|
|
* anchor point of the segment that describes the in tangent of the
|
|
|
|
* segment.
|
|
|
|
* @param {Point} [handleOut={x: 0, y: 0}] the handle point relative to the
|
|
|
|
* anchor point of the segment that describes the out tangent of the
|
|
|
|
* segment.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-05 16:44:32 -04:00
|
|
|
* @example {@paperscript}
|
|
|
|
* var handleIn = new Point(-80, -100);
|
|
|
|
* var handleOut = new Point(80, 100);
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* var firstPoint = new Point(100, 50);
|
|
|
|
* var firstSegment = new Segment(firstPoint, null, handleOut);
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-05 16:44:32 -04:00
|
|
|
* var secondPoint = new Point(300, 50);
|
2011-05-22 18:42:22 -04:00
|
|
|
* var secondSegment = new Segment(secondPoint, handleIn, null);
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-06-05 16:44:32 -04:00
|
|
|
* var path = new Path(firstSegment, secondSegment);
|
2011-05-30 13:42:17 -04:00
|
|
|
* path.strokeColor = 'black';
|
2011-05-22 18:42:22 -04:00
|
|
|
*/
|
2011-03-06 07:24:03 -05:00
|
|
|
initialize: function(arg0, arg1, arg2, arg3, arg4, arg5) {
|
2011-05-26 06:08:07 -04:00
|
|
|
var count = arguments.length,
|
|
|
|
createPoint = SegmentPoint.create,
|
2011-05-26 05:58:16 -04:00
|
|
|
point, handleIn, handleOut;
|
2011-05-26 06:08:07 -04:00
|
|
|
if (count == 0) {
|
2011-05-26 05:58:16 -04:00
|
|
|
// Nothing
|
2011-05-26 06:08:07 -04:00
|
|
|
} else if (count == 1) {
|
2011-05-26 05:58:16 -04:00
|
|
|
// TODO: If beans are not activated, this won't copy from existing
|
|
|
|
// segments. OK?
|
2011-03-06 07:24:03 -05:00
|
|
|
if (arg0.point) {
|
2011-05-26 05:58:16 -04:00
|
|
|
point = arg0.point;
|
|
|
|
handleIn = arg0.handleIn;
|
|
|
|
handleOut = arg0.handleOut;
|
2011-02-07 13:28:09 -05:00
|
|
|
} else {
|
2011-05-26 05:58:16 -04:00
|
|
|
point = arg0;
|
2011-02-07 13:28:09 -05:00
|
|
|
}
|
2011-05-26 06:08:07 -04:00
|
|
|
} else if (count < 6) {
|
2011-06-05 13:41:58 -04:00
|
|
|
if (count == 2 && arg1.x === undefined) {
|
2011-05-26 05:58:16 -04:00
|
|
|
point = [ arg0, arg1 ];
|
2011-02-07 13:28:09 -05:00
|
|
|
} else {
|
2011-05-26 05:58:16 -04:00
|
|
|
point = arg0;
|
|
|
|
// Doesn't matter if these arguments exist, SegmentPointcreate
|
|
|
|
// produces creates points with (0, 0) otherwise
|
|
|
|
handleIn = arg1;
|
|
|
|
handleOut = arg2;
|
2011-02-07 13:28:09 -05:00
|
|
|
}
|
2011-05-26 06:08:07 -04:00
|
|
|
} else if (count == 6) {
|
2011-05-26 05:58:16 -04:00
|
|
|
point = [ arg0, arg1 ];
|
|
|
|
handleIn = [ arg2, arg3 ];
|
|
|
|
handleOut = [ arg4, arg5 ];
|
2011-02-13 10:09:24 -05:00
|
|
|
}
|
2011-05-26 05:58:16 -04:00
|
|
|
createPoint(this, '_point', point);
|
|
|
|
createPoint(this, '_handleIn', handleIn);
|
|
|
|
createPoint(this, '_handleOut', handleOut);
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-05-01 19:17:21 -04:00
|
|
|
_changed: function(point) {
|
2011-05-26 06:04:57 -04:00
|
|
|
if (!this._path)
|
|
|
|
return;
|
|
|
|
// Delegate changes to affected curves if they exist
|
|
|
|
var curve = this._path._curves && this.getCurve(), other;
|
|
|
|
if (curve) {
|
|
|
|
curve._changed();
|
|
|
|
// Get the other affected curve, which is the previous one for
|
|
|
|
// _point or _handleIn changing when this segment is _segment1 of
|
|
|
|
// the curve, for all other cases it's the next (e.g. _handleOut
|
|
|
|
// when this segment is _segment2)
|
|
|
|
if (other = (curve[point == this._point
|
|
|
|
|| point == this._handleIn && curve._segment1 == this
|
|
|
|
? 'getPrevious' : 'getNext']())) {
|
|
|
|
other._changed();
|
2011-05-01 19:17:21 -04:00
|
|
|
}
|
|
|
|
}
|
2011-06-19 17:20:28 -04:00
|
|
|
this._path._changed(Change.GEOMETRY);
|
2011-05-01 19:17:21 -04:00
|
|
|
},
|
|
|
|
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* The anchor point of the segment.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* @type Point
|
|
|
|
* @bean
|
|
|
|
*/
|
2011-02-07 13:28:09 -05:00
|
|
|
getPoint: function() {
|
2011-03-06 05:57:14 -05:00
|
|
|
return this._point;
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-03-13 13:31:00 -04:00
|
|
|
setPoint: function(point) {
|
|
|
|
point = Point.read(arguments);
|
2011-03-06 07:24:03 -05:00
|
|
|
// Do not replace the internal object but update it instead, so
|
|
|
|
// references to it are kept alive.
|
|
|
|
this._point.set(point.x, point.y);
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* The handle point relative to the anchor point of the segment that
|
|
|
|
* describes the in tangent of the segment.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* @type Point
|
|
|
|
* @bean
|
|
|
|
*/
|
2011-02-07 13:28:09 -05:00
|
|
|
getHandleIn: function() {
|
2011-03-06 05:57:14 -05:00
|
|
|
return this._handleIn;
|
|
|
|
},
|
|
|
|
|
2011-03-13 13:31:00 -04:00
|
|
|
setHandleIn: function(point) {
|
|
|
|
point = Point.read(arguments);
|
2011-03-06 07:24:03 -05:00
|
|
|
// See #setPoint:
|
|
|
|
this._handleIn.set(point.x, point.y);
|
2011-03-06 05:57:14 -05:00
|
|
|
// Update corner accordingly
|
2011-05-01 18:29:15 -04:00
|
|
|
// this.corner = !this._handleIn.isColinear(this._handleOut);
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
|
|
|
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* The handle point relative to the anchor point of the segment that
|
|
|
|
* describes the out tangent of the segment.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* @type Point
|
|
|
|
* @bean
|
|
|
|
*/
|
2011-03-06 06:18:35 -05:00
|
|
|
getHandleOut: function() {
|
|
|
|
return this._handleOut;
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-03-13 13:31:00 -04:00
|
|
|
setHandleOut: function(point) {
|
|
|
|
point = Point.read(arguments);
|
2011-03-06 07:24:03 -05:00
|
|
|
// See #setPoint:
|
|
|
|
this._handleOut.set(point.x, point.y);
|
2011-03-06 05:57:14 -05:00
|
|
|
// Update corner accordingly
|
2011-05-01 18:29:15 -04:00
|
|
|
// this.corner = !this._handleIn.isColinear(this._handleOut);
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-05-30 13:42:17 -04:00
|
|
|
_isSelected: function(point) {
|
|
|
|
var state = this._selectionState;
|
|
|
|
return point == this._point ? !!(state & SelectionState.POINT)
|
|
|
|
: point == this._handleIn ? !!(state & SelectionState.HANDLE_IN)
|
|
|
|
: point == this._handleOut ? !!(state & SelectionState.HANDLE_OUT)
|
|
|
|
: false;
|
|
|
|
},
|
|
|
|
|
|
|
|
_setSelected: function(point, selected) {
|
|
|
|
var path = this._path,
|
|
|
|
selected = !!selected, // convert to boolean
|
2011-06-17 14:00:41 -04:00
|
|
|
state = this._selectionState || 0,
|
2011-05-30 13:42:17 -04:00
|
|
|
// For performance reasons use array indices to access the various
|
|
|
|
// selection states: 0 = point, 1 = handleIn, 2 = handleOut
|
|
|
|
selection = [
|
|
|
|
!!(state & SelectionState.POINT),
|
|
|
|
!!(state & SelectionState.HANDLE_IN),
|
|
|
|
!!(state & SelectionState.HANDLE_OUT)
|
|
|
|
];
|
|
|
|
if (point == this._point) {
|
|
|
|
if (selected) {
|
|
|
|
// We're selecting point, deselect the handles
|
|
|
|
selection[1] = selection[2] = false;
|
|
|
|
} else {
|
|
|
|
var previous = this.getPrevious(),
|
|
|
|
next = this.getNext();
|
|
|
|
// When deselecting a point, the handles get selected instead
|
|
|
|
// depending on the selection state of their neighbors.
|
|
|
|
selection[1] = previous && (previous._point.isSelected()
|
|
|
|
|| previous._handleOut.isSelected());
|
|
|
|
selection[2] = next && (next._point.isSelected()
|
|
|
|
|| next._handleIn.isSelected());
|
|
|
|
}
|
|
|
|
selection[0] = selected;
|
|
|
|
} else {
|
|
|
|
var index = point == this._handleIn ? 1 : 2;
|
|
|
|
if (selection[index] != selected) {
|
|
|
|
// When selecting handles, the point get deselected.
|
|
|
|
if (selected)
|
|
|
|
selection[0] = false;
|
|
|
|
selection[index] = selected;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this._selectionState = (selection[0] ? SelectionState.POINT : 0)
|
|
|
|
| (selection[1] ? SelectionState.HANDLE_IN : 0)
|
|
|
|
| (selection[2] ? SelectionState.HANDLE_OUT : 0);
|
|
|
|
// If the selection state of the segment has changed, we need to let
|
|
|
|
// it's path know and possibly add or remove it from
|
|
|
|
// project._selectedItems
|
2012-10-09 02:12:43 -04:00
|
|
|
if (path && state != this._selectionState) {
|
2011-06-14 10:37:25 -04:00
|
|
|
path._updateSelection(this, state, this._selectionState);
|
2012-10-09 02:12:43 -04:00
|
|
|
// Let path know that we changed something and the view should be
|
|
|
|
// redrawn
|
|
|
|
path._changed(Change.ATTRIBUTE);
|
|
|
|
}
|
2011-05-30 13:42:17 -04:00
|
|
|
},
|
|
|
|
|
2011-06-30 06:01:51 -04:00
|
|
|
|
2011-06-14 10:37:25 -04:00
|
|
|
|
2011-05-30 13:42:17 -04:00
|
|
|
/**
|
|
|
|
* Specifies whether the {@link #point} of the segment is selected.
|
|
|
|
* @type Boolean
|
|
|
|
* @bean
|
|
|
|
*/
|
|
|
|
isSelected: function() {
|
|
|
|
return this._isSelected(this._point);
|
|
|
|
},
|
|
|
|
|
|
|
|
setSelected: function(selected) {
|
|
|
|
this._setSelected(this._point, selected);
|
|
|
|
},
|
|
|
|
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* {@grouptitle Hierarchy}
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* The index of the segment in the {@link Path#segments} array that the
|
|
|
|
* segment belongs to.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-27 14:15:15 -04:00
|
|
|
* @type Number
|
2011-05-22 18:42:22 -04:00
|
|
|
* @bean
|
|
|
|
*/
|
2011-05-01 08:27:53 -04:00
|
|
|
getIndex: function() {
|
2011-05-07 11:10:38 -04:00
|
|
|
return this._index !== undefined ? this._index : null;
|
2011-05-01 08:27:53 -04:00
|
|
|
},
|
|
|
|
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* The path that the segment belongs to.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* @type Path
|
|
|
|
* @bean
|
|
|
|
*/
|
|
|
|
getPath: function() {
|
|
|
|
return this._path || null;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The curve that the segment belongs to.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* @type Curve
|
|
|
|
* @bean
|
|
|
|
*/
|
2011-03-06 08:11:04 -05:00
|
|
|
getCurve: function() {
|
2011-05-01 19:17:21 -04:00
|
|
|
if (this._path) {
|
2011-05-01 08:27:53 -04:00
|
|
|
var index = this._index;
|
2011-03-06 08:11:04 -05:00
|
|
|
// The last segment of an open path belongs to the last curve
|
2011-04-30 18:22:29 -04:00
|
|
|
if (!this._path._closed && index == this._path._segments.length - 1)
|
2011-03-06 08:11:04 -05:00
|
|
|
index--;
|
2011-04-27 16:13:32 -04:00
|
|
|
return this._path.getCurves()[index] || null;
|
2011-03-06 08:11:04 -05:00
|
|
|
}
|
|
|
|
return null;
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* {@grouptitle Sibling Segments}
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* The next segment in the {@link Path#segments} array that the segment
|
2011-05-27 07:28:13 -04:00
|
|
|
* belongs to. If the segments belongs to a closed path, the first segment
|
|
|
|
* is returned for the last segment of the path.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* @type Segment
|
|
|
|
* @bean
|
|
|
|
*/
|
2011-02-07 13:28:09 -05:00
|
|
|
getNext: function() {
|
2011-04-27 07:21:31 -04:00
|
|
|
var segments = this._path && this._path._segments;
|
2011-05-01 08:27:53 -04:00
|
|
|
return segments && (segments[this._index + 1]
|
2011-04-30 18:22:29 -04:00
|
|
|
|| this._path._closed && segments[0]) || null;
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* The previous segment in the {@link Path#segments} array that the
|
2011-05-27 07:28:13 -04:00
|
|
|
* segment belongs to. If the segments belongs to a closed path, the last
|
|
|
|
* segment is returned for the first segment of the path.
|
2011-06-30 06:01:51 -04:00
|
|
|
*
|
2011-05-22 18:42:22 -04:00
|
|
|
* @type Segment
|
|
|
|
* @bean
|
|
|
|
*/
|
2011-02-07 13:28:09 -05:00
|
|
|
getPrevious: function() {
|
2011-04-27 07:21:31 -04:00
|
|
|
var segments = this._path && this._path._segments;
|
2011-05-01 08:27:53 -04:00
|
|
|
return segments && (segments[this._index - 1]
|
2011-04-30 18:22:29 -04:00
|
|
|
|| this._path._closed && segments[segments.length - 1]) || null;
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* Returns the reversed the segment, without modifying the segment itself.
|
|
|
|
* @return {Segment} the reversed segment
|
|
|
|
*/
|
2011-02-07 13:28:09 -05:00
|
|
|
reverse: function() {
|
2011-03-06 05:57:14 -05:00
|
|
|
return new Segment(this._point, this._handleOut, this._handleIn);
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-05-22 18:42:22 -04:00
|
|
|
/**
|
|
|
|
* Removes the segment from the path that it belongs to.
|
|
|
|
*/
|
2011-02-07 13:28:09 -05:00
|
|
|
remove: function() {
|
2011-05-01 08:27:53 -04:00
|
|
|
return this._path ? !!this._path.removeSegment(this._index) : false;
|
2011-02-07 13:28:09 -05:00
|
|
|
},
|
2011-03-03 17:45:17 -05:00
|
|
|
|
2011-12-07 05:54:41 -05:00
|
|
|
clone: function() {
|
|
|
|
return new Segment(this._point, this._handleIn, this._handleOut);
|
|
|
|
},
|
|
|
|
|
2011-12-07 05:53:07 -05:00
|
|
|
equals: function(segment) {
|
|
|
|
return segment == this || segment
|
|
|
|
&& this._point.equals(segment._point)
|
|
|
|
&& this._handleIn.equals(segment._handleIn)
|
|
|
|
&& this._handleOut.equals(segment._handleOut);
|
|
|
|
},
|
|
|
|
|
2011-05-29 10:57:48 -04:00
|
|
|
/**
|
|
|
|
* @return {String} A string representation of the segment.
|
|
|
|
*/
|
2011-02-07 13:28:09 -05:00
|
|
|
toString: function() {
|
2011-05-02 03:57:55 -04:00
|
|
|
var parts = [ 'point: ' + this._point ];
|
|
|
|
if (!this._handleIn.isZero())
|
|
|
|
parts.push('handleIn: ' + this._handleIn);
|
|
|
|
if (!this._handleOut.isZero())
|
|
|
|
parts.push('handleOut: ' + this._handleOut);
|
|
|
|
return '{ ' + parts.join(', ') + ' }';
|
2011-03-06 16:26:38 -05:00
|
|
|
},
|
|
|
|
|
|
|
|
_transformCoordinates: function(matrix, coords, change) {
|
|
|
|
// Use matrix.transform version() that takes arrays of multiple
|
|
|
|
// points for largely improved performance, as no calls to
|
|
|
|
// Point.read() and Point constructors are necessary.
|
|
|
|
var point = this._point,
|
2011-07-02 00:24:27 -04:00
|
|
|
// If change is true, only transform handles if they are set, as
|
|
|
|
// _transformCoordinates is called only to change the segment, no
|
|
|
|
// to receive the coords.
|
|
|
|
// This saves some computation time. If change is false, always
|
2011-06-30 06:01:51 -04:00
|
|
|
// use the real handles, as we just want to receive a filled
|
2011-03-06 19:36:44 -05:00
|
|
|
// coords array for getBounds().
|
2011-07-02 00:24:27 -04:00
|
|
|
handleIn = !change || !this._handleIn.isZero()
|
2011-07-01 06:30:10 -04:00
|
|
|
? this._handleIn : null,
|
2011-07-02 00:24:27 -04:00
|
|
|
handleOut = !change || !this._handleOut.isZero()
|
2011-07-01 06:30:10 -04:00
|
|
|
? this._handleOut : null,
|
2011-04-21 08:33:12 -04:00
|
|
|
x = point._x,
|
2011-05-02 03:59:51 -04:00
|
|
|
y = point._y,
|
|
|
|
i = 2;
|
2011-03-06 16:26:38 -05:00
|
|
|
coords[0] = x;
|
|
|
|
coords[1] = y;
|
|
|
|
// We need to convert handles to absolute coordinates in order
|
|
|
|
// to transform them.
|
|
|
|
if (handleIn) {
|
2011-05-02 03:59:51 -04:00
|
|
|
coords[i++] = handleIn._x + x;
|
|
|
|
coords[i++] = handleIn._y + y;
|
2011-03-06 16:26:38 -05:00
|
|
|
}
|
|
|
|
if (handleOut) {
|
2011-05-02 03:59:51 -04:00
|
|
|
coords[i++] = handleOut._x + x;
|
|
|
|
coords[i++] = handleOut._y + y;
|
2011-03-06 16:26:38 -05:00
|
|
|
}
|
2011-07-02 00:24:27 -04:00
|
|
|
// If no matrix was previded, this was just called to get the coords and
|
|
|
|
// we are done now.
|
|
|
|
if (!matrix)
|
|
|
|
return;
|
|
|
|
matrix._transformCoordinates(coords, 0, coords, 0, i / 2);
|
|
|
|
x = coords[0];
|
|
|
|
y = coords[1];
|
|
|
|
if (change) {
|
|
|
|
// If change is true, we need to set the new values back
|
|
|
|
point._x = x;
|
|
|
|
point._y = y;
|
|
|
|
i = 2;
|
|
|
|
if (handleIn) {
|
|
|
|
handleIn._x = coords[i++] - x;
|
|
|
|
handleIn._y = coords[i++] - y;
|
|
|
|
}
|
|
|
|
if (handleOut) {
|
|
|
|
handleOut._x = coords[i++] - x;
|
|
|
|
handleOut._y = coords[i++] - y;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// We want to receive the results in coords, so make sure
|
|
|
|
// handleIn and out are defined too, even if they're 0
|
|
|
|
if (!handleIn) {
|
|
|
|
coords[i++] = x;
|
|
|
|
coords[i++] = y;
|
|
|
|
}
|
|
|
|
if (!handleOut) {
|
|
|
|
coords[i++] = x;
|
|
|
|
coords[i++] = y;
|
2011-03-06 16:26:38 -05:00
|
|
|
}
|
|
|
|
}
|
2011-02-07 13:28:09 -05:00
|
|
|
}
|
2011-02-13 11:26:24 -05:00
|
|
|
});
|