mirror of
https://github.com/konvajs/konva.git
synced 2025-05-03 12:27:47 +08:00
drag and drop operatons now dynamically generate a temporary top layer for high performance drag and drop. When completed, the top layer is removed. Also cleaned up a bit of drag and drop logic
This commit is contained in:
parent
36584a3ce2
commit
7ba40a6a68
@ -31,7 +31,6 @@
|
||||
this.frame.timeDiff = 0;
|
||||
this.frame.lastTime = new Date().getTime();
|
||||
Kinetic.Animation._addAnimation(this);
|
||||
Kinetic.Animation._handleAnimation();
|
||||
},
|
||||
/**
|
||||
* stop animation
|
||||
@ -59,6 +58,7 @@
|
||||
|
||||
Kinetic.Animation._addAnimation = function(anim) {
|
||||
this.animations.push(anim);
|
||||
this._handleAnimation();
|
||||
};
|
||||
Kinetic.Animation._removeAnimation = function(anim) {
|
||||
var id = anim.id;
|
||||
|
@ -150,8 +150,6 @@
|
||||
/**
|
||||
* apply shadow
|
||||
* @name applyShadow
|
||||
* @param {CanvasContext} context
|
||||
* @param {Function} func draw function
|
||||
* @methodOf Kinetic.Canvas.prototype
|
||||
* @param {Kinetic.Shape} shape
|
||||
* @param {Function} drawFunc
|
||||
@ -194,6 +192,13 @@
|
||||
pixelRatio = 1 / pixelRatio;
|
||||
this.getContext().scale(pixelRatio, pixelRatio);
|
||||
}
|
||||
},
|
||||
_applyAncestorTransforms: function(node) {
|
||||
var context = this.context;
|
||||
node.eachAncestorReverse(function(no) {
|
||||
var t = no.getTransform(), m = t.getMatrix();
|
||||
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -5,12 +5,74 @@
|
||||
offset: {
|
||||
x: 0,
|
||||
y: 0
|
||||
},
|
||||
prevParent: null,
|
||||
topLayer: null
|
||||
};
|
||||
Kinetic.Node.prototype._startDrag = function() {
|
||||
var dd = Kinetic.DD;
|
||||
var stage = this.getStage();
|
||||
var pos = stage.getUserPosition();
|
||||
|
||||
if(pos) {
|
||||
var m = this.getTransform().getTranslation(), ap = this.getAbsolutePosition(), nodeType = this.nodeType;
|
||||
|
||||
dd.node = this;
|
||||
dd.offset.x = pos.x - ap.x;
|
||||
dd.offset.y = pos.y - ap.y;
|
||||
|
||||
/*
|
||||
* if dragging and dropping the stage,
|
||||
* draw all of the layers
|
||||
*/
|
||||
if(nodeType === 'Stage') {
|
||||
dd.anim.node = this;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* if node type is a group or shape, create a top layer,
|
||||
* and move the node to the top layer
|
||||
*/
|
||||
if(nodeType === 'Group' || nodeType === 'Shape') {
|
||||
var lastContainer = null;
|
||||
dd.prevParent = this.getParent();
|
||||
|
||||
// re-construct node tree
|
||||
this.eachAncestorReverse(function(node) {
|
||||
if(node.nodeType === 'Layer') {
|
||||
dd.topLayer = new Kinetic.Layer({
|
||||
x: node.getX(),
|
||||
y: node.getY(),
|
||||
scale: node.getScale(),
|
||||
rotation: node.getRotation()
|
||||
});
|
||||
lastContainer = dd.topLayer;
|
||||
stage.add(dd.topLayer);
|
||||
}
|
||||
else if(node.nodeType === 'Group') {
|
||||
var group = new Kinetic.Group({
|
||||
x: node.getX(),
|
||||
y: node.getY(),
|
||||
scale: node.getScale(),
|
||||
rotation: node.getRotation()
|
||||
});
|
||||
|
||||
lastContainer.add(group);
|
||||
lastContainer = group;
|
||||
}
|
||||
});
|
||||
|
||||
this.moveTo(lastContainer);
|
||||
dd.prevParent.getLayer().draw();
|
||||
}
|
||||
|
||||
dd.anim.node = this.getLayer();
|
||||
}
|
||||
dd.anim.start();
|
||||
}
|
||||
};
|
||||
|
||||
Kinetic.DD._startDrag = function(evt) {
|
||||
var dd = Kinetic.DD;
|
||||
var node = dd.node;
|
||||
Kinetic.DD._drag = function(evt) {
|
||||
var dd = Kinetic.DD, node = dd.node;
|
||||
|
||||
if(node) {
|
||||
var pos = node.getStage().getUserPosition();
|
||||
@ -40,14 +102,21 @@
|
||||
}
|
||||
};
|
||||
Kinetic.DD._endDrag = function(evt) {
|
||||
var dd = Kinetic.DD;
|
||||
var node = dd.node;
|
||||
var dd = Kinetic.DD, node = dd.node;
|
||||
if(node) {
|
||||
var nodeType = node.nodeType;
|
||||
node.setListening(true);
|
||||
if(node.nodeType === 'Stage') {
|
||||
if(nodeType === 'Stage') {
|
||||
node.draw();
|
||||
}
|
||||
else {
|
||||
if(nodeType === 'Group' || nodeType === 'Shape') {
|
||||
node.moveTo(dd.prevParent);
|
||||
dd.topLayer.remove();
|
||||
dd.prevParent = null;
|
||||
dd.topLayer = null;
|
||||
}
|
||||
|
||||
node.getLayer().draw();
|
||||
}
|
||||
|
||||
@ -90,37 +159,9 @@
|
||||
|
||||
Kinetic.Node.prototype._listenDrag = function() {
|
||||
this._dragCleanup();
|
||||
var that = this;
|
||||
this.on('mousedown.kinetic touchstart.kinetic', function(evt) {
|
||||
that._initDrag();
|
||||
});
|
||||
this.on('mousedown.kinetic touchstart.kinetic', this._startDrag);
|
||||
};
|
||||
Kinetic.Node.prototype._initDrag = function() {
|
||||
var dd = Kinetic.DD;
|
||||
var stage = this.getStage();
|
||||
var pos = stage.getUserPosition();
|
||||
|
||||
if(pos) {
|
||||
var m = this.getTransform().getTranslation();
|
||||
var am = this.getAbsoluteTransform().getTranslation();
|
||||
var ap = this.getAbsolutePosition();
|
||||
dd.node = this;
|
||||
dd.offset.x = pos.x - ap.x;
|
||||
dd.offset.y = pos.y - ap.y;
|
||||
|
||||
/*
|
||||
* if dragging and dropping the stage,
|
||||
* draw all of the layers
|
||||
*/
|
||||
if(this.nodeType === 'Stage') {
|
||||
dd.anim.node = this;
|
||||
}
|
||||
else {
|
||||
dd.anim.node = this.getLayer();
|
||||
}
|
||||
dd.anim.start();
|
||||
}
|
||||
};
|
||||
Kinetic.Node.prototype._dragChange = function() {
|
||||
if(this.attrs.draggable) {
|
||||
this._listenDrag();
|
||||
@ -145,7 +186,6 @@
|
||||
this.off('mousedown.kinetic');
|
||||
this.off('touchstart.kinetic');
|
||||
};
|
||||
|
||||
/**
|
||||
* get draggable. Alias of getDraggable()
|
||||
* @name isDraggable
|
||||
|
38
src/Node.js
38
src/Node.js
@ -436,6 +436,42 @@
|
||||
getRotationDeg: function() {
|
||||
return Kinetic.Type._radToDeg(this.getRotation());
|
||||
},
|
||||
/**
|
||||
* iterate through ancestors in reverse
|
||||
* @name eachAncestorReverse
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
* @param {Function} func function is passed two arguments, a node and
|
||||
* the iterator integer
|
||||
*/
|
||||
eachAncestorReverse: function(func) {
|
||||
var family = [], parent = this.getParent();
|
||||
|
||||
// build family by traversing ancestors
|
||||
family.unshift(this);
|
||||
while(parent) {
|
||||
family.unshift(parent);
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
var len = family.length;
|
||||
for(var n = 0; n < len; n++) {
|
||||
func(family[n], n);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* iterate through ancestors
|
||||
* @name eachAncestor
|
||||
* @methodOf Kinetic.Node.prototype
|
||||
* @param {Function} func function is passed two arguments, a node and
|
||||
* the iterator integer
|
||||
*/
|
||||
eachAncestor: function(func) {
|
||||
var family = [], parent = this.getParent(), n = 0;
|
||||
while(parent) {
|
||||
func(parent, n++);
|
||||
parent = parent.parent;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* set rotation in degrees
|
||||
* @name setRotationDeg
|
||||
@ -761,7 +797,7 @@
|
||||
context = canvas.getContext();
|
||||
context.save();
|
||||
canvas._counterPixelRatio();
|
||||
|
||||
|
||||
if(x || y) {
|
||||
context.translate(-1 * x, -1 * y);
|
||||
}
|
||||
|
28
src/Shape.js
28
src/Shape.js
@ -205,23 +205,11 @@
|
||||
var attrs = this.attrs, drawFunc = attrs.drawFunc, canvas = canvas || this.getLayer().getCanvas(), context = canvas.getContext();
|
||||
|
||||
if(drawFunc && this.isVisible()) {
|
||||
var stage = this.getStage(), family = [], parent = this.parent;
|
||||
|
||||
family.unshift(this);
|
||||
while(parent) {
|
||||
family.unshift(parent);
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
context.save();
|
||||
canvas._handlePixelRatio();
|
||||
canvas._applyOpacity(this);
|
||||
canvas._applyLineJoin(this);
|
||||
var len = family.length;
|
||||
for(var n = 0; n < len; n++) {
|
||||
var node = family[n], t = node.getTransform(), m = t.getMatrix();
|
||||
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||
}
|
||||
canvas._applyAncestorTransforms(this);
|
||||
|
||||
drawFunc.call(this, canvas);
|
||||
context.restore();
|
||||
@ -231,21 +219,9 @@
|
||||
var attrs = this.attrs, drawFunc = attrs.drawHitFunc || attrs.drawFunc, canvas = this.getLayer().hitCanvas, context = canvas.getContext();
|
||||
|
||||
if(drawFunc && this.isVisible() && this.isListening()) {
|
||||
var stage = this.getStage(), family = [], parent = this.parent;
|
||||
|
||||
family.unshift(this);
|
||||
while(parent) {
|
||||
family.unshift(parent);
|
||||
parent = parent.parent;
|
||||
}
|
||||
|
||||
context.save();
|
||||
canvas._applyLineJoin(this);
|
||||
var len = family.length;
|
||||
for(var n = 0; n < len; n++) {
|
||||
var node = family[n], t = node.getTransform(), m = t.getMatrix();
|
||||
context.transform(m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||
}
|
||||
canvas._applyAncestorTransforms(this);
|
||||
|
||||
drawFunc.call(this, canvas);
|
||||
context.restore();
|
||||
|
18
src/Stage.js
18
src/Stage.js
@ -26,12 +26,9 @@
|
||||
this._id = Kinetic.Global.idCounter++;
|
||||
this._buildDOM();
|
||||
this._bindContentEvents();
|
||||
|
||||
var go = Kinetic.Global;
|
||||
go.stages.push(this);
|
||||
Kinetic.Global.stages.push(this);
|
||||
this._addId(this);
|
||||
this._addName(this);
|
||||
|
||||
},
|
||||
/**
|
||||
* set container dom element which contains the stage wrapper div element
|
||||
@ -333,11 +330,6 @@
|
||||
this.targetShape = null;
|
||||
}
|
||||
this.mousePos = undefined;
|
||||
|
||||
// end drag and drop
|
||||
if(dd) {
|
||||
dd._endDrag(evt);
|
||||
}
|
||||
},
|
||||
_mousemove: function(evt) {
|
||||
this._setUserPosition(evt);
|
||||
@ -373,7 +365,7 @@
|
||||
|
||||
// start drag and drop
|
||||
if(dd) {
|
||||
dd._startDrag(evt);
|
||||
dd._drag(evt);
|
||||
}
|
||||
},
|
||||
_mousedown: function(evt) {
|
||||
@ -387,7 +379,7 @@
|
||||
|
||||
//init stage drag and drop
|
||||
if(Kinetic.DD && this.attrs.draggable) {
|
||||
this._initDrag();
|
||||
this._startDrag();
|
||||
}
|
||||
},
|
||||
_mouseup: function(evt) {
|
||||
@ -440,7 +432,7 @@
|
||||
* init stage drag and drop
|
||||
*/
|
||||
if(Kinetic.DD && this.attrs.draggable) {
|
||||
this._initDrag();
|
||||
this._startDrag();
|
||||
}
|
||||
},
|
||||
_touchend: function(evt) {
|
||||
@ -491,7 +483,7 @@
|
||||
|
||||
// start drag and drop
|
||||
if(dd) {
|
||||
dd._startDrag(evt);
|
||||
dd._drag(evt);
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
@ -177,7 +177,7 @@ Test.Modules.MANUAL = {
|
||||
anim.stop();
|
||||
}, 3000);
|
||||
},
|
||||
'*ANIMATION - test multiple animations': function(containerId) {
|
||||
'ANIMATION - test multiple animations': function(containerId) {
|
||||
var stage = new Kinetic.Stage({
|
||||
container: containerId,
|
||||
width: 578,
|
||||
|
Loading…
Reference in New Issue
Block a user