Skip to content

Commit

Permalink
fix(events): fallback to touch and mouse events (#399)
Browse files Browse the repository at this point in the history
  • Loading branch information
timmywil authored Aug 12, 2019
1 parent 2d7cd00 commit 2c4c303
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 21 deletions.
33 changes: 33 additions & 0 deletions src/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
let events: { down: string; move: string; up: string }
if (typeof (window as any).PointerEvent === 'function') {
events = {
down: 'pointerdown',
move: 'pointermove',
up: 'pointerup pointerleave pointercancel'
}
} else if (typeof (window as any).TouchEvent === 'function') {
events = {
down: 'touchstart',
move: 'touchmove',
up: 'touchend touchcancel'
}
} else {
events = {
down: 'mousedown',
move: 'mousemove',
up: 'mouseup mouseleave'
}
}

export function onPointer(
event: 'down' | 'move' | 'up',
elem: HTMLElement | SVGElement | Document,
handler: (event: PointerEvent) => void,
eventOpts?: any
) {
events[event].split(' ').forEach((name) => {
;(elem as HTMLElement).addEventListener<
'pointerdown' | 'pointermove' | 'pointerup' | 'pointerleave' | 'pointercancel'
>(name as any, handler, eventOpts)
})
}
29 changes: 11 additions & 18 deletions src/panzoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@
*
*/
import { getDimensions, setStyle, setTransform } from './css'
import { onPointer } from './events'
import isAttached from './isAttached'
import isSVGElement from './isSVGElement'
import { addEvent, getDistance, getMiddle, removeEvent } from './pointers'
import { addPointer, getDistance, getMiddle, removePointer } from './pointers'
import './polyfills'
import shallowClone from './shallowClone'
import { PanOptions, PanzoomObject, PanzoomOptions, ZoomOptions } from './types'
Expand Down Expand Up @@ -53,8 +54,6 @@ function Panzoom(elem: HTMLElement | SVGElement, options?: PanzoomOptions): Panz
}

const isSVG = isSVGElement(elem)
// SVG has pointer events, but TypeScript doesn't know that
const htmlElem = elem as HTMLElement

function setOptions(opts: PanzoomOptions = {}) {
for (const key in opts) {
Expand Down Expand Up @@ -339,10 +338,7 @@ function Panzoom(elem: HTMLElement | SVGElement, options?: PanzoomOptions): Panz
if (event.target && (event.target as Element).classList.contains(options.clickableClass)) {
return
}
addEvent(pointers, event)
if (event.pointerId) {
elem.setPointerCapture(event.pointerId)
}
addPointer(pointers, event)
isPanning = true
event.preventDefault()
event.stopPropagation()
Expand All @@ -361,7 +357,6 @@ function Panzoom(elem: HTMLElement | SVGElement, options?: PanzoomOptions): Panz
}

function move(event: PointerEvent) {
// console.log(elem, event.type, event.pointerId)
if (
!isPanning ||
origX === undefined ||
Expand All @@ -371,7 +366,7 @@ function Panzoom(elem: HTMLElement | SVGElement, options?: PanzoomOptions): Panz
) {
return
}
addEvent(pointers, event)
addPointer(pointers, event)
const current = getMiddle(pointers)
if (pointers.length > 1) {
// Use the distance between the first 2 pointers
Expand All @@ -391,26 +386,24 @@ function Panzoom(elem: HTMLElement | SVGElement, options?: PanzoomOptions): Panz
}

function handleUp(event: PointerEvent) {
if (!isPanning) {
return
}
// Only call panzoomend once
if (pointers.length === 1) {
trigger('panzoomend', { x, y, scale }, options)
}
// Note: don't remove all pointers
// Can restart without having to reinitiate all of them
removeEvent(pointers, event)
if (event.pointerId) {
elem.releasePointerCapture(event.pointerId)
}
removePointer(pointers, event)
isPanning = false
origX = origY = startClientX = startClientY = undefined
}

if (!options.disablePan) {
htmlElem.addEventListener('pointerdown', handleDown)
htmlElem.addEventListener('pointermove', move, { passive: true })
htmlElem.addEventListener('pointerup', handleUp, { passive: true })
htmlElem.addEventListener('pointerleave', handleUp, { passive: true })
htmlElem.addEventListener('pointercancel', handleUp, { passive: true })
onPointer('down', elem, handleDown)
onPointer('move', document, move, { passive: true })
onPointer('up', document, handleUp, { passive: true })
}

return {
Expand Down
24 changes: 21 additions & 3 deletions src/pointers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,34 @@ function findEventIndex(pointers: PointerEvent[], event: PointerEvent) {
return -1
}

export function addEvent(pointers: PointerEvent[], event: PointerEvent) {
const i = findEventIndex(pointers, event)
export function addPointer(pointers: PointerEvent[], event: PointerEvent) {
let i
// Add touches if applicable
if ((event as any).touches) {
i = 0
for (const touch of (event as any).touches) {
touch.pointerId = i++
addPointer(pointers, touch)
}
return
}
i = findEventIndex(pointers, event)
// Update if already present
if (i > -1) {
pointers.splice(i, 1)
}
pointers.push(event)
}

export function removeEvent(pointers: PointerEvent[], event: PointerEvent) {
export function removePointer(pointers: PointerEvent[], event: PointerEvent) {
// Add touches if applicable
if ((event as any).touches) {
// Remove all touches
while (pointers.length) {
pointers.pop()
}
return
}
const i = findEventIndex(pointers, event)
if (i > -1) {
pointers.splice(i, 1)
Expand Down

0 comments on commit 2c4c303

Please sign in to comment.