mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-20 22:39:50 -05:00
Add beginning of value caching (_length, _bounds) and change tracking to invalidate cached values.
This commit is contained in:
parent
4bac4b89f6
commit
0a4150a5c9
4 changed files with 77 additions and 23 deletions
|
@ -35,6 +35,11 @@ var Curve = this.Curve = Base.extend({
|
|||
}
|
||||
},
|
||||
|
||||
_changed: function() {
|
||||
// Clear cached values.
|
||||
delete this._length;
|
||||
},
|
||||
|
||||
_updateSegments: function() {
|
||||
if (this._path) {
|
||||
this._index2 = this._index1 + 1;
|
||||
|
@ -153,11 +158,19 @@ var Curve = this.Curve = Base.extend({
|
|||
},
|
||||
|
||||
getLength: function(/* from, to */) {
|
||||
var from = arguments[0],
|
||||
to = arguments[1];
|
||||
fullLength = arguments.length == 0 || from == 0 && to == 1;
|
||||
if (fullLength && this._length != null)
|
||||
return this._length;
|
||||
// Hide parameters from Bootstrap so it injects bean too
|
||||
var args = this.getCurveValues();
|
||||
if (arguments.length > 0)
|
||||
args.push(arguments[0], arguments[1]);
|
||||
return Curve.getLength.apply(Curve, args);
|
||||
if (!fullLength)
|
||||
args.push(from, to);
|
||||
var length = Curve.getLength.apply(Curve, args);
|
||||
if (fullLength)
|
||||
this._length = length;
|
||||
return length;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -28,6 +28,13 @@ var Path = this.Path = PathItem.extend({
|
|||
|| typeof segments[0] !== 'object' ? arguments : segments);
|
||||
},
|
||||
|
||||
_changed: function() {
|
||||
// Clear cached values.
|
||||
delete this._length;
|
||||
delete this._bounds;
|
||||
delete this._strokeBounds;
|
||||
},
|
||||
|
||||
/**
|
||||
* The segments contained within the path.
|
||||
*/
|
||||
|
@ -102,6 +109,7 @@ var Path = this.Path = PathItem.extend({
|
|||
if (closed)
|
||||
this._curves[i = length - 1] = Curve.create(this, i);
|
||||
}
|
||||
this._changed();
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -116,6 +124,7 @@ var Path = this.Path = PathItem.extend({
|
|||
this._segments[i]._transformCoordinates(matrix, coords, true);
|
||||
}
|
||||
}
|
||||
this._changed();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -163,6 +172,7 @@ var Path = this.Path = PathItem.extend({
|
|||
if (this._closed)
|
||||
this._curves[l - 1]._updateSegments();
|
||||
}
|
||||
this._changed();
|
||||
return segment;
|
||||
},
|
||||
|
||||
|
@ -199,6 +209,7 @@ var Path = this.Path = PathItem.extend({
|
|||
segment._selectionState = 0;
|
||||
}
|
||||
}
|
||||
this._changed();
|
||||
return segments;
|
||||
}
|
||||
return null;
|
||||
|
@ -245,6 +256,7 @@ var Path = this.Path = PathItem.extend({
|
|||
segment._handleIn = segment._handleOut;
|
||||
segment._handleOut = handleIn;
|
||||
}
|
||||
this._changed();
|
||||
},
|
||||
|
||||
join: function(path) {
|
||||
|
@ -282,17 +294,20 @@ var Path = this.Path = PathItem.extend({
|
|||
last1.remove();
|
||||
this.setClosed(true);
|
||||
}
|
||||
this._changed();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
getLength: function() {
|
||||
var curves = this.getCurves();
|
||||
var length = 0;
|
||||
for (var i = 0, l = curves.length; i < l; i++)
|
||||
length += curves[i].getLength();
|
||||
return length;
|
||||
if (this._length == null) {
|
||||
var curves = this.getCurves();
|
||||
this._length = 0;
|
||||
for (var i = 0, l = curves.length; i < l; i++)
|
||||
this._length += curves[i].getLength();
|
||||
}
|
||||
return this._length;
|
||||
},
|
||||
|
||||
_getOffset: function(location) {
|
||||
|
@ -977,9 +992,12 @@ var Path = this.Path = PathItem.extend({
|
|||
getBounds: function(/* matrix */) {
|
||||
// Pass the matrix hidden from Bootstrap, so it still inject
|
||||
// getBounds as bean too.
|
||||
var bounds = getBounds(this, arguments[0]);
|
||||
return LinkedRectangle.create(this, 'setBounds',
|
||||
bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
if (!this._bounds) {
|
||||
var bounds = getBounds(this, arguments[0]);
|
||||
this._bounds = LinkedRectangle.create(this, 'setBounds',
|
||||
bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
}
|
||||
return this._bounds;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,6 +51,28 @@ var Segment = this.Segment = Base.extend({
|
|||
this._handleOut = SegmentPoint.create(this, 0, 0);
|
||||
},
|
||||
|
||||
_changed: function(point) {
|
||||
if (this._path) {
|
||||
// Delegate changes to affected curves if they exist
|
||||
if (this._path._curves) {
|
||||
var curve = 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 or this segment == _segment2)
|
||||
if (other = (curve[point == this._point
|
||||
|| point == this._handleIn && curve._segment1 == this
|
||||
? 'getPrevious' : 'getNext']())) {
|
||||
other._changed();
|
||||
}
|
||||
}
|
||||
}
|
||||
this._path._changed();
|
||||
}
|
||||
},
|
||||
|
||||
getPoint: function() {
|
||||
return this._point;
|
||||
},
|
||||
|
@ -105,7 +127,7 @@ var Segment = this.Segment = Base.extend({
|
|||
},
|
||||
|
||||
getCurve: function() {
|
||||
if (this._path != null) {
|
||||
if (this._path) {
|
||||
var index = this._index;
|
||||
// The last segment of an open path belongs to the last curve
|
||||
if (!this._path._closed && index == this._path._segments.length - 1)
|
||||
|
|
|
@ -8,7 +8,7 @@ var SegmentPoint = Point.extend({
|
|||
set: function(x, y) {
|
||||
this._x = x;
|
||||
this._y = y;
|
||||
// this._segment._markDirty(DirtyFlags.BOUNDS);
|
||||
this._segment._changed(this);
|
||||
return this;
|
||||
},
|
||||
|
||||
|
@ -18,7 +18,7 @@ var SegmentPoint = Point.extend({
|
|||
|
||||
setX: function(x) {
|
||||
this._x = x;
|
||||
// this._segment._markDirty(DirtyFlags.BOUNDS);
|
||||
this._segment._changed(this);
|
||||
},
|
||||
|
||||
getY: function() {
|
||||
|
@ -27,7 +27,7 @@ var SegmentPoint = Point.extend({
|
|||
|
||||
setY: function(y) {
|
||||
this._y = y;
|
||||
// this._segment._markDirty(DirtyFlags.BOUNDS);
|
||||
this._segment._changed(this);
|
||||
},
|
||||
|
||||
setSelected: function(selected) {
|
||||
|
@ -39,15 +39,16 @@ var SegmentPoint = Point.extend({
|
|||
},
|
||||
|
||||
statics: {
|
||||
create: function(segment, arg1, arg2) {
|
||||
var point;
|
||||
if (arguments.length == 2) {
|
||||
point = new SegmentPoint(arg1);
|
||||
} else {
|
||||
point = new SegmentPoint(SegmentPoint.dont);
|
||||
point._x = arg1;
|
||||
point._y = arg2;
|
||||
create: function(segment, x, y) {
|
||||
if (y === undefined) {
|
||||
// Use the normal point constructor to read in point values
|
||||
var tmp = new Point(x);
|
||||
x = tmp.x;
|
||||
y = tmp.y;
|
||||
}
|
||||
var point = new SegmentPoint(SegmentPoint.dont);
|
||||
point._x = x;
|
||||
point._y = y;
|
||||
point._segment = segment;
|
||||
return point;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue