fix wront mouseleale trigger after drag is finished. close #1374

This commit is contained in:
Anton Lavrenov 2022-08-05 10:57:36 -05:00
parent de571787d3
commit 05c98fa463
5 changed files with 72 additions and 4 deletions

View File

@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Fix `Konva.Label` position when tag attributes are changed
- Fix incorrect ellipsis display for `Konva.Text`
- Fix `click` event trigger on parent containers on touch devices
### 8.3.10 (2022-06-20)

View File

@ -95,6 +95,7 @@ export const DD = {
// dragBefore and dragAfter allows us to set correct order of events
// setup all in dragbefore, and stop dragging only after pointerup triggered.
_endDragBefore(evt?) {
const drawNodes = [];
DD._dragElements.forEach((elem) => {
const { node } = elem;
// we need to find pointer relative to that node
@ -124,10 +125,17 @@ export const DD = {
const drawNode =
elem.node.getLayer() ||
((elem.node instanceof Konva['Stage'] && elem.node) as any);
if (drawNode) {
drawNode.batchDraw();
if (drawNode && drawNodes.indexOf(drawNode) === -1) {
drawNodes.push(drawNode);
}
});
// draw in a sync way
// because mousemove event may trigger BEFORE batch draw is called
// but as we have not hit canvas updated yet, it will trigger incorrect mouseover/mouseout events
drawNodes.forEach((drawNode) => {
drawNode.draw();
});
},
_endDragAfter(evt) {
DD._dragElements.forEach((elem, key) => {

View File

@ -737,7 +737,10 @@ export class Stage extends Container<Layer> {
// always call preventDefault for desktop events because some browsers
// try to drag and drop the canvas element
if (evt.cancelable && eventType !== "touch") {
// TODO: are we sure we need to prevent default at all?
// do not call this function on mobile because it prevent "click" event on all parent containers
// but apps may listen to it.
if (evt.cancelable && eventType !== 'touch') {
evt.preventDefault();
}
}

View File

@ -1223,4 +1223,60 @@ describe('DragAndDrop', function () {
assert.equal(dragstart, 0);
assert.equal(dragend, 0);
});
it('mouseleave should not occur after drag and drop', function (done) {
var stage = addStage();
var layer = new Konva.Layer();
var circle = new Konva.Circle({
x: 40,
y: 40,
radius: 20,
strokeWidth: 4,
fill: 'green',
stroke: 'black',
draggable: true,
});
layer.add(circle);
stage.add(layer);
var mouseleave = false;
var dragend = false;
var mouseenter = true;
circle.on('mouseenter', function () {
mouseenter = true;
});
circle.on('mouseleave', function () {
mouseleave = true;
});
circle.on('dragend', function () {
dragend = true;
});
simulateMouseMove(stage, {
x: 40,
y: 40,
});
assert(mouseenter, 'mouseenter event should have been fired');
simulateMouseDown(stage, {
x: 40,
y: 40,
});
setTimeout(function () {
simulateMouseMove(stage, {
x: 100,
y: 100,
});
setTimeout(() => {
simulateMouseUp(stage, {
x: 100,
y: 100,
});
simulateMouseMove(stage, {
x: 102,
y: 102,
});
assert(!mouseleave, 'mouseleave event should not have been fired');
assert(dragend, 'dragend event should have been fired');
done();
}, 70);
}, 70);
});
});

View File

@ -202,8 +202,8 @@ export function simulateMouseMove(stage, pos) {
type: 'mousemove',
};
stage._pointermove(evt);
Konva.DD._drag(evt);
stage._pointermove(evt);
}
export function simulateMouseUp(stage, pos) {