feat: image pinch to zoom (#1620)
parent
e92d1c6adf
commit
2cf8f591e8
|
@ -1,5 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { SwipeDirection } from '@vueuse/core'
|
||||
import { useGesture } from '@vueuse/gesture'
|
||||
import type { PermissiveMotionProperties } from '@vueuse/motion'
|
||||
import { useReducedMotion } from '@vueuse/motion'
|
||||
import type { mastodon } from 'masto'
|
||||
|
||||
|
@ -23,18 +25,36 @@ const reduceMotion = useReducedMotion()
|
|||
|
||||
const canAnimate = computed(() => !reduceMotion.value && animateTimeout.value)
|
||||
|
||||
const { motionProperties } = useMotionProperties(target, {
|
||||
cursor: 'grab',
|
||||
scale: 1,
|
||||
x: 0,
|
||||
y: 0,
|
||||
})
|
||||
const { set } = useSpring(motionProperties as Partial<PermissiveMotionProperties>)
|
||||
|
||||
function resetZoom() {
|
||||
set({ scale: 1 })
|
||||
}
|
||||
|
||||
watch(modelValue, resetZoom)
|
||||
|
||||
const { width, height } = useElementSize(target)
|
||||
const { isSwiping, lengthX, lengthY, direction } = useSwipe(target, {
|
||||
threshold: 5,
|
||||
passive: false,
|
||||
onSwipeEnd(e, direction) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
if (direction === SwipeDirection.RIGHT && Math.abs(distanceX.value) > threshold)
|
||||
if (direction === SwipeDirection.RIGHT && Math.abs(distanceX.value) > threshold) {
|
||||
modelValue.value = Math.max(0, modelValue.value - 1)
|
||||
resetZoom()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
if (direction === SwipeDirection.LEFT && Math.abs(distanceX.value) > threshold)
|
||||
if (direction === SwipeDirection.LEFT && Math.abs(distanceX.value) > threshold) {
|
||||
modelValue.value = Math.min(media.length - 1, modelValue.value + 1)
|
||||
resetZoom()
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-use-before-define
|
||||
if (direction === SwipeDirection.UP && Math.abs(distanceY.value) > threshold)
|
||||
|
@ -42,6 +62,21 @@ const { isSwiping, lengthX, lengthY, direction } = useSwipe(target, {
|
|||
},
|
||||
})
|
||||
|
||||
useGesture({
|
||||
onPinch({ offset: [distance, angle] }) {
|
||||
set({ scale: 1 + distance / 200 })
|
||||
},
|
||||
onMove({ movement: [x, y], dragging, pinching }) {
|
||||
if (dragging && !pinching)
|
||||
set({ x, y })
|
||||
},
|
||||
}, {
|
||||
domTarget: target,
|
||||
eventOptions: {
|
||||
passive: true,
|
||||
},
|
||||
})
|
||||
|
||||
const distanceX = computed(() => {
|
||||
if (width.value === 0)
|
||||
return 0
|
||||
|
|
Loading…
Reference in New Issue