Introduce Project#_drawCount mechanism as a better and more efficient way to filter out selected items that are not currently part of the DOM.

This commit is contained in:
Jürg Lehni 2013-01-20 14:01:27 -08:00
parent e22b3292ed
commit 50ee598bca
3 changed files with 23 additions and 16 deletions

View file

@ -1206,7 +1206,7 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
*/
insertChild: function(index, item) {
if (this._children) {
item._remove(false, true);
item._remove(true);
Base.splice(this._children, [item], index, 0);
item._parent = this;
item._setProject(this._project);
@ -1353,10 +1353,8 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
/**
* Removes the item from its parent's children list.
*/
_remove: function(deselect, notify) {
_remove: function(notify) {
if (this._parent) {
if (deselect)
this.setSelected(false);
if (this._name)
this._removeFromNamed();
if (this._index != null)
@ -1377,7 +1375,7 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
* @return {Boolean} {@true the item was removed}
*/
remove: function() {
return this._remove(true, true);
return this._remove(true);
},
/**
@ -1407,7 +1405,7 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
// fine, since it only calls Base.splice() if #_index is set.
var removed = Base.splice(this._children, null, from, to - from);
for (var i = removed.length - 1; i >= 0; i--)
removed[i]._remove(true, false);
removed[i]._remove(false);
if (removed.length > 0)
this._changed(/*#=*/ Change.HIERARCHY);
return removed;
@ -2493,6 +2491,11 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
draw: function(item, ctx, param) {
if (!item._visible || item._opacity == 0)
return;
// Each time the project gets drawn, it's _drawCount is increased.
// Keep the _drawCount of drawn items in sync, so we have an easy
// way to filter out selected items that are not being drawn, e.g.
// because they are currently not part of the DOM.
item._drawCount = item._project._drawCount;
var tempCanvas, parentCtx,
itemOffset, prevOffset;
// If the item has a blendMode or is defining an opacity, draw it on

View file

@ -52,12 +52,10 @@ var Layer = this.Layer = Group.extend(/** @lends Layer# */{
* Removes the layer from its project's layers list
* or its parent's children list.
*/
_remove: function(deselect, notify) {
_remove: function(notify) {
if (this._parent)
return this.base(deselect, notify);
return this.base(notify);
if (this._index != null) {
if (deselect)
this.setSelected(false);
Base.splice(this._project.layers, null, this._index, 1);
// Tell project we need a redraw. This is similar to _changed()
// mechanism.
@ -96,7 +94,7 @@ var Layer = this.Layer = Group.extend(/** @lends Layer# */{
// If the item is a layer and contained within Project#layers, use
// our own version of move().
if (item instanceof Layer && !item._parent
&& this._remove(false, true)) {
&& this._remove(true)) {
Base.splice(item._project.layers, [this],
item._index + (above ? 1 : 0), 0);
this._setProject(item._project);

View file

@ -60,6 +60,8 @@ var Project = this.Project = PaperScopeItem.extend(/** @lends Project# */{
this._currentStyle = new PathStyle();
this._selectedItems = {};
this._selectedItemCount = 0;
// See Item.draw() for an explanation of _drawCount
this._drawCount = 0;
// Change tracking, not in use for now. Activate once required:
// this._changes = [];
// this._changesById = {};
@ -153,9 +155,11 @@ var Project = this.Project = PaperScopeItem.extend(/** @lends Project# */{
// TODO: The order of these items should be that of their
// drawing order.
var items = [];
Base.each(this._selectedItems, function(item) {
items.push(item);
});
for (var id in this._selectedItems) {
var item = this._selectedItems[id];
if (item._drawCount === this._drawCount)
items.push(item);
}
return items;
},
@ -184,7 +188,7 @@ var Project = this.Project = PaperScopeItem.extend(/** @lends Project# */{
*/
deselectAll: function() {
for (var i in this._selectedItems)
this._selectedItems[i].setSelected(false);
this._selectedItems[i].item.setSelected(false);
},
/**
@ -260,6 +264,7 @@ var Project = this.Project = PaperScopeItem.extend(/** @lends Project# */{
*/
draw: function(ctx, matrix) {
this._drawCount++;
ctx.save();
if (!matrix.isIdentity())
matrix.applyToContext(ctx);
@ -303,7 +308,8 @@ var Project = this.Project = PaperScopeItem.extend(/** @lends Project# */{
}
for (var id in this._selectedItems) {
var item = this._selectedItems[id];
item.drawSelected(ctx, getGlobalMatrix(item, matrix.clone()));
if (item._drawCount === this._drawCount)
item.drawSelected(ctx, getGlobalMatrix(item, matrix.clone()));
}
ctx.restore();
}