Skip to content

Commit

Permalink
Add support for preventing zoom on single touch ✨
Browse files Browse the repository at this point in the history
  • Loading branch information
willnguyen1312 committed Sep 16, 2024
1 parent cfd340a commit 5940d90
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 22 deletions.
5 changes: 5 additions & 0 deletions .changeset/weak-shoes-remember.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@zoom-image/core": minor
---

Add support for preventing zoom on single touch ✨
19 changes: 12 additions & 7 deletions packages/core/src/createZoomImageWheel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export type ZoomImageWheelOptions = {
wheelZoomRatio?: number
dblTapAnimationDuration?: number
initialState?: Partial<ZoomImageWheelStateUpdate>
shouldZoomOnSingleTouch?: () => boolean
}

/* The delta values are not consistent across browsers.
Expand Down Expand Up @@ -37,13 +38,16 @@ const defaultInitialState: ZoomImageWheelState = {
currentRotation: 0,
}

const noop = () => true

export function createZoomImageWheel(container: HTMLElement, options: ZoomImageWheelOptions = {}) {
const sourceImgElement = getSourceImage(container)
const finalOptions: Required<ZoomImageWheelOptions> = {
maxZoom: options.maxZoom || 4,
wheelZoomRatio: options.wheelZoomRatio || 0.1,
dblTapAnimationDuration: options.dblTapAnimationDuration || 300,
initialState: { ...defaultInitialState, ...options.initialState },
shouldZoomOnSingleTouch: options.shouldZoomOnSingleTouch || noop,
}

const store = createStore<ZoomImageWheelState>(finalOptions.initialState as ZoomImageWheelState)
Expand Down Expand Up @@ -204,14 +208,14 @@ export function createZoomImageWheel(container: HTMLElement, options: ZoomImageW
function _handlePointerMove(event: PointerEvent) {
event.preventDefault()
const { clientX, clientY, pointerId } = event
for (const [cachedPointerid] of pointerMap.entries()) {
if (cachedPointerid === pointerId) {
pointerMap.set(cachedPointerid, { x: clientX, y: clientY })
for (const [cachedPointerId] of pointerMap.entries()) {
if (cachedPointerId === pointerId) {
pointerMap.set(cachedPointerId, { x: clientX, y: clientY })
}
}

if (pointerMap.size === 1) {
const { currentZoom, currentRotation } = store.getState()
const { currentZoom, currentRotation } = store.getState()
if (pointerMap.size === 1 && currentZoom !== 1) {
const isDimensionSwitched = checkDimensionSwitched()
const normalizedClientX = isDimensionSwitched ? clientY : clientX
const normalizedClientY = isDimensionSwitched ? clientX : clientY
Expand Down Expand Up @@ -256,7 +260,6 @@ export function createZoomImageWheel(container: HTMLElement, options: ZoomImageW

function animateZoom(touchCoordinate: { x: number; y: number }) {
// the `touchCoordinate` should be relative to the container

const currentState = store.getState()

animationState.startTimestamp = null
Expand Down Expand Up @@ -338,8 +341,9 @@ export function createZoomImageWheel(container: HTMLElement, options: ZoomImageW
}

function _handleTouchMove(event: TouchEvent) {
event.preventDefault()
if (finalOptions.shouldZoomOnSingleTouch()) event.preventDefault()
if (event.touches.length === 2) {
event.preventDefault()
const currentTwoPositions = [...event.touches].map((t) => ({ x: t.clientX, y: t.clientY })) as [
PointerPosition,
PointerPosition,
Expand All @@ -357,6 +361,7 @@ export function createZoomImageWheel(container: HTMLElement, options: ZoomImageW
}

function _handlePointerDown(event: PointerEvent) {
if (event.pointerType === "touch" && !finalOptions.shouldZoomOnSingleTouch()) return
event.preventDefault()
if (pointerMap.size === 2) {
return
Expand Down
3 changes: 3 additions & 0 deletions packages/docs/src/api/createZoomImageWheel.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ type ZoomImageWheelOptions = {
// Partial or full initial state
// useful for storing previous zoomed state and re-initialize it on load
initialState?: Partial<ZoomImageWheelState>

// Predicate function to determine if zoom should be triggered on a single touch action
shouldZoomOnSingleTouch?: () => boolean
}

function createZoomImageWheel(
Expand Down
4 changes: 3 additions & 1 deletion packages/docs/src/components/HomePageShow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ watch(
}
if (zoomType.value === "wheel") {
createZoomImageWheel(imageWheelContainerRef.value as HTMLDivElement)
createZoomImageWheel(imageWheelContainerRef.value as HTMLDivElement, {
shouldZoomOnSingleTouch: () => false,
})
}
if (zoomType.value === "move") {
Expand Down
28 changes: 14 additions & 14 deletions size.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"@zoom-image/core": {
"createZoomImageWheel": "2.1 KB",
"createZoomImageWheel": "2.17 KB",
"createZoomImageHover": "1.28 KB",
"createZoomImageMove": "1 KB",
"createZoomImageClick": "943 B",
Expand All @@ -9,45 +9,45 @@
"makeCalculatePercentage": "153 B"
},
"@zoom-image/react": {
"useZoomImageWheel": "2.38 KB",
"useZoomImageWheel": "2.46 KB",
"useZoomImageHover": "1.56 KB",
"useZoomImageMove": "1.26 KB",
"useZoomImageClick": "1.18 KB"
},
"@zoom-image/preact": {
"useZoomImageWheel": "3.27 KB",
"useZoomImageWheel": "3.33 KB",
"useZoomImageHover": "2.46 KB",
"useZoomImageMove": "2.19 KB",
"useZoomImageClick": "2.11 KB"
},
"@zoom-image/qwik": {
"useZoomImageWheel": "2.52 KB",
"useZoomImageHover": "1.68 KB",
"useZoomImageMove": "1.38 KB",
"useZoomImageClick": "1.3 KB"
"useZoomImageWheel": "2.58 KB",
"useZoomImageHover": "1.67 KB",
"useZoomImageMove": "1.37 KB",
"useZoomImageClick": "1.29 KB"
},
"@zoom-image/solid": {
"useZoomImageWheel": "3.56 KB",
"useZoomImageWheel": "3.62 KB",
"useZoomImageHover": "2.75 KB",
"useZoomImageMove": "2.48 KB",
"useZoomImageClick": "2.4 KB"
},
"@zoom-image/svelte": {
"useZoomImageWheel": "2.57 KB",
"useZoomImageWheel": "2.63 KB",
"useZoomImageHover": "1.75 KB",
"useZoomImageMove": "1.48 KB",
"useZoomImageClick": "1.39 KB"
},
"@zoom-image/vue": {
"useZoomImageWheel": "2.36 KB",
"useZoomImageWheel": "2.42 KB",
"useZoomImageHover": "1.54 KB",
"useZoomImageMove": "1.25 KB",
"useZoomImageClick": "1.17 KB"
},
"@zoom-image/angular": {
"ZoomImageClickService": "3.97 KB",
"ZoomImageHoverService": "3.97 KB",
"ZoomImageMoveService": "3.97 KB",
"ZoomImageWheelService": "3.97 KB"
"ZoomImageClickService": "4.04 KB",
"ZoomImageHoverService": "4.04 KB",
"ZoomImageMoveService": "4.04 KB",
"ZoomImageWheelService": "4.04 KB"
}
}

0 comments on commit 5940d90

Please sign in to comment.