feat(ui): click outside the image in the viewer modal closes it (parity with IR)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-23 21:24:06 -04:00
parent c9ddcd0f60
commit 38a45baad5
3 changed files with 38 additions and 4 deletions
+32 -2
View File
@@ -1,14 +1,16 @@
<template>
<div
ref="canvasEl"
class="fc-canvas"
:class="{ 'fc-canvas--zoomed': panZoom.state.scale > 1 }"
@wheel="panZoom.handlers.onWheel"
@pointerdown="panZoom.handlers.onPointerDown"
@pointermove="panZoom.handlers.onPointerMove"
@pointerup="panZoom.handlers.onPointerUp"
@click="panZoom.handlers.onClick"
@click="onCanvasClick"
>
<img
ref="imgEl"
:src="src" :alt="alt"
:style="{
transform: `translate(${panZoom.state.x}px, ${panZoom.state.y}px) scale(${panZoom.state.scale})`
@@ -19,14 +21,42 @@
</template>
<script setup>
import { watch } from 'vue'
import { ref, watch } from 'vue'
import { usePanZoom } from '../../composables/usePanZoom.js'
const props = defineProps({ src: String, alt: String })
const emit = defineEmits(['close-request'])
const panZoom = usePanZoom()
const canvasEl = ref(null)
const imgEl = ref(null)
// Reset zoom when the src changes (prev/next nav).
watch(() => props.src, () => panZoom.reset())
// Click on the image → toggle zoom (IR/expected behavior). Click on
// the haze area around the image → request close. We use the image's
// own bounding rect rather than @click.self because the <img> sets
// pointer-events: none for the pan-drag pathway, so the click always
// targets the canvas div regardless of where the cursor was.
function onCanvasClick(ev) {
if (panZoom.state.scale > 1) {
// When zoomed, any click resets zoom — preserve old behavior.
panZoom.handlers.onClick(ev)
return
}
const img = imgEl.value
if (!img) return
const r = img.getBoundingClientRect()
const inside =
ev.clientX >= r.left && ev.clientX <= r.right &&
ev.clientY >= r.top && ev.clientY <= r.bottom
if (inside) {
panZoom.handlers.onClick(ev)
} else {
emit('close-request')
}
}
</script>
<style scoped>