forked from BRETT/BRETT
Initial Commit
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<script setup lang="ts">
|
||||
import { onKeyStroke } from '@vueuse/core'
|
||||
|
||||
defineProps<{
|
||||
src: string
|
||||
alt?: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
close: []
|
||||
}>()
|
||||
|
||||
const scale = ref(1)
|
||||
const offset = ref({ x: 0, y: 0 })
|
||||
const dragging = ref(false)
|
||||
let last = { x: 0, y: 0 }
|
||||
|
||||
function onWheel(event: WheelEvent) {
|
||||
const factor = event.deltaY < 0 ? 1.15 : 1 / 1.15
|
||||
scale.value = Math.min(10, Math.max(0.2, scale.value * factor))
|
||||
}
|
||||
|
||||
function onPointerDown(event: PointerEvent) {
|
||||
dragging.value = true
|
||||
last = { x: event.clientX, y: event.clientY }
|
||||
;(event.currentTarget as HTMLElement).setPointerCapture(event.pointerId)
|
||||
}
|
||||
|
||||
function onPointerMove(event: PointerEvent) {
|
||||
if (!dragging.value) return
|
||||
offset.value = {
|
||||
x: offset.value.x + event.clientX - last.x,
|
||||
y: offset.value.y + event.clientY - last.y,
|
||||
}
|
||||
last = { x: event.clientX, y: event.clientY }
|
||||
}
|
||||
|
||||
function onPointerUp() {
|
||||
dragging.value = false
|
||||
}
|
||||
|
||||
function reset() {
|
||||
scale.value = 1
|
||||
offset.value = { x: 0, y: 0 }
|
||||
}
|
||||
|
||||
onKeyStroke('Escape', () => emit('close'))
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div
|
||||
class="fixed inset-0 z-50 flex items-center justify-center overflow-hidden bg-black/90"
|
||||
@wheel.prevent="onWheel"
|
||||
@click="emit('close')"
|
||||
>
|
||||
<NuxtImg
|
||||
:src="src"
|
||||
:alt="alt"
|
||||
draggable="false"
|
||||
class="max-h-[95vh] max-w-[95vw] touch-none select-none"
|
||||
:class="dragging ? 'cursor-grabbing' : 'cursor-grab'"
|
||||
:style="{ transform: `translate(${offset.x}px, ${offset.y}px) scale(${scale})` }"
|
||||
@click.stop
|
||||
@dblclick="reset"
|
||||
@pointerdown.prevent="onPointerDown"
|
||||
@pointermove="onPointerMove"
|
||||
@pointerup="onPointerUp"
|
||||
@pointercancel="onPointerUp"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="absolute top-4 right-4 rounded-md bg-black/50 p-2 text-white hover:bg-black/70"
|
||||
@click="emit('close')"
|
||||
>
|
||||
<Icon name="ph:x-fill" class="size-5" />
|
||||
<span class="sr-only">Schließen</span>
|
||||
</button>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
Reference in New Issue
Block a user