Testing image copying

This commit is contained in:
Simon Pocrnjič 2026-03-18 21:48:39 +01:00
parent d80c99c6c0
commit f8d1579cb2

View File

@ -42,6 +42,9 @@ const dragStartTY = ref(0);
const MAX_SCALE = 8; const MAX_SCALE = 8;
// Image context menu state
const contextMenu = ref({ visible: false, x: 0, y: 0 });
const imageCursorClass = computed(() => { const imageCursorClass = computed(() => {
if (isDragging.value && hasMoved.value) return "cursor-grabbing"; if (isDragging.value && hasMoved.value) return "cursor-grabbing";
if (imageScale.value > fitScale.value + 0.01) return "cursor-grab"; if (imageScale.value > fitScale.value + 0.01) return "cursor-grab";
@ -56,7 +59,7 @@ const initImageView = () => {
const cH = container.clientHeight; const cH = container.clientHeight;
const iW = img.naturalWidth || cW; const iW = img.naturalWidth || cW;
const iH = img.naturalHeight || cH; const iH = img.naturalHeight || cH;
const fs = Math.min(cW / iW, cH / iH); const fs = Math.min(1, cW / iW, cH / iH);
fitScale.value = fs; fitScale.value = fs;
imageScale.value = fs; imageScale.value = fs;
translateX.value = (cW - iW * fs) / 2; translateX.value = (cW - iW * fs) / 2;
@ -156,9 +159,42 @@ const handleMouseDown = (e) => {
window.addEventListener("mouseup", onMouseUp); window.addEventListener("mouseup", onMouseUp);
}; };
const closeContextMenu = () => {
contextMenu.value.visible = false;
window.removeEventListener("click", closeContextMenu);
};
const handleContextMenu = (e) => {
e.preventDefault();
contextMenu.value = { visible: true, x: e.clientX, y: e.clientY };
setTimeout(() => window.addEventListener("click", closeContextMenu), 0);
};
const copyImageToClipboard = async () => {
closeContextMenu();
const img = imageRef.value;
if (!img) return;
const displayW = Math.round(img.naturalWidth * fitScale.value);
const displayH = Math.round(img.naturalHeight * fitScale.value);
const canvas = document.createElement("canvas");
canvas.width = displayW;
canvas.height = displayH;
const ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, displayW, displayH);
canvas.toBlob(async (blob) => {
if (!blob) return;
try {
await navigator.clipboard.write([new ClipboardItem({ "image/png": blob })]);
} catch (err) {
console.error("Copy failed", err);
}
}, "image/png");
};
onUnmounted(() => { onUnmounted(() => {
window.removeEventListener("mousemove", onMouseMove); window.removeEventListener("mousemove", onMouseMove);
window.removeEventListener("mouseup", onMouseUp); window.removeEventListener("mouseup", onMouseUp);
window.removeEventListener("click", closeContextMenu);
}); });
const fileExtension = computed(() => { const fileExtension = computed(() => {
@ -337,6 +373,7 @@ watch(
transition: isDragging ? 'none' : 'transform 0.12s ease', transition: isDragging ? 'none' : 'transform 0.12s ease',
}" }"
@load="handleImageLoad" @load="handleImageLoad"
@contextmenu.prevent="handleContextMenu"
/> />
<!-- Zoom level badge --> <!-- Zoom level badge -->
<div <div
@ -362,6 +399,21 @@ watch(
> >
Kolesce za povečavo / pomanjšavo · Povleči za premik Kolesce za povečavo / pomanjšavo · Povleči za premik
</div> </div>
<!-- Custom context menu -->
<Teleport to="body">
<div
v-if="contextMenu.visible"
class="fixed z-[9999] min-w-36 rounded-md border bg-popover shadow-md py-1 text-sm text-popover-foreground"
:style="{ top: contextMenu.y + 'px', left: contextMenu.x + 'px' }"
>
<button
class="w-full text-left px-3 py-1.5 hover:bg-accent hover:text-accent-foreground rounded-sm"
@click.stop="copyImageToClipboard"
>
Kopiraj sliko
</button>
</div>
</Teleport>
</div> </div>
</template> </template>