Skip to content

Commit

Permalink
feat: image pinch to zoom (#1620)
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnyTheCarrot authored Feb 4, 2023
1 parent e92d1c6 commit 2cf8f59
Showing 1 changed file with 37 additions and 2 deletions.
39 changes: 37 additions & 2 deletions components/modal/ModalMediaPreviewCarousel.vue
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -23,25 +25,58 @@ 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)
emit('close')
},
})
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
Expand Down

0 comments on commit 2cf8f59

Please sign in to comment.