diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ea983ca..5558ccbe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - `Konva.names` and `Konva.ids` are removed - new `flipEnabled` property for `Konva.Transformer`. - new `node.isClientRectOnScreen()` method +- argument `selector` is removed from `node.getIntersection(pos)` API +- `Konva.captureTouchEventsEnabled` is renamed to `Konva.capturePointerEventsEnabled` ## 7.2.5 diff --git a/src/Context.ts b/src/Context.ts index f7e515b3..bbc1ff80 100644 --- a/src/Context.ts +++ b/src/Context.ts @@ -459,8 +459,12 @@ export class Context { * @method * @name Konva.Context#fillText */ - fillText(a0, a1, a2) { - this._context.fillText(a0, a1, a2); + fillText(text: string, x: number, y: number, maxWidth?: number) { + if (maxWidth) { + this._context.fillText(text, x, y, maxWidth); + } else { + this._context.fillText(text, x, y); + } } /** * measureText function. @@ -696,30 +700,6 @@ export class SceneContext extends Context { shape._fillFunc(this); } _fillPattern(shape) { - var fillPatternX = shape.getFillPatternX(), - fillPatternY = shape.getFillPatternY(), - fillPatternRotation = Konva.getAngle(shape.getFillPatternRotation()), - fillPatternOffsetX = shape.getFillPatternOffsetX(), - fillPatternOffsetY = shape.getFillPatternOffsetY(), - fillPatternScaleX = shape.getFillPatternScaleX(), - fillPatternScaleY = shape.getFillPatternScaleY(); - - // if (fillPatternX || fillPatternY) { - // this.translate(fillPatternX || 0, fillPatternY || 0); - // } - - // if (fillPatternRotation) { - // this.rotate(fillPatternRotation); - // } - - if (fillPatternScaleX || fillPatternScaleY) { - // this.scale(fillPatternScaleX, fillPatternScaleY); - } - - // if (fillPatternOffsetX || fillPatternOffsetY) { - // this.translate(-1 * fillPatternOffsetX, -1 * fillPatternOffsetY); - // } - this.setAttr('fillStyle', shape._getFillPattern()); shape._fillFunc(this); } diff --git a/src/DragAndDrop.ts b/src/DragAndDrop.ts index 4b99d4ac..e674b198 100644 --- a/src/DragAndDrop.ts +++ b/src/DragAndDrop.ts @@ -95,7 +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?) { - DD._dragElements.forEach((elem, key) => { + DD._dragElements.forEach((elem) => { const { node } = elem; // we need to find pointer relative to that node const stage = node.getStage(); @@ -113,7 +113,7 @@ export const DD = { } if (elem.dragStatus === 'dragging' || elem.dragStatus === 'stopped') { - // if a node is stopped manully we still need to reset events: + // if a node is stopped manually we still need to reset events: DD.justDragged = true; Konva.listenClickTap = false; elem.dragStatus = 'stopped'; diff --git a/src/Global.ts b/src/Global.ts index 02f9068a..700cc6d1 100644 --- a/src/Global.ts +++ b/src/Global.ts @@ -45,7 +45,7 @@ export const Konva = { return Konva.angleDeg ? angle * PI_OVER_180 : angle; }, enableTrace: false, - _pointerEventsEnabled: false, + pointerEventsEnabled: false, /** * Should Konva automatically update canvas on any changes. Default is true. * @property autoDrawEnabled @@ -72,16 +72,15 @@ export const Konva = { * The case: we touchstart on div1, then touchmove out of that element into another element div2. * DOM will continue trigger touchmove events on div1 (not div2). Because events are "captured" into initial target. * By default Konva do not do that and will trigger touchmove on another element, while pointer is moving. - * @property captureTouchEventsEnabled + * @property capturePointerEventsEnabled * @default false - * @name captureTouchEventsEnabled + * @name capturePointerEventsEnabled * @memberof Konva * @example - * Konva.captureTouchEventsEnabled = true; + * Konva.capturePointerEventsEnabled = true; */ - captureTouchEventsEnabled: false, + capturePointerEventsEnabled: false, - // TODO: move that to stage? listenClickTap: false, inDblClickWindow: false, diff --git a/src/Layer.ts b/src/Layer.ts index d5e1eb5f..8a20ca9d 100644 --- a/src/Layer.ts +++ b/src/Layer.ts @@ -331,14 +331,11 @@ export class Layer extends Container { * @param {Object} pos * @param {Number} pos.x * @param {Number} pos.y - * @param {String} [selector] * @returns {Konva.Node} * @example * var shape = layer.getIntersection({x: 50, y: 50}); - * // or if you interested in shape parent: - * var group = layer.getIntersection({x: 50, y: 50}, 'Group'); */ - getIntersection(pos: Vector2d, selector?: string): Node | null { + getIntersection(pos: Vector2d) { if (!this.isListening() || !this.isVisible()) { return null; } @@ -354,9 +351,7 @@ export class Layer extends Container { y: pos.y + intersectionOffset.y * spiralSearchDistance, }); const shape = obj.shape; - if (shape && selector) { - return shape.findAncestor(selector, true); - } else if (shape) { + if (shape) { return shape; } // we should continue search if we found antialiased pixel diff --git a/src/Stage.ts b/src/Stage.ts index 0542a9c9..2ab847ae 100644 --- a/src/Stage.ts +++ b/src/Stage.ts @@ -39,6 +39,7 @@ var STAGE = 'Stage', TAP = 'tap', DBL_TAP = 'dbltap', TOUCHMOVE = 'touchmove', + TOUCHCANCEL = 'touchcancel', WHEEL = 'wheel', CONTENT_MOUSEOUT = 'contentMouseout', CONTENT_MOUSEOVER = 'contentMouseover', @@ -53,52 +54,97 @@ var STAGE = 'Stage', CONTENT_DBL_TAP = 'contentDbltap', CONTENT_TAP = 'contentTap', CONTENT_TOUCHMOVE = 'contentTouchmove', - CONTENT_POINTERMOVE = 'contentPointermove', - CONTENT_POINTERDOWN = 'contentPointerdown', - CONTENT_POINTERUP = 'contentPointerup', CONTENT_WHEEL = 'contentWheel', RELATIVE = 'relative', KONVA_CONTENT = 'konvajs-content', - SPACE = ' ', UNDERSCORE = '_', CONTAINER = 'container', MAX_LAYERS_NUMBER = 5, EMPTY_STRING = '', EVENTS = [ - MOUSEENTER, - MOUSEDOWN, - MOUSEMOVE, - MOUSEUP, - MOUSELEAVE, - TOUCHSTART, - TOUCHMOVE, - TOUCHEND, - MOUSEOVER, - WHEEL, - CONTEXTMENU, - POINTERDOWN, - POINTERMOVE, - POINTERUP, - POINTERCANCEL, - LOSTPOINTERCAPTURE, - ], - // cached variables - eventsLength = EVENTS.length; - -function addEvent(ctx, eventName) { - ctx.content.addEventListener( - eventName, - function (evt) { - ctx[UNDERSCORE + eventName](evt); - }, - false - ); -} + [MOUSEENTER, '_pointerenter'], + [MOUSEDOWN, '_pointerdown'], + [MOUSEMOVE, '_pointermove'], + [MOUSEUP, '_pointerup'], + [MOUSELEAVE, '_pointerleave'], + [TOUCHSTART, '_pointerdown'], + [TOUCHMOVE, '_pointermove'], + [TOUCHEND, '_pointerup'], + [TOUCHCANCEL, '_pointercancel'], + [MOUSEOVER, '_pointerover'], + [WHEEL, '_wheel'], + [CONTEXTMENU, '_contextmenu'], + [POINTERDOWN, '_pointerdown'], + [POINTERMOVE, '_pointermove'], + [POINTERUP, '_pointerup'], + [POINTERCANCEL, '_pointercancel'], + [LOSTPOINTERCAPTURE, '_lostpointercapture'], + ]; const NO_POINTERS_MESSAGE = `Pointer position is missing and not registered by the stage. Looks like it is outside of the stage container. You can set it manually from event: stage.setPointersPositions(event);`; export const stages: Stage[] = []; +const EVENTS_MAP = { + mouse: { + pointerout: 'mouseout', + pointerleave: 'mouseleave', + pointerover: 'mouseover', + pointerenter: 'mouseenter', + pointermove: 'mousemove', + pointerdown: 'mousedown', + pointerup: 'mouseup', + pointercancel: 'mousecancel', + pointerclick: 'click', + pointerdblclick: 'dblclick', + }, + touch: { + pointerout: 'touchout', + pointerleave: 'touchleave', + pointerover: 'touchover', + pointerenter: 'touchenter', + pointermove: 'touchmove', + pointerdown: 'touchstart', + pointerup: 'touchend', + pointerclick: 'tap', + pointerdblclick: 'dbltap', + }, + pointer: { + pointerout: 'pointerout', + pointerleave: 'pointerleave', + pointerover: 'pointerover', + pointerenter: 'pointerenter', + pointermove: 'pointermove', + pointerdown: 'pointerdown', + pointerup: 'pointerup', + pointerclick: 'pointerclick', + pointerdblclick: 'pointerdblclick', + }, +}; + +const getEventType = (type) => { + if (type.indexOf('pointer') >= 0) { + return 'pointer'; + } + if (type.indexOf('touch') >= 0) { + return 'touch'; + } + return 'mouse'; +}; + +const getEventsMap = (eventType: string) => { + const type = getEventType(eventType); + if (type === 'pointer') { + return Konva.pointerEventsEnabled && EVENTS_MAP.pointer; + } + if (type === 'touch') { + return EVENTS_MAP.touch; + } + if (type === 'mouse') { + return EVENTS_MAP.mouse; + } +}; + function checkNoClip(attrs: any = {}) { if (attrs.clipFunc || attrs.clipWidth || attrs.clipHeight) { Util.warn( @@ -128,16 +174,23 @@ export class Stage extends Container { content: HTMLDivElement; pointerPos: Vector2d | null; _pointerPositions: (Vector2d & { id?: number })[] = []; - _changedPointerPositions: (Vector2d & { id?: number })[] = []; + _changedPointerPositions: (Vector2d & { id: number })[] = []; bufferCanvas: SceneCanvas; bufferHitCanvas: HitCanvas; - targetShape: Shape; - clickStartShape: Shape; - clickEndShape: Shape; - tapStartShape: Shape; - tapEndShape: Shape; - dblTimeout: any; + _mouseTargetShape: Shape; + _touchTargetShape: Shape; + _pointerTargetShape: Shape; + _mouseClickStartShape: Shape; + _touchClickStartShape: Shape; + _pointerClickStartShape: Shape; + _mouseClickEndShape: Shape; + _touchClickEndShape: Shape; + _pointerClickEndShape: Shape; + + _mouseDblTimeout: any; + _touchDblTimeout: any; + _pointerDblTimeout: any; constructor(config: StageConfig) { super(checkNoClip(config)); @@ -320,14 +373,11 @@ export class Stage extends Container { * @param {Object} pos * @param {Number} pos.x * @param {Number} pos.y - * @param {String} [selector] * @returns {Konva.Node} * @example * var shape = stage.getIntersection({x: 50, y: 50}); - * // or if you interested in shape parent: - * var group = stage.getIntersection({x: 50, y: 50}, 'Group'); */ - getIntersection(pos: Vector2d | null, selector?: string) { + getIntersection(pos: Vector2d) { if (!pos) { return null; } @@ -337,7 +387,7 @@ export class Stage extends Container { n; for (n = end; n >= 0; n--) { - const shape = layers[n].getIntersection(pos, selector); + const shape = layers[n].getIntersection(pos); if (shape) { return shape; } @@ -423,36 +473,64 @@ export class Stage extends Container { if (!Konva.isBrowser) { return; } - for (var n = 0; n < eventsLength; n++) { - addEvent(this, EVENTS[n]); + EVENTS.forEach(([event, methodName]) => { + this.content.addEventListener(event, (evt) => { + this[methodName](evt); + }); + }); + } + _pointerenter(evt) { + this.setPointersPositions(evt); + const events = getEventsMap(evt.type); + this._fire(events.pointerenter, { + evt: evt, + target: this, + currentTarget: this, + }); + } + _pointerover(evt) { + this.setPointersPositions(evt); + const events = getEventsMap(evt.type); + this._fire(events.pointerover, { + evt: evt, + target: this, + currentTarget: this, + }); + } + _getTargetShape(evenType) { + let shape: Shape | null = this[evenType + 'targetShape']; + if (shape && !shape.getStage()) { + shape = null; } + return shape; } - _mouseenter(evt) { - this.setPointersPositions(evt); - this._fire(MOUSEENTER, { evt: evt, target: this, currentTarget: this }); - } - _mouseover(evt) { - this.setPointersPositions(evt); - this._fire(CONTENT_MOUSEOVER, { evt: evt }); - this._fire(MOUSEOVER, { evt: evt, target: this, currentTarget: this }); - } - _mouseleave(evt) { - this.setPointersPositions(evt); - var targetShape = this.targetShape?.getStage() ? this.targetShape : null; + _pointerleave(evt) { + const events = getEventsMap(evt.type); + const eventType = getEventType(evt.type); + if (!events) { + return; + } + this.setPointersPositions(evt); + + var targetShape = this._getTargetShape(eventType); var eventsEnabled = !DD.isDragging || Konva.hitOnDragEnabled; if (targetShape && eventsEnabled) { - targetShape._fireAndBubble(MOUSEOUT, { evt: evt }); - targetShape._fireAndBubble(MOUSELEAVE, { evt: evt }); - this._fire(MOUSELEAVE, { evt: evt, target: this, currentTarget: this }); - this.targetShape = null; - } else if (eventsEnabled) { - this._fire(MOUSELEAVE, { + targetShape._fireAndBubble(events.pointerout, { evt: evt }); + targetShape._fireAndBubble(events.pointerleave, { evt: evt }); + this._fire(events.pointerleave, { evt: evt, target: this, currentTarget: this, }); - this._fire(MOUSEOUT, { + this[eventType + 'targetShape'] = null; + } else if (eventsEnabled) { + this._fire(events.pointerleave, { + evt: evt, + target: this, + currentTarget: this, + }); + this._fire(events.pointerout, { evt: evt, target: this, currentTarget: this, @@ -460,177 +538,220 @@ export class Stage extends Container { } this.pointerPos = undefined; this._pointerPositions = []; - - this._fire(CONTENT_MOUSEOUT, { evt: evt }); } - _mousemove(evt) { + _pointerdown(evt: TouchEvent | MouseEvent | PointerEvent) { + const events = getEventsMap(evt.type); + const eventType = getEventType(evt.type); + + if (!events) { + return; + } this.setPointersPositions(evt); - var pointerId = Util._getFirstPointerId(evt); - var targetShape = this.targetShape?.getStage() ? this.targetShape : null; + + var triggeredOnShape = false; + this._changedPointerPositions.forEach((pos) => { + var shape = this.getIntersection(pos); + DD.justDragged = false; + // probably we are staring a click + Konva.listenClickTap = true; + + // no shape detected? do nothing + const hasShape = shape && shape.isListening(); + if (!hasShape) { + return; + } + + if (Konva.capturePointerEventsEnabled) { + shape.setPointerCapture(pos.id); + } + + // save where we started the click + this[eventType + 'ClickStartShape'] = shape; + + shape._fireAndBubble(events.pointerdown, { + evt: evt, + pointerId: pos.id, + }); + triggeredOnShape = true; + + // TODO: test in iframe + // only call preventDefault if the shape is listening for events + const isTouch = evt.type.indexOf('touch') >= 0; + if (shape.preventDefault() && evt.cancelable && isTouch) { + evt.preventDefault(); + } + }); + + // trigger down on stage if not already + if (!triggeredOnShape) { + this._fire(events.pointerdown, { + evt: evt, + target: this, + currentTarget: this, + pointerId: this._pointerPositions[0].id, + }); + } + } + _pointermove(evt: TouchEvent | MouseEvent | PointerEvent) { + const events = getEventsMap(evt.type); + const eventType = getEventType(evt.type); + if (!events) { + return; + } + if (DD.isDragging && DD.node.preventDefault() && evt.cancelable) { + evt.preventDefault(); + } + this.setPointersPositions(evt); + var eventsEnabled = !DD.isDragging || Konva.hitOnDragEnabled; - if (eventsEnabled) { - const shape = this.getIntersection(this.getPointerPosition()) as Shape; - if (shape && shape.isListening()) { - var differentTarget = targetShape !== shape; - if (eventsEnabled && differentTarget) { - if (targetShape) { - targetShape._fireAndBubble( - MOUSEOUT, - { evt: evt, pointerId }, - shape - ); - targetShape._fireAndBubble( - MOUSELEAVE, - { evt: evt, pointerId }, - shape - ); - } - shape._fireAndBubble(MOUSEOVER, { evt: evt, pointerId }, targetShape); - shape._fireAndBubble( - MOUSEENTER, - { evt: evt, pointerId }, - targetShape - ); - shape._fireAndBubble(MOUSEMOVE, { evt: evt, pointerId }); - this.targetShape = shape; - } else { - shape._fireAndBubble(MOUSEMOVE, { evt: evt, pointerId }); + if (!eventsEnabled) { + return; + } + + var processedShapesIds = {}; + let triggeredOnShape = false; + var targetShape = this._getTargetShape(eventType); + this._changedPointerPositions.forEach((pos) => { + const shape = (PointerEvents.getCapturedShape(pos.id) || + this.getIntersection(pos)) as Shape; + const pointerId = pos.id; + const event = { evt: evt, pointerId }; + + var differentTarget = targetShape !== shape; + + if (differentTarget && targetShape) { + targetShape._fireAndBubble(events.pointerout, event, shape); + targetShape._fireAndBubble(events.pointerleave, event, shape); + } + + if (shape) { + if (processedShapesIds[shape._id]) { + return; } + processedShapesIds[shape._id] = true; + } + + if (shape && shape.isListening()) { + triggeredOnShape = true; + if (differentTarget) { + shape._fireAndBubble(events.pointerover, event, targetShape); + shape._fireAndBubble(events.pointerenter, event, targetShape); + this[eventType + 'targetShape'] = shape; + } + shape._fireAndBubble(events.pointermove, event); } else { - /* - * if no shape was detected, clear target shape and try - * to run mouseout from previous target shape - */ - if (targetShape && eventsEnabled) { - targetShape._fireAndBubble(MOUSEOUT, { evt: evt, pointerId }); - targetShape._fireAndBubble(MOUSELEAVE, { evt: evt, pointerId }); - this._fire(MOUSEOVER, { + if (targetShape) { + this._fire(events.pointerover, { evt: evt, target: this, currentTarget: this, pointerId, }); - this.targetShape = null; + this[eventType + 'targetShape'] = null; } - this._fire(MOUSEMOVE, { - evt: evt, - target: this, - currentTarget: this, - pointerId, - }); } + }); - // content event - this._fire(CONTENT_MOUSEMOVE, { evt: evt }); - } - - // always call preventDefault for desktop events because some browsers - // try to drag and drop the canvas element - if (evt.cancelable) { - evt.preventDefault(); - } - } - _mousedown(evt) { - this.setPointersPositions(evt); - var pointerId = Util._getFirstPointerId(evt); - var shape = this.getIntersection(this.getPointerPosition()) as Shape; - - DD.justDragged = false; - Konva.listenClickTap = true; - - if (shape && shape.isListening()) { - this.clickStartShape = shape; - shape._fireAndBubble(MOUSEDOWN, { evt: evt, pointerId }); - } else { - this._fire(MOUSEDOWN, { + if (!triggeredOnShape) { + this._fire(events.pointermove, { evt: evt, target: this, currentTarget: this, - pointerId, + pointerId: this._changedPointerPositions[0].id, }); } // content event - this._fire(CONTENT_MOUSEDOWN, { evt: evt }); - - // Do not prevent default behavior, because it will prevent listening events outside of window iframe - // we used preventDefault for disabling native drag&drop - // but userSelect = none style will do the trick - // if (evt.cancelable) { - // evt.preventDefault(); - // } + this._fire(CONTENT_MOUSEMOVE, { evt: evt }); } - _mouseup(evt) { - this.setPointersPositions(evt); - var pointerId = Util._getFirstPointerId(evt); - var shape = this.getIntersection(this.getPointerPosition()) as Shape, - clickStartShape = this.clickStartShape, - clickEndShape = this.clickEndShape, - fireDblClick = false; + _pointerup(evt) { + const events = getEventsMap(evt.type); + const eventType = getEventType(evt.type); - if (Konva.inDblClickWindow) { - fireDblClick = true; - clearTimeout(this.dblTimeout); - // Konva.inDblClickWindow = false; - } else if (!DD.justDragged) { - // don't set inDblClickWindow after dragging - Konva.inDblClickWindow = true; - clearTimeout(this.dblTimeout); + if (!events) { + return; } + this.setPointersPositions(evt); + const clickStartShape = this[eventType + 'ClickStartShape']; + const clickEndShape = this[eventType + 'ClickEndShape']; + var processedShapesIds = {}; + let triggeredOnShape = false; + this._changedPointerPositions.forEach((pos) => { + const shape = (PointerEvents.getCapturedShape(pos.id) || + this.getIntersection(pos)) as Shape; - this.dblTimeout = setTimeout(function () { - Konva.inDblClickWindow = false; - }, Konva.dblClickWindow); + if (shape) { + shape.releaseCapture(pos.id); + if (processedShapesIds[shape._id]) { + return; + } + processedShapesIds[shape._id] = true; + } - if (shape && shape.isListening()) { - this.clickEndShape = shape; - shape._fireAndBubble(MOUSEUP, { evt: evt, pointerId }); + const pointerId = pos.id; + const event = { evt: evt, pointerId }; - // detect if click or double click occurred - if ( - Konva.listenClickTap && - clickStartShape && - clickStartShape._id === shape._id - ) { - shape._fireAndBubble(CLICK, { evt: evt, pointerId }); + let fireDblClick = false; + if (Konva.inDblClickWindow) { + fireDblClick = true; + clearTimeout(this[eventType + 'DblTimeout']); + } else if (!DD.justDragged) { + // don't set inDblClickWindow after dragging + Konva.inDblClickWindow = true; + clearTimeout(this[eventType + 'DblTimeout']); + } - if (fireDblClick && clickEndShape && clickEndShape === shape) { - shape._fireAndBubble(DBL_CLICK, { evt: evt, pointerId }); + this[eventType + 'DblTimeout'] = setTimeout(function () { + Konva.inDblClickWindow = false; + }, Konva.dblClickWindow); + + if (shape && shape.isListening()) { + triggeredOnShape = true; + this[eventType + 'ClickEndShape'] = shape; + shape._fireAndBubble(events.pointerup, event); + + // detect if click or double click occurred + if ( + Konva.listenClickTap && + clickStartShape && + clickStartShape === shape + ) { + shape._fireAndBubble(events.pointerclick, event); + + if (fireDblClick && clickEndShape && clickEndShape === shape) { + shape._fireAndBubble(events.pointerdblclick, event); + } + } + } else { + this[eventType + 'ClickEndShape'] = null; + + if (Konva.listenClickTap) { + this._fire(events.pointerclick, { + evt: evt, + target: this, + currentTarget: this, + pointerId, + }); + } + + if (fireDblClick) { + this._fire(events.pointerdblclick, { + evt: evt, + target: this, + currentTarget: this, + pointerId, + }); } } - } else { - this.clickEndShape = null; - this._fire(MOUSEUP, { + }); + + if (!triggeredOnShape) { + this._fire(events.pointerup, { evt: evt, target: this, currentTarget: this, - pointerId, + pointerId: this._changedPointerPositions[0].id, }); - if (Konva.listenClickTap) { - this._fire(CLICK, { - evt: evt, - target: this, - currentTarget: this, - pointerId, - }); - } - - if (fireDblClick) { - this._fire(DBL_CLICK, { - evt: evt, - target: this, - currentTarget: this, - pointerId, - }); - } - } - // content events - this._fire(CONTENT_MOUSEUP, { evt: evt }); - if (Konva.listenClickTap) { - this._fire(CONTENT_CLICK, { evt: evt }); - if (fireDblClick) { - this._fire(CONTENT_DBL_CLICK, { evt: evt }); - } } Konva.listenClickTap = false; @@ -654,190 +775,6 @@ export class Stage extends Container { currentTarget: this, }); } - this._fire(CONTENT_CONTEXTMENU, { evt: evt }); - } - _touchstart(evt) { - this.setPointersPositions(evt); - var triggeredOnShape = false; - this._changedPointerPositions.forEach((pos) => { - var shape = this.getIntersection(pos) as Shape; - Konva.listenClickTap = true; - DD.justDragged = false; - const hasShape = shape && shape.isListening(); - - if (!hasShape) { - return; - } - - if (Konva.captureTouchEventsEnabled) { - shape.setPointerCapture(pos.id); - } - - this.tapStartShape = shape; - shape._fireAndBubble(TOUCHSTART, { evt: evt, pointerId: pos.id }, this); - triggeredOnShape = true; - // only call preventDefault if the shape is listening for events - if (shape.isListening() && shape.preventDefault() && evt.cancelable) { - evt.preventDefault(); - } - }); - - if (!triggeredOnShape) { - this._fire(TOUCHSTART, { - evt: evt, - target: this, - currentTarget: this, - pointerId: this._changedPointerPositions[0].id, - }); - } - - // content event - this._fire(CONTENT_TOUCHSTART, { evt: evt }); - } - _touchmove(evt) { - this.setPointersPositions(evt); - var eventsEnabled = !DD.isDragging || Konva.hitOnDragEnabled; - if (eventsEnabled) { - var triggeredOnShape = false; - var processedShapesIds = {}; - this._changedPointerPositions.forEach((pos) => { - const shape = - PointerEvents.getCapturedShape(pos.id) || this.getIntersection(pos); - - const hasShape = shape && shape.isListening(); - if (!hasShape) { - return; - } - if (processedShapesIds[shape._id]) { - return; - } - processedShapesIds[shape._id] = true; - shape._fireAndBubble(TOUCHMOVE, { evt: evt, pointerId: pos.id }); - triggeredOnShape = true; - // only call preventDefault if the shape is listening for events - if (shape.isListening() && shape.preventDefault() && evt.cancelable) { - evt.preventDefault(); - } - }); - - if (!triggeredOnShape) { - this._fire(TOUCHMOVE, { - evt: evt, - target: this, - currentTarget: this, - pointerId: this._changedPointerPositions[0].id, - }); - } - - this._fire(CONTENT_TOUCHMOVE, { evt: evt }); - } - if (DD.isDragging && DD.node.preventDefault() && evt.cancelable) { - evt.preventDefault(); - } - } - _touchend(evt) { - this.setPointersPositions(evt); - - var tapEndShape = this.tapEndShape, - fireDblClick = false; - - if (Konva.inDblClickWindow) { - fireDblClick = true; - clearTimeout(this.dblTimeout); - // Konva.inDblClickWindow = false; - } else if (!DD.justDragged) { - Konva.inDblClickWindow = true; - clearTimeout(this.dblTimeout); - } - - this.dblTimeout = setTimeout(function () { - Konva.inDblClickWindow = false; - }, Konva.dblClickWindow); - - var triggeredOnShape = false; - var processedShapesIds = {}; - var tapTriggered = false; - var dblTapTriggered = false; - - this._changedPointerPositions.forEach((pos) => { - var shape = - (PointerEvents.getCapturedShape(pos.id) as Shape) || - (this.getIntersection(pos) as Shape); - - if (shape) { - shape.releaseCapture(pos.id); - } - - const hasShape = shape && shape.isListening(); - if (!hasShape) { - return; - } - if (processedShapesIds[shape._id]) { - return; - } - processedShapesIds[shape._id] = true; - - this.tapEndShape = shape; - shape._fireAndBubble(TOUCHEND, { evt: evt, pointerId: pos.id }); - triggeredOnShape = true; - - // detect if tap or double tap occurred - if (Konva.listenClickTap && shape === this.tapStartShape) { - tapTriggered = true; - shape._fireAndBubble(TAP, { evt: evt, pointerId: pos.id }); - - if (fireDblClick && tapEndShape && tapEndShape === shape) { - dblTapTriggered = true; - shape._fireAndBubble(DBL_TAP, { evt: evt, pointerId: pos.id }); - } - } - - // only call preventDefault if the shape is listening for events - if (shape.isListening() && shape.preventDefault() && evt.cancelable) { - evt.preventDefault(); - } - }); - - if (!triggeredOnShape) { - this._fire(TOUCHEND, { - evt: evt, - target: this, - currentTarget: this, - pointerId: this._changedPointerPositions[0].id, - }); - } - - if (Konva.listenClickTap && !tapTriggered) { - this.tapEndShape = null; - this._fire(TAP, { - evt: evt, - target: this, - currentTarget: this, - pointerId: this._changedPointerPositions[0].id, - }); - } - if (fireDblClick && !dblTapTriggered) { - this._fire(DBL_TAP, { - evt: evt, - target: this, - currentTarget: this, - pointerId: this._changedPointerPositions[0].id, - }); - } - // content events - this._fire(CONTENT_TOUCHEND, { evt: evt }); - if (Konva.listenClickTap) { - this._fire(CONTENT_TAP, { evt: evt }); - if (fireDblClick) { - this._fire(CONTENT_DBL_TAP, { evt: evt }); - } - } - - if (this.preventDefault() && evt.cancelable) { - evt.preventDefault(); - } - - Konva.listenClickTap = false; } _wheel(evt) { @@ -853,59 +790,9 @@ export class Stage extends Container { currentTarget: this, }); } - this._fire(CONTENT_WHEEL, { evt: evt }); - } - - _pointerdown(evt: PointerEvent) { - if (!Konva._pointerEventsEnabled) { - return; - } - this.setPointersPositions(evt); - - const shape = - PointerEvents.getCapturedShape(evt.pointerId) || - this.getIntersection(this.getPointerPosition()); - - if (shape) { - shape._fireAndBubble(POINTERDOWN, PointerEvents.createEvent(evt)); - } - } - - _pointermove(evt: PointerEvent) { - if (!Konva._pointerEventsEnabled) { - return; - } - this.setPointersPositions(evt); - - const shape = - PointerEvents.getCapturedShape(evt.pointerId) || - this.getIntersection(this.getPointerPosition()); - - if (shape) { - shape._fireAndBubble(POINTERMOVE, PointerEvents.createEvent(evt)); - } - } - - _pointerup(evt: PointerEvent) { - if (!Konva._pointerEventsEnabled) { - return; - } - this.setPointersPositions(evt); - const shape = - PointerEvents.getCapturedShape(evt.pointerId) || - this.getIntersection(this.getPointerPosition()); - - if (shape) { - shape._fireAndBubble(POINTERUP, PointerEvents.createEvent(evt)); - } - - PointerEvents.releaseCapture(evt.pointerId); } _pointercancel(evt: PointerEvent) { - if (!Konva._pointerEventsEnabled) { - return; - } this.setPointersPositions(evt); const shape = PointerEvents.getCapturedShape(evt.pointerId) || diff --git a/src/index-types.d.ts b/src/index-types.d.ts index dae8b52c..10628eb9 100644 --- a/src/index-types.d.ts +++ b/src/index-types.d.ts @@ -33,7 +33,7 @@ declare namespace Konva { export let dragDistance: number; export let angleDeg: boolean; export let showWarnings: boolean; - export let captureTouchEventsEnabled: boolean; + export let capturePointerEventsEnabled: boolean; export let dragButtons: Array; export let hitOnDragEnabled: boolean; export const isDragging: () => boolean; diff --git a/test/unit/Layer-test.ts b/test/unit/Layer-test.ts index 07eb5fd4..b0891d56 100644 --- a/test/unit/Layer-test.ts +++ b/test/unit/Layer-test.ts @@ -243,56 +243,6 @@ describe('Layer', function () { ); }); - // ====================================================== - it('layer getIntersection() with selector', function () { - var stage = addStage(); - var layer = new Konva.Layer({ - name: 'layer', - }); - - var group = new Konva.Group({ - name: 'group', - }); - - var circle = new Konva.Circle({ - x: stage.width() / 2, - y: stage.height() / 2, - radius: 70, - strokeWidth: 4, - fill: 'red', - stroke: 'black', - }); - - group.add(circle); - layer.add(group); - stage.add(layer); - - assert.equal( - layer.getIntersection( - { x: stage.width() / 2, y: stage.height() / 2 }, - 'Circle' - ), - circle, - 'intersection with shape selector' - ); - assert.equal( - layer.getIntersection( - { x: stage.width() / 2, y: stage.height() / 2 }, - '.group' - ), - group, - 'intersection with group selector' - ); - assert.equal( - layer.getIntersection( - { x: stage.width() / 2, y: stage.height() / 2 }, - 'Stage' - ), - stage, - 'intersection with stage selector' - ); - }); - // ====================================================== it('set layer visibility', function () { var stage = addStage(); diff --git a/test/unit/MouseEvents-test.ts b/test/unit/MouseEvents-test.ts index 0bad634d..a9b1cfce 100644 --- a/test/unit/MouseEvents-test.ts +++ b/test/unit/MouseEvents-test.ts @@ -12,139 +12,6 @@ import { } from './test-utils'; describe('MouseEvents', function () { - // ====================================================== - it('stage content mouse events', function (done) { - var stage = addStage(); - var layer = new Konva.Layer(); - var circle = new Konva.Circle({ - x: 100, - y: 100, - radius: 70, - fill: 'green', - stroke: 'black', - strokeWidth: 4, - name: 'myCircle', - }); - - layer.add(circle); - stage.add(layer); - - var circleMousedown = 0; - var circleMouseup = 0; - var stageContentMousedown = 0; - var stageContentMouseup = 0; - var stageContentMousemove = 0; - var stageContentMouseout = 0; - var stageContentMouseover = 0; - var stageContentClick = 0; - var stageContentDblClick = 0; - - circle.on('mousedown', function () { - circleMousedown++; - }); - - circle.on('mouseup', function () { - circleMouseup++; - }); - - stage.on('contentMousedown', function () { - stageContentMousedown++; - }); - - stage.on('contentMouseup', function () { - stageContentMouseup++; - }); - - stage.on('contentMousemove', function () { - stageContentMousemove++; - }); - - stage.on('contentMouseout', function () { - stageContentMouseout++; - }); - - stage.on('contentMouseover', function () { - stageContentMouseover++; - }); - - stage.on('contentClick', function () { - //console.log('click'); - stageContentClick++; - }); - - stage.on('contentDblclick', function () { - //console.log('dbl click'); - stageContentDblClick++; - }); - - simulateMouseDown(stage, { - x: 100, - y: 100, - }); - - simulateMouseUp(stage, { - x: 100, - y: 100, - }); - - assert.equal(circleMousedown, 1); - assert.equal(circleMouseup, 1); - assert.equal(stageContentMousedown, 1); - assert.equal(stageContentMouseup, 1); - assert.equal(stageContentClick, 1); - - simulateMouseDown(stage, { - x: 1, - y: 1, - }); - simulateMouseUp(stage, { - x: 1, - y: 1, - }); - - assert.equal(stageContentMousedown, 2); - assert.equal(stageContentMouseup, 2); - - // trigger double click - simulateMouseDown(stage, { - x: 1, - y: 1, - }); - simulateMouseUp(stage, { - x: 1, - y: 1, - }); - - assert.equal(stageContentMousedown, 3); - assert.equal(stageContentMouseup, 3); - //assert.equal(stageContentDblClick, 1); - - setTimeout(function () { - simulateMouseMove(stage, { - x: 200, - y: 1, - }); - - assert.equal(stageContentMousemove, 1); - - stage._mouseleave({ - offsetX: 0, - offsetY: 0, - }); - - assert.equal(stageContentMouseout, 1); - - stage._mouseover({ - offsetX: 0, - offsetY: 0, - }); - - assert.equal(stageContentMouseover, 1); - - done(); - }, 20); - }); - // ====================================================== it('remove shape with onclick', function () { var stage = addStage(); @@ -443,6 +310,54 @@ describe('MouseEvents', function () { }, 20); }); + it.skip('mouseleave and mouseenter', function () { + var stage = addStage(); + var layer = new Konva.Layer({ + throttle: 999, + }); + var circle = new Konva.Circle({ + x: 100, + y: 100, + radius: 70, + strokeWidth: 4, + fill: 'red', + stroke: 'black', + }); + layer.add(circle); + stage.add(layer); + + var mouseenter = 0; + circle.on('mouseenter', () => { + mouseenter += 1; + }); + + var mouseleave = 0; + circle.on('mouseleave', () => { + mouseleave += 1; + }); + + simulateMouseMove(stage, { + x: 10, + y: 10, + }); + simulateMouseMove(stage, { + x: 100, + y: 100, + }); + simulateMouseMove(stage, { + x: 100, + y: 100, + }); + assert.equal(mouseenter, 1); + assert.equal(mouseleave, 0); + simulateMouseMove(stage, { + x: 10, + y: 10, + }); + assert.equal(mouseenter, 1); + assert.equal(mouseleave, 1); + }); + // ====================================================== it('mousedown mouseup mouseover mouseout mousemove click dblclick', function (done) { var stage = addStage(); @@ -2045,7 +1960,7 @@ describe('MouseEvents', function () { y: 15, }); - assert.equal(bigClicks, 0, 'single click on big rect'); + assert.equal(bigClicks, 0, 'single click on big rect (1)'); assert.equal(smallClicks, 0, 'no click on small rect'); assert.equal(smallDblClicks, 0, 'no dblclick on small rect'); @@ -2059,7 +1974,7 @@ describe('MouseEvents', function () { y: 100, }); - assert.equal(bigClicks, 0, 'single click on big rect'); + assert.equal(bigClicks, 0, 'single click on big rect (2)'); assert.equal(smallClicks, 1, 'single click on small rect'); assert.equal(smallDblClicks, 0, 'no dblclick on small rect'); @@ -2073,7 +1988,7 @@ describe('MouseEvents', function () { y: 100, }); - assert.equal(bigClicks, 0, 'single click on big rect'); + assert.equal(bigClicks, 0, 'single click on big rect (3)'); assert.equal(smallClicks, 2, 'second click on small rect'); assert.equal(smallDblClicks, 1, 'single dblclick on small rect'); @@ -2097,9 +2012,10 @@ describe('MouseEvents', function () { clientX: 10, clientY: 10 + top, button: 0, + type: 'mouseenter', }; - stage._mouseenter(evt); + stage._pointerenter(evt); assert.equal(mouseenterCount, 1, 'mouseenterCount should be 1'); }); @@ -2119,9 +2035,10 @@ describe('MouseEvents', function () { clientX: 0, clientY: 0 + top, button: 0, + type: 'mouseleave', }; - stage._mouseleave(evt); + stage._pointerleave(evt); assert.equal(mouseleave, 1, 'mouseleave should be 1'); }); @@ -2178,9 +2095,10 @@ describe('MouseEvents', function () { clientX: 200, clientY: -5 + top, button: 0, + type: 'mouseleave', }; - stage._mouseleave(evt); + stage._pointerleave(evt); assert.equal(circleMouseleave, 1, 'circleMouseleave should be 1'); assert.equal(circleMouseout, 1, 'circleMouseout should be 1'); @@ -2294,16 +2212,20 @@ describe('MouseEvents', function () { clientX: 10, clientY: 10 + top, button: 0, + type: 'mouseenter', }; - stage._mouseenter(evt); + stage._pointerenter(evt); simulateMouseMove(stage, { x: 10, y: 10, }); - stage._mouseleave(evt); + stage._pointerleave({ + ...evt, + type: 'mouseleave', + }); assert.equal(mouseenter, 1, 'mouseenter should be 1'); }); diff --git a/test/unit/PointerEvents-test.ts b/test/unit/PointerEvents-test.ts index ae9e2e14..f2d36095 100644 --- a/test/unit/PointerEvents-test.ts +++ b/test/unit/PointerEvents-test.ts @@ -8,9 +8,7 @@ import { simulatePointerUp, } from './test-utils'; -// TODO: restore it! describe.skip('PointerEvents', function () { - Konva._pointerEventsEnabled = true; // ====================================================== it('pointerdown pointerup pointermove', function (done) { var stage = addStage(); @@ -51,8 +49,6 @@ describe.skip('PointerEvents', function () { simulatePointerDown(stage, { x: 289, y: 100, - pointerId: 1, - preventDefault: function () {}, }); assert(pointerdown, '1) pointerdown should be true'); @@ -61,8 +57,8 @@ describe.skip('PointerEvents', function () { // pointerup circle simulatePointerUp(stage, { - touches: [], - preventDefault: function () {}, + x: 289, + y: 100, }); assert(pointerdown, '2) pointerdown should be true'); @@ -71,13 +67,8 @@ describe.skip('PointerEvents', function () { // pointerdown circle simulatePointerDown(stage, { - touches: [ - { - x: 289, - y: 100, - }, - ], - preventDefault: function () {}, + x: 289, + y: 100, }); assert(pointerdown, '3) pointerdown should be true'); @@ -86,8 +77,8 @@ describe.skip('PointerEvents', function () { // pointerup circle to triger dbltap simulatePointerUp(stage, { - touches: [], - preventDefault: function () {}, + x: 289, + y: 100, }); // end drag is tied to document mouseup and pointerup event // which can't be simulated. call _endDrag manually @@ -100,13 +91,8 @@ describe.skip('PointerEvents', function () { setTimeout(function () { // pointermove circle simulatePointerMove(stage, { - touches: [ - { - x: 290, - y: 100, - }, - ], - preventDefault: function () {}, + x: 290, + y: 100, }); assert(pointerdown, '5) pointerdown should be true'); @@ -118,7 +104,7 @@ describe.skip('PointerEvents', function () { }); // ====================================================== - it('pointer capture', function (done) { + it.skip('pointer capture', function (done) { var stage = addStage(); var layer = new Konva.Layer(); var circle = new Konva.Circle({ @@ -172,17 +158,15 @@ describe.skip('PointerEvents', function () { layer.add(circle2); stage.add(layer); - var top = stage.content.getBoundingClientRect().top; - // on circle 2 to confirm it works simulatePointerDown(stage, { x: 289, - y: 10 + top, + y: 10, pointerId: 0, preventDefault: function () {}, }); - assert(otherDownCount === 1, '6) otherDownCount should be 1'); + assert.equal(otherDownCount, 1, '6) otherDownCount should be 1'); assert(downCount === 0, '6) downCount should be 0'); assert(!pointermove, '6) pointermove should be false'); assert(!pointerup, '6) pointerup should be false'); @@ -190,12 +174,12 @@ describe.skip('PointerEvents', function () { // on circle with capture simulatePointerDown(stage, { x: 289, - y: 100 + top, + y: 100, pointerId: 1, preventDefault: function () {}, }); - assert(otherDownCount === 1, '7) otherDownCount should be 1'); + assert.equal(otherDownCount, 1, '7) otherDownCount should be 1'); assert(downCount === 1, '7) downCount should be 1'); assert(!pointermove, '7) pointermove should be false'); assert(!pointerup, '7) pointerup should be true'); @@ -203,12 +187,12 @@ describe.skip('PointerEvents', function () { // second pointerdown simulatePointerDown(stage, { x: 289, - y: 10 + top, - pointerId: 1, + y: 10, + pointerId: 2, preventDefault: function () {}, }); - assert(otherDownCount === 1, '8) otherDownCount should be 1'); + assert.equal(otherDownCount, 1, '8) otherDownCount should be 1'); assert(downCount === 2, '8) pointerdown should be 2'); assert(!pointermove, '8) pointermove should be false'); assert(!pointerup, '8) pointerup should be true'); @@ -217,9 +201,8 @@ describe.skip('PointerEvents', function () { // pointermove over circle 2 simulatePointerMove(stage, { x: 290, - y: 10 + top, + y: 10, pointerId: 1, - preventDefault: function () {}, }); assert(otherDownCount === 1, '9) otherDownCount should be 1'); @@ -232,7 +215,7 @@ describe.skip('PointerEvents', function () { simulatePointerDown(stage, { x: 289, - y: 10 + top, + y: 10, pointerId: 1, preventDefault: function () {}, }); diff --git a/test/unit/Stage-test.ts b/test/unit/Stage-test.ts index 54f41e44..2c29569d 100644 --- a/test/unit/Stage-test.ts +++ b/test/unit/Stage-test.ts @@ -309,56 +309,6 @@ describe('Stage', function () { ); }); - // ====================================================== - it('layer getIntersection() with selector', function () { - var stage = addStage(); - var layer = new Konva.Layer({ - name: 'layer', - }); - - var group = new Konva.Group({ - name: 'group', - }); - - var circle = new Konva.Circle({ - x: stage.width() / 2, - y: stage.height() / 2, - radius: 70, - strokeWidth: 4, - fill: 'red', - stroke: 'black', - }); - - group.add(circle); - layer.add(group); - stage.add(layer); - - assert.equal( - stage.getIntersection( - { x: stage.width() / 2, y: stage.height() / 2 }, - 'Circle' - ), - circle, - 'intersection with shape selector' - ); - assert.equal( - stage.getIntersection( - { x: stage.width() / 2, y: stage.height() / 2 }, - '.group' - ), - group, - 'intersection with group selector' - ); - assert.equal( - stage.getIntersection( - { x: stage.width() / 2, y: stage.height() / 2 }, - 'Stage' - ), - stage, - 'intersection with stage selector' - ); - }); - // ====================================================== it('stage getIntersection() edge detection', function () { var stage = addStage(); @@ -1190,9 +1140,10 @@ describe('Stage', function () { } }); - stage._mouseover({ + stage._pointerover({ clientX: 0, clientY: 0, + type: 'mouseover', }); assert.equal(mouseover, 1, 'initial over'); @@ -1267,7 +1218,7 @@ describe('Stage', function () { stage.on('mouseout', function () { count += 1; }); - stage._mouseleave({}); + stage._pointerleave({ type: 'mouseleave' }); assert.equal(count, 2); }); diff --git a/test/unit/TouchEvents-test.ts b/test/unit/TouchEvents-test.ts index 85aa0f74..dc2dfcbc 100644 --- a/test/unit/TouchEvents-test.ts +++ b/test/unit/TouchEvents-test.ts @@ -9,77 +9,6 @@ import { } from './test-utils'; describe('TouchEvents', function () { - // ====================================================== - it('stage content touch events', function () { - var stage = addStage(); - var layer = new Konva.Layer(); - var circle = new Konva.Circle({ - x: 100, - y: 100, - radius: 70, - fill: 'green', - stroke: 'black', - strokeWidth: 4, - name: 'myCircle', - }); - - layer.add(circle); - stage.add(layer); - - var circleTouchstart = 0; - var circleTouchend = 0; - var stageContentTouchstart = 0; - var stageContentTouchend = 0; - var stageContentTouchmove = 0; - var stageContentTap = 0; - var stageContentDbltap = 0; - - circle.on('touchstart', function () { - circleTouchstart++; - }); - - circle.on('touchend', function () { - circleTouchend++; - }); - - stage.on('contentTouchstart', function () { - stageContentTouchstart++; - }); - - stage.on('contentTouchend', function () { - stageContentTouchend++; - }); - - stage.on('contentTouchmove', function () { - stageContentTouchmove++; - }); - - stage.on('contentTap', function () { - stageContentTap++; - }); - - stage.on('contentDbltap', function () { - stageContentDbltap++; - }); - - simulateTouchStart(stage, [{ x: 100, y: 100, id: 0 }]); - - simulateTouchEnd(stage, [], [{ x: 100, y: 100, id: 0 }]); - assert.equal(circleTouchstart, 1, '1'); - assert.equal(circleTouchend, 1, '2'); - assert.equal(stageContentTouchstart, 1, '3'); - assert.equal(stageContentTouchend, 1, '4'); - assert.equal(stageContentDbltap, 0, '5'); - - simulateTouchStart(stage, [{ x: 1, y: 1, id: 0 }]); - - simulateTouchEnd(stage, [], [{ x: 1, y: 1, id: 0 }]); - - assert.equal(stageContentTouchstart, 2, '6'); - assert.equal(stageContentTouchend, 2, '7'); - assert.equal(stageContentDbltap, 1, '8'); - }); - // ====================================================== it('touchstart touchend touchmove tap dbltap', function (done) { var stage = addStage(); @@ -282,26 +211,14 @@ describe('TouchEvents', function () { stage.add(layer); var circleTouchend = 0; - var stageContentTouchstart = 0; - var stageContentTouchend = 0; circle.on('touchend', function () { circleTouchend++; }); - stage.on('contentTouchstart', function () { - stageContentTouchstart++; - }); - - stage.on('contentTouchend', function () { - stageContentTouchend++; - }); - simulateTouchStart(stage, [{ x: 1, y: 1, id: 0 }]); simulateTouchEnd(stage, [], [{ x: 100, y: 100, id: 0 }]); - assert.equal(stageContentTouchstart, 1); - assert.equal(stageContentTouchend, 1); assert.equal(circleTouchend, 1); }); @@ -554,7 +471,7 @@ describe('TouchEvents', function () { }); it('can capture touch events', function () { - Konva.captureTouchEventsEnabled = true; + Konva.capturePointerEventsEnabled = true; var stage = addStage(); var layer = new Konva.Layer(); stage.add(layer); @@ -641,7 +558,7 @@ describe('TouchEvents', function () { assert.equal(circle1.hasPointerCapture(0), false); assert.equal(circle1.hasPointerCapture(1), false); - Konva.captureTouchEventsEnabled = false; + Konva.capturePointerEventsEnabled = false; }); it('tap and double tap should trigger just once on stage', function () { diff --git a/test/unit/test-utils.ts b/test/unit/test-utils.ts index 4f5aaf07..89614acf 100644 --- a/test/unit/test-utils.ts +++ b/test/unit/test-utils.ts @@ -24,7 +24,9 @@ afterEach(function () { var isManual = this.currentTest.parent.title === 'Manual'; Konva.stages.forEach(function (stage) { - clearTimeout(stage.dblTimeout); + clearTimeout(stage._mouseDblTimeout); + clearTimeout(stage._touchDblTimeout); + clearTimeout(stage._pointerDblTimeout); }); if (!isFailed && !isManual) { @@ -177,37 +179,43 @@ export function showHit(layer) { } export function simulateMouseDown(stage, pos) { + // simulatePointerDown(stage, pos); var top = isNode ? 0 : stage.content.getBoundingClientRect().top; - stage._mousedown({ + stage._pointerdown({ clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, + type: 'mousedown', }); } export function simulateMouseMove(stage, pos) { + // simulatePointerMove(stage, pos); var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var evt = { clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, + type: 'mousemove', }; - stage._mousemove(evt); + stage._pointermove(evt); Konva.DD._drag(evt); } export function simulateMouseUp(stage, pos) { + // simulatePointerUp(stage, pos); var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var evt = { clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, + type: 'mouseup', }; Konva.DD._endDragBefore(evt); - stage._mouseup(evt); + stage._pointerup(evt); Konva.DD._endDragAfter(evt); } @@ -242,9 +250,10 @@ export function simulateTouchStart(stage, pos, changed?) { var evt = { touches: touches, changedTouches: changedTouches, + type: 'touchstart', }; - stage._touchstart(evt); + stage._pointerdown(evt); } export function simulateTouchMove(stage, pos, changed?) { @@ -278,9 +287,10 @@ export function simulateTouchMove(stage, pos, changed?) { var evt = { touches: touches, changedTouches: changedTouches, + type: 'touchmove', }; - stage._touchmove(evt); + stage._pointermove(evt); Konva.DD._drag(evt); } @@ -315,10 +325,11 @@ export function simulateTouchEnd(stage, pos, changed?) { var evt = { touches: touches, changedTouches: changedTouches, + type: 'touchend', }; Konva.DD._endDragBefore(evt); - stage._touchend(evt); + stage._pointerup(evt); Konva.DD._endDragAfter(evt); } @@ -329,6 +340,7 @@ export function simulatePointerDown(stage: Stage, pos) { clientY: pos.y + top, button: pos.button || 0, pointerId: pos.pointerId || 1, + type: 'pointerdown', } as any); } @@ -339,6 +351,7 @@ export function simulatePointerMove(stage: Stage, pos) { clientY: pos.y + top, button: pos.button || 0, pointerId: pos.pointerId || 1, + type: 'pointermove', }; stage._pointermove(evt as any); @@ -346,13 +359,13 @@ export function simulatePointerMove(stage: Stage, pos) { } export function simulatePointerUp(stage: Stage, pos) { - debugger; var top = isNode ? 0 : stage.content.getBoundingClientRect().top; var evt = { clientX: pos.x, clientY: pos.y + top, button: pos.button || 0, pointerId: pos.pointerId || 1, + type: 'pointerup', }; Konva.DD._endDragBefore(evt);