Skip to content

Commit

Permalink
feat: add a minDistance configuration option
Browse files Browse the repository at this point in the history
This change makes it possible to configure a minimum distance that is used as a threshold to determine whether to begin a pan or zoom operation when triggered via pointer events.

This option can help in situations when small movements during a click/tap cause the element to move slightly which is a little off putting.
  • Loading branch information
mattnathan committed Jun 17, 2020
1 parent 5e05ea1 commit e3dc402
Showing 1 changed file with 30 additions and 14 deletions.
44 changes: 30 additions & 14 deletions src/panzoom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const defaultOptions: PanzoomOptions = {
e.stopPropagation()
},
maxScale: 4,
minDistance: 0,
minScale: 0.125,
overflow: 'hidden',
panOnlyWhenZoomed: false,
Expand Down Expand Up @@ -121,6 +122,7 @@ function Panzoom(
let x = 0
let y = 0
let scale = 1
let isWatching = false
let isPanning = false
zoom(options.startScale, { animate: false })
// Wait for scale to update
Expand Down Expand Up @@ -407,13 +409,11 @@ function Panzoom(
return
}
addPointer(pointers, event)
isPanning = true
isWatching = true
options.handleStartEvent(event)
origX = x
origY = y

trigger('panzoomstart', { x, y, scale }, options)

// This works whether there are multiple
// pointers or not
const point = getMiddle(pointers)
Expand All @@ -425,7 +425,7 @@ function Panzoom(

function move(event: PointerEvent) {
if (
!isPanning ||
!isWatching ||
origX === undefined ||
origY === undefined ||
startClientX === undefined ||
Expand All @@ -435,21 +435,36 @@ function Panzoom(
}
addPointer(pointers, event)
const current = getMiddle(pointers)
let scaleDiff = 0
if (pointers.length > 1) {
// Use the distance between the first 2 pointers
// to determine the current scale
const diff = getDistance(pointers) - startDistance
const toScale = constrainScale((diff * options.step) / 80 + startScale).scale
zoomToPoint(toScale, current)
scaleDiff = getDistance(pointers) - startDistance
}

if (!isPanning) {
// have we moved far enough to trigger panning/zooming
const panDiff = Math.hypot(current.clientX - startClientX, current.clientY - startClientY)
if (Math.abs(scaleDiff) > options.minDistance || panDiff > options.minDistance) {
trigger('panzoomstart', { origX, origY, startScale }, options)
isPanning = true
}
}

pan(
origX + (current.clientX - startClientX) / scale,
origY + (current.clientY - startClientY) / scale,
{
animate: false
if (isPanning) {
if (pointers.length > 1) {
const toScale = constrainScale((scaleDiff * options.step) / 80 + startScale).scale
zoomToPoint(toScale, current)
}
)

pan(
origX + (current.clientX - startClientX) / scale,
origY + (current.clientY - startClientY) / scale,
{
animate: false
}
)
}
}

function handleUp(event: PointerEvent) {
Expand All @@ -462,9 +477,10 @@ function Panzoom(
// Can restart without having to reinitiate all of them
// Remove the pointer regardless of the isPanning state
removePointer(pointers, event)
if (!isPanning) {
if (!isWatching) {
return
}
isWatching = false
isPanning = false
origX = origY = startClientX = startClientY = undefined
}
Expand Down

0 comments on commit e3dc402

Please sign in to comment.