Merge pull request #1531 from sasensi/Fix_#1503_Item#position_caching_issue

Fix #1503 Item#position caching issue
This commit is contained in:
Jürg Lehni 2018-10-03 17:33:24 +02:00 committed by GitHub
commit 959ccc83c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 13 deletions

View file

@ -746,21 +746,29 @@ new function() { // Injection scope for various item event handlers
getPosition: function(_dontLink) { getPosition: function(_dontLink) {
// Cache position value. // Cache position value.
// Pass true for _dontLink in getCenter(), so receive back a normal point // Pass true for _dontLink in getCenter(), so receive back a normal point
var position = this._position, var ctor = _dontLink ? Point : LinkedPoint;
ctor = _dontLink ? Point : LinkedPoint;
// Do not cache LinkedPoints directly, since we would not be able to // Do not cache LinkedPoints directly, since we would not be able to
// use them to calculate the difference in #setPosition, as when it is // use them to calculate the difference in #setPosition, as when it is
// modified, it would hold new values already and only then cause the // modified, it would hold new values already and only then cause the
// calling of #setPosition. // calling of #setPosition.
if (!position) { if (!this._position) {
// If an pivot point is provided, use it to determine position // set position if needed
// based on the matrix. Otherwise use the center of the bounds. this._position = this._getPositionFromBounds();
var pivot = this._pivot;
position = this._position = pivot
? this._matrix._transformPoint(pivot)
: this.getBounds().getCenter(true);
} }
return new ctor(position.x, position.y, this, 'setPosition'); return new ctor(this._position.x, this._position.y, this, 'setPosition');
},
/**
* Internal method used to calculate position either from pivot point or bounds.
* @param {Rectangle} bounds if provided, these bounds are used instead of
* calling getBounds()
* @returns {Point} the transformed pivot point or the center of the bounds
* @private
*/
_getPositionFromBounds: function(bounds) {
return this._pivot
? this._matrix._transformPoint(this._pivot)
: (bounds || this.getBounds()).getCenter(true);
}, },
setPosition: function(/* point */) { setPosition: function(/* point */) {
@ -3511,10 +3519,10 @@ new function() { // Injection scope for hit-test functions shared with project
this._bounds = bounds; this._bounds = bounds;
// If we have cached bounds, try to determine _position as its // If we have cached bounds, try to determine _position as its
// center. Use _boundsOptions do get the cached default bounds. // center. Use _boundsOptions do get the cached default bounds.
var cached = bounds[this._getBoundsCacheKey( var cached = bounds[this._getBoundsCacheKey(this._boundsOptions || {})];
this._boundsOptions || {})];
if (cached) { if (cached) {
this._position = cached.rect.getCenter(true); // use this method to handle pivot case (see #1503)
this._position = this._getPositionFromBounds(cached.rect);
} }
} else if (transform && position && this._pivot) { } else if (transform && position && this._pivot) {
// If the item has a pivot defined, it means that the default // If the item has a pivot defined, it means that the default

View file

@ -929,3 +929,11 @@ test('Item#scaling, #rotation', function() {
equals(shape2.bounds, expected, equals(shape2.bounds, expected,
'shape2.bounds, setting shape2.scaling before shape2.rotation'); 'shape2.bounds, setting shape2.scaling before shape2.rotation');
}); });
test('Item#position cache issue with pivot point #1503', function() {
var item = Path.Rectangle(new Point(0, 0), new Size(20));
item.pivot = new Point(0, 0);
item.getBounds();
item.translate(5, 5);
equals(item.position, new Point(5, 5));
});