mirror of
https://github.com/konvajs/konva.git
synced 2025-04-05 20:48:28 +08:00
fix dragstart bug. close #708
This commit is contained in:
parent
37fcd13fa0
commit
57d9917b62
2
konva.min.js
vendored
2
konva.min.js
vendored
File diff suppressed because one or more lines are too long
@ -443,7 +443,7 @@ export abstract class Container<ChildType extends Node> extends Node<
|
||||
var layer = this.getLayer();
|
||||
var layerUnderDrag = false;
|
||||
DD._dragElements.forEach(elem => {
|
||||
if (elem.isDragging && elem.node.getLayer() === layer) {
|
||||
if (elem.dragStatus === 'dragging' && elem.node.getLayer() === layer) {
|
||||
layerUnderDrag = true;
|
||||
}
|
||||
});
|
||||
|
@ -7,7 +7,7 @@ export const DD = {
|
||||
get isDragging() {
|
||||
var flag = false;
|
||||
DD._dragElements.forEach(elem => {
|
||||
if (elem.isDragging) {
|
||||
if (elem.dragStatus === 'dragging') {
|
||||
flag = true;
|
||||
}
|
||||
});
|
||||
@ -28,9 +28,13 @@ export const DD = {
|
||||
node: Node;
|
||||
startPointerPos: Vector2d;
|
||||
offset: Vector2d;
|
||||
isDragging: boolean;
|
||||
pointerId?: number;
|
||||
dragStopped: boolean;
|
||||
// when we just put pointer down on a node
|
||||
// it will create drag element
|
||||
dragStatus: 'ready' | 'dragging' | 'stopped';
|
||||
// dragStarted: boolean;
|
||||
// isDragging: boolean;
|
||||
// dragStopped: boolean;
|
||||
}
|
||||
>(),
|
||||
|
||||
@ -55,7 +59,7 @@ export const DD = {
|
||||
if (!pos) {
|
||||
return;
|
||||
}
|
||||
if (!elem.isDragging) {
|
||||
if (elem.dragStatus !== 'dragging') {
|
||||
var dragDistance = node.dragDistance();
|
||||
var distance = Math.max(
|
||||
Math.abs(pos.x - elem.startPointerPos.x),
|
||||
@ -64,16 +68,7 @@ export const DD = {
|
||||
if (distance < dragDistance) {
|
||||
return;
|
||||
}
|
||||
elem.isDragging = true;
|
||||
node.fire(
|
||||
'dragstart',
|
||||
{
|
||||
type: 'dragstart',
|
||||
target: node,
|
||||
evt: evt
|
||||
},
|
||||
true
|
||||
);
|
||||
node.startDrag(evt);
|
||||
// a user can stop dragging inside `dragstart`
|
||||
if (!node.isDragging()) {
|
||||
return;
|
||||
@ -112,13 +107,12 @@ export const DD = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (elem.isDragging) {
|
||||
if (elem.dragStatus === 'dragging') {
|
||||
DD.justDragged = true;
|
||||
Konva.listenClickTap = false;
|
||||
}
|
||||
|
||||
elem.dragStopped = true;
|
||||
elem.isDragging = false;
|
||||
elem.dragStatus = 'stopped';
|
||||
|
||||
const drawNode =
|
||||
elem.node.getLayer() ||
|
||||
@ -130,7 +124,7 @@ export const DD = {
|
||||
},
|
||||
_endDragAfter(evt) {
|
||||
DD._dragElements.forEach((elem, key) => {
|
||||
if (elem.dragStopped) {
|
||||
if (elem.dragStatus === 'stopped') {
|
||||
elem.node.fire(
|
||||
'dragend',
|
||||
{
|
||||
|
66
src/Node.ts
66
src/Node.ts
@ -2229,32 +2229,47 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
}
|
||||
|
||||
// drag & drop
|
||||
_createDragElement(evt) {
|
||||
var pointerId = evt ? evt.pointerId : undefined;
|
||||
var stage = this.getStage();
|
||||
var ap = this.getAbsolutePosition();
|
||||
var pos =
|
||||
stage._getPointerById(pointerId) ||
|
||||
stage._changedPointerPositions[0] ||
|
||||
ap;
|
||||
DD._dragElements.set(this._id, {
|
||||
node: this,
|
||||
startPointerPos: pos,
|
||||
offset: {
|
||||
x: pos.x - ap.x,
|
||||
y: pos.y - ap.y
|
||||
},
|
||||
dragStatus: 'ready',
|
||||
pointerId
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* initiate drag and drop
|
||||
* initiate drag and drop.
|
||||
* @method
|
||||
* @name Konva.Node#startDrag
|
||||
*/
|
||||
startDrag(evt?: any) {
|
||||
// forceDrag means it is started by user
|
||||
const forceDrag = !evt;
|
||||
var pointerId = evt ? evt.pointerId : undefined;
|
||||
var stage = this.getStage(),
|
||||
pos = stage._getPointerById(pointerId),
|
||||
ap = this.getAbsolutePosition();
|
||||
|
||||
if (pos || forceDrag) {
|
||||
DD._dragElements.set(this._id, {
|
||||
node: this,
|
||||
startPointerPos: pos,
|
||||
offset: forceDrag ? {x: 0, y: 0 } : {
|
||||
x: pos.x - ap.x,
|
||||
y: pos.y - ap.y
|
||||
},
|
||||
isDragging: forceDrag ? true : false,
|
||||
pointerId,
|
||||
dragStopped: false
|
||||
});
|
||||
if (!DD._dragElements.has(this._id)) {
|
||||
this._createDragElement(evt);
|
||||
}
|
||||
|
||||
const elem = DD._dragElements.get(this._id);
|
||||
elem.dragStatus = 'dragging';
|
||||
this.fire(
|
||||
'dragstart',
|
||||
{
|
||||
type: 'dragstart',
|
||||
target: this,
|
||||
evt: evt && evt.evt
|
||||
},
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
_setDragPosition(evt, elem) {
|
||||
@ -2300,7 +2315,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
var evt = {};
|
||||
const elem = DD._dragElements.get(this._id);
|
||||
if (elem) {
|
||||
elem.dragStopped = true;
|
||||
elem.dragStatus = 'stopped';
|
||||
}
|
||||
DD._endDragBefore(evt);
|
||||
DD._endDragAfter(evt);
|
||||
@ -2318,7 +2333,7 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
*/
|
||||
isDragging() {
|
||||
const elem = DD._dragElements.get(this._id);
|
||||
return elem ? elem.isDragging : false;
|
||||
return elem ? elem.dragStatus === 'dragging' : false;
|
||||
}
|
||||
|
||||
_listenDrag() {
|
||||
@ -2340,11 +2355,12 @@ export abstract class Node<Config extends NodeConfig = NodeConfig> {
|
||||
if (this.isAncestorOf(elem.node)) {
|
||||
hasDraggingChild = true;
|
||||
}
|
||||
})
|
||||
});
|
||||
// nested drag can be started
|
||||
// in that case we don't need to start new drag
|
||||
if (!hasDraggingChild) {
|
||||
this.startDrag(evt);
|
||||
this._createDragElement(evt);
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -659,22 +659,32 @@ suite('DragAndDrop', function() {
|
||||
]);
|
||||
|
||||
// move one finger
|
||||
stage.simulateTouchMove([
|
||||
{
|
||||
x: 100,
|
||||
y: 100,
|
||||
id: 0
|
||||
},
|
||||
{
|
||||
x: 270,
|
||||
y: 70,
|
||||
id: 1
|
||||
}
|
||||
]);
|
||||
stage.simulateTouchMove(
|
||||
[
|
||||
{
|
||||
x: 100,
|
||||
y: 100,
|
||||
id: 0
|
||||
},
|
||||
{
|
||||
x: 270,
|
||||
y: 70,
|
||||
id: 1
|
||||
}
|
||||
],
|
||||
[
|
||||
{
|
||||
x: 100,
|
||||
y: 100,
|
||||
id: 0
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
assert.equal(dragstart1, 1);
|
||||
assert.equal(circle1.isDragging(), true);
|
||||
assert.equal(dragmove1, 1);
|
||||
assert.equal(dragmove2, 0);
|
||||
assert.equal(circle1.x(), 100);
|
||||
assert.equal(circle1.y(), 100);
|
||||
|
||||
@ -944,6 +954,41 @@ suite('DragAndDrop', function() {
|
||||
assert.equal(circle.y(), 80);
|
||||
});
|
||||
|
||||
test('calling startDrag show still fire event when required', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
var circle = new Konva.Circle({
|
||||
x: 70,
|
||||
y: 70,
|
||||
radius: 70,
|
||||
fill: 'green',
|
||||
stroke: 'black',
|
||||
strokeWidth: 4,
|
||||
name: 'myCircle',
|
||||
draggable: true
|
||||
});
|
||||
|
||||
var dragstart = 0;
|
||||
circle.on('dragstart', function() {
|
||||
dragstart += 1;
|
||||
});
|
||||
layer.add(circle);
|
||||
stage.add(layer);
|
||||
|
||||
// register pointer
|
||||
stage.simulateMouseMove({ x: 70, y: 80 });
|
||||
circle.startDrag();
|
||||
assert.equal(dragstart, 1);
|
||||
assert.equal(circle.isDragging(), true);
|
||||
// moving by one pixel should move circle too
|
||||
stage.simulateMouseMove({ x: 70, y: 81 });
|
||||
stage.simulateMouseUp({ x: 70, y: 81 });
|
||||
|
||||
assert.equal(circle.x(), 70);
|
||||
assert.equal(circle.y(), 71);
|
||||
});
|
||||
|
||||
test('try nested dragging', function() {
|
||||
var stage = addStage();
|
||||
var layer = new Konva.Layer({
|
||||
|
Loading…
Reference in New Issue
Block a user