Implement Item#getGlobalMatrix(), #globalToLocal() and #localToGlobal()

Closes #270.
This commit is contained in:
Jürg Lehni 2013-12-08 20:04:10 +01:00
parent 696b5f29b9
commit 97fcd6ff38
3 changed files with 23 additions and 16 deletions

View file

@ -27,6 +27,7 @@ var HitResult = Base.extend(/** @lends HitResult# */{
// properties. // properties.
// This allows the definition of getters too, e.g. for 'pixel'. // This allows the definition of getters too, e.g. for 'pixel'.
if (values) { if (values) {
// Make enumerable so toString() works.
values.enumerable = true; values.enumerable = true;
this.inject(values); this.inject(values);
} }

View file

@ -207,8 +207,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
var parent = this._parent, var parent = this._parent,
project = this._project, project = this._project,
symbol = this._parentSymbol; symbol = this._parentSymbol;
// Reset _drawCount on each change. // Reset _updateCount on each change.
this._drawCount = null; this._updateCount = null;
if (flags & /*#=*/ ChangeFlag.GEOMETRY) { if (flags & /*#=*/ ChangeFlag.GEOMETRY) {
// Clear cached bounds and position whenever geometry changes // Clear cached bounds and position whenever geometry changes
delete this._bounds; delete this._bounds;
@ -1068,10 +1068,16 @@ var Item = Base.extend(Callback, /** @lends Item# */{
* @bean * @bean
*/ */
getGlobalMatrix: function() { getGlobalMatrix: function() {
// TODO: if drawCount is out of sync, we still need to walk up the chain var matrix = this._updateCount === this._project._updateCount
// and concatenate the matrices.
return this._drawCount === this._project._drawCount
&& this._globalMatrix || null; && this._globalMatrix || null;
// If _updateCount is out of sync or no _globalMatrix was calculated
// when rendering, iteratively calculate it now.
if (!matrix) {
matrix = this._globalMatrix = item._matrix.clone();
if (this._parent)
matrix.concatenate(this._parent.getGlobalMatrix());
}
return matrix;
}, },
/** /**
@ -2719,7 +2725,7 @@ var Item = Base.extend(Callback, /** @lends Item# */{
*/ */
globalToLocal: function(/* point */) { globalToLocal: function(/* point */) {
var matrix = this.getGlobalMatrix(); var matrix = this.getGlobalMatrix();
return matrix && matrix._transformPoint(Point.read(arguments)); return matrix && matrix._inverseTransform(Point.read(arguments));
}, },
/** /**
@ -2731,7 +2737,7 @@ var Item = Base.extend(Callback, /** @lends Item# */{
*/ */
localToGlobal: function(/* point */) { localToGlobal: function(/* point */) {
var matrix = this.getGlobalMatrix(); var matrix = this.getGlobalMatrix();
return matrix && matrix._inverseTransform(Point.read(arguments)); return matrix && matrix._transformPoint(Point.read(arguments));
}, },
/** /**
@ -3321,10 +3327,10 @@ var Item = Base.extend(Callback, /** @lends Item# */{
draw: function(ctx, param) { draw: function(ctx, param) {
if (!this._visible || this._opacity === 0) if (!this._visible || this._opacity === 0)
return; return;
// Each time the project gets drawn, it's _drawCount is increased. // Each time the project gets drawn, it's _updateCount is increased.
// Keep the _drawCount of drawn items in sync, so we have an easy // Keep the _updateCount of drawn items in sync, so we have an easy
// way to know for which selected items we need to draw selection info. // way to know for which selected items we need to draw selection info.
this._drawCount = this._project._drawCount; this._updateCount = this._project._updateCount;
// Keep calculating the current global matrix, by keeping a history // Keep calculating the current global matrix, by keeping a history
// and pushing / popping as we go along. // and pushing / popping as we go along.
var trackTransforms = param.trackTransforms, var trackTransforms = param.trackTransforms,

View file

@ -59,8 +59,8 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
this.view = view instanceof View ? view : View.create(view); this.view = view instanceof View ? view : View.create(view);
this._selectedItems = {}; this._selectedItems = {};
this._selectedItemCount = 0; this._selectedItemCount = 0;
// See Item#draw() for an explanation of _drawCount // See Item#draw() for an explanation of _updateCount
this._drawCount = 0; this._updateCount = 0;
// Change tracking, not in use for now. Activate once required: // Change tracking, not in use for now. Activate once required:
// this._changes = []; // this._changes = [];
// this._changesById = {}; // this._changesById = {};
@ -421,9 +421,9 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
*/ */
draw: function(ctx, matrix, ratio) { draw: function(ctx, matrix, ratio) {
// Increase the drawCount before the draw-loop. After that, items that // Increase the _updateCount before the draw-loop. After that, items
// are visible will have their drawCount set to the new value. // that are visible will have their _updateCount set to the new value.
this._drawCount++; this._updateCount++;
ctx.save(); ctx.save();
matrix.applyToContext(ctx); matrix.applyToContext(ctx);
// Use new Base() so we can use param.extend() to easily override // Use new Base() so we can use param.extend() to easily override
@ -450,7 +450,7 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
ctx.strokeWidth = 1; ctx.strokeWidth = 1;
for (var id in this._selectedItems) { for (var id in this._selectedItems) {
var item = this._selectedItems[id]; var item = this._selectedItems[id];
if (item._drawCount === this._drawCount if (item._updateCount === this._updateCount
&& (item._drawSelected || item._boundsSelected)) { && (item._drawSelected || item._boundsSelected)) {
// Allow definition of selected color on a per item and per // Allow definition of selected color on a per item and per
// layer level, with a fallback to #009dec // layer level, with a fallback to #009dec