Implement local caching for the calculation of concatenated global matrices in the drawing of selected items in Project#draw().

This commit is contained in:
Jürg Lehni 2011-12-20 23:09:49 +01:00
parent 16113d5462
commit a8392fbf68
2 changed files with 35 additions and 17 deletions

View file

@ -539,18 +539,6 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
// Use Matrix#initialize to easily copy over values.
this._matrix.initialize(matrix);
this._changed(Change.GEOMETRY);
},
getGlobalMatrix: function() {
// TODO: Implement caching?
var matrix = new Matrix(),
item = this;
while (item) {
if (!item._matrix.isIdentity())
matrix.preConcatenate(item._matrix);
item = item._parent;
}
return matrix;
}
}, Base.each(['bounds', 'strokeBounds', 'handleBounds', 'roughBounds'],
function(name) {

View file

@ -272,12 +272,42 @@ var Project = this.Project = PaperScopeItem.extend(/** @lends Project# */{
ctx.strokeWidth = 1;
// TODO: use Layer#color
ctx.strokeStyle = ctx.fillStyle = '#009dec';
// Create a local lookup table for hierarchically concatenated
// matrices by item id, to speed up drawing by eliminating repeated
// concatenation of parent's matrices through caching.
var matrices = {};
// Descriptionf of the paramters to getGlobalMatrix():
// matrix is the container for the final concatenated matrix, passed
// to getGlobalMatrix() on the initial call.
// cached defines wether the result of the concatenation should be
// cached, only used for parents of items that this is called for.
function getGlobalMatrix(item, matrix, cached) {
var cache = cached && matrices[item._id];
if (cache) {
// Found a cached version, copy over the values and return
matrix.initialize(cache);
return matrix;
}
if (item._parent) {
// Get concatenated matrix from all the parents, using
// local caching (passing true for cached):
getGlobalMatrix(item._parent, matrix, true);
// No need to concatenate if it's the identity matrix
if (!item._matrix.isIdentity())
matrix.concatenate(item._matrix);
} else {
// Simply copy over the item's matrix, since it's the root
matrix.initialize(item._matrix);
}
// If the result needs to be cached, create a copy since matrix
// might be further modified through recursive calls
if (cached)
matrices[item._id] = matrix.clone();
return matrix;
}
for (var id in this._selectedItems) {
var item = this._selectedItems[id],
mx = item.getGlobalMatrix();
if (matrix)
mx.preConcatenate(matrix);
item.drawSelected(ctx, mx);
var item = this._selectedItems[id];
item.drawSelected(ctx, getGlobalMatrix(item, new Matrix()));
}
ctx.restore();
}