import "./index.d" import "tocca" // Pointer Events // -------------- // Thanks to https://github.com/mpizenberg/elm-pep/ let enteredElement tocca({ dbltapThreshold: 400, tapThreshold: 250 }) function mousePointerEvent(eventType, mouseEvent) { const pointerEvent: any = new MouseEvent(eventType, mouseEvent) pointerEvent.pointerId = 1 pointerEvent.isPrimary = true pointerEvent.pointerType = "mouse" pointerEvent.width = 1 pointerEvent.height = 1 pointerEvent.tiltX = 0 pointerEvent.tiltY = 0 "buttons" in mouseEvent && mouseEvent.buttons !== 0 ? (pointerEvent.pressure = 0.5) : (pointerEvent.pressure = 0) return pointerEvent } function touchPointerEvent(eventType, touchEvent, touch) { const pointerEvent: any = new CustomEvent(eventType, { bubbles: true, cancelable: true }) pointerEvent.ctrlKey = touchEvent.ctrlKey pointerEvent.shiftKey = touchEvent.shiftKey pointerEvent.altKey = touchEvent.altKey pointerEvent.metaKey = touchEvent.metaKey pointerEvent.clientX = touch.clientX pointerEvent.clientY = touch.clientY pointerEvent.screenX = touch.screenX pointerEvent.screenY = touch.screenY pointerEvent.pageX = touch.pageX pointerEvent.pageY = touch.pageY const rect = touch.target.getBoundingClientRect() pointerEvent.offsetX = touch.clientX - rect.left pointerEvent.offsetY = touch.clientY - rect.top pointerEvent.pointerId = 1 + touch.identifier pointerEvent.button = 0 pointerEvent.buttons = 1 pointerEvent.movementX = 0 pointerEvent.movementY = 0 pointerEvent.region = null pointerEvent.relatedTarget = null pointerEvent.x = pointerEvent.clientX pointerEvent.y = pointerEvent.clientY pointerEvent.pointerType = "touch" pointerEvent.width = 1 pointerEvent.height = 1 pointerEvent.tiltX = 0 pointerEvent.tiltY = 0 pointerEvent.pressure = 1 pointerEvent.isPrimary = true return pointerEvent } // Simulate `pointerenter` and `pointerleave` event for non-touch devices if (!self.PointerEvent) { document.addEventListener("mouseover", event => { const section = document.body.querySelector("section") const isDragging = section && section.classList.contains("dragging-something") const node = isDragging && document.elementFromPoint(event.clientX, event.clientY) if (node && node != enteredElement) { enteredElement && enteredElement.dispatchEvent(mousePointerEvent("pointerleave", event)) node.dispatchEvent(mousePointerEvent("pointerenter", event)) enteredElement = node } }) } // Simulate `pointerenter` and `pointerleave` event for touch devices document.body.addEventListener("touchmove", event => { const section = document.body.querySelector("section") const isDragging = section && section.classList.contains("dragging-something") const touch = event.touches[0] let node if (isDragging && touch) { node = document.elementFromPoint(touch.clientX, touch.clientY) } if (node && node != enteredElement) { enteredElement && enteredElement.dispatchEvent(touchPointerEvent("pointerleave", event, touch)) node.dispatchEvent(touchPointerEvent("pointerenter", event, touch)) enteredElement = node } if (isDragging) { event.stopPropagation() } })