fix preview
This commit is contained in:
@@ -1,11 +1,41 @@
|
||||
<script setup lang="ts">
|
||||
import { useGalleryStore } from "../stores/gallery";
|
||||
import { convertFileSrc } from "@tauri-apps/api/core";
|
||||
import { ref, computed } from "vue";
|
||||
import { ref, computed, onMounted, onUnmounted, watch } from "vue";
|
||||
|
||||
const store = useGalleryStore();
|
||||
const isDragging = ref(false);
|
||||
const dragStart = ref({ x: 0, y: 0 });
|
||||
const imgRef = ref<HTMLImageElement | null>(null);
|
||||
const renderHeight = ref(0);
|
||||
|
||||
let resizeObserver: ResizeObserver | null = null;
|
||||
|
||||
const updateHeight = () => {
|
||||
if (imgRef.value) {
|
||||
renderHeight.value = imgRef.value.clientHeight;
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
resizeObserver = new ResizeObserver(() => {
|
||||
updateHeight();
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
if (resizeObserver) resizeObserver.disconnect();
|
||||
});
|
||||
|
||||
// Watch for image ref availability
|
||||
watch(imgRef, (el) => {
|
||||
if (el && resizeObserver) {
|
||||
resizeObserver.disconnect(); // clear old
|
||||
resizeObserver.observe(el);
|
||||
// Force update immediately
|
||||
// Wait for load? ResizeObserver usually handles layout shifts
|
||||
}
|
||||
});
|
||||
|
||||
// Use either manual position (if override is true) or ZCA suggestion
|
||||
const position = computed(() => {
|
||||
@@ -56,12 +86,6 @@ const onMouseUp = () => {
|
||||
const onMouseLeave = () => {
|
||||
isDragging.value = false;
|
||||
};
|
||||
|
||||
// Calculate font size relative to current display image height
|
||||
// We need to know the rendered height of the image to approximate the visual effect
|
||||
// Backend uses "percentage of real image height".
|
||||
// In CSS, if we use % of container height, it should match if container matches image aspect.
|
||||
// Since we use inline-flex and the img determines size, 100% height of parent refers to the image height.
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -77,10 +101,16 @@ const onMouseLeave = () => {
|
||||
style="max-width: 100%; max-height: 100%;"
|
||||
>
|
||||
<img
|
||||
ref="imgRef"
|
||||
:src="convertFileSrc(store.selectedImage.path)"
|
||||
class="max-w-full max-h-full w-auto h-auto block shadow-lg select-none pointer-events-none"
|
||||
style="max-height: calc(100vh - 10rem);"
|
||||
alt="Hero Image"
|
||||
loading="eager"
|
||||
decoding="sync"
|
||||
fetchpriority="high"
|
||||
@load="updateHeight"
|
||||
@error="(e) => console.error('Hero Image Load Error:', e)"
|
||||
/>
|
||||
|
||||
<!-- Text Watermark Overlay -->
|
||||
@@ -93,34 +123,15 @@ const onMouseLeave = () => {
|
||||
transform: 'translate(-50%, -50%)',
|
||||
opacity: store.watermarkSettings.opacity,
|
||||
color: store.watermarkSettings.color,
|
||||
fontSize: (store.watermarkSettings.scale * 100 * 1.5) + 'cqh',
|
||||
/* Using container query units or just % of height?
|
||||
Since container is the div wrapping img, its height IS the img height.
|
||||
So height: 100% = img height.
|
||||
fontSize: X% of height.
|
||||
*/
|
||||
height: '0px', /* collapse container height so it doesn't affect layout, rely on overflow visible for text */
|
||||
fontSize: (renderHeight * store.watermarkSettings.scale) + 'px',
|
||||
height: '0px',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
}"
|
||||
@mousedown="onMouseDown"
|
||||
>
|
||||
<span :style="{ fontSize: (store.watermarkSettings.scale * 1000) + '%' }">
|
||||
<!-- This is tricky in CSS. Let's use viewport units approximation or just fix it
|
||||
The simplest way to scale text with container height in Vue without ResizeObserver
|
||||
is to use a computed style that relies on container size if we knew it.
|
||||
Actually, since we are inside the container, we can use % of height for font-size? No, font-size % refers to parent font size.
|
||||
|
||||
Hack: Viewport units are stable-ish.
|
||||
Better: Render text in SVG overlaid?
|
||||
|
||||
Simple approach for MVP Preview:
|
||||
Use a fixed visual size or simple scale multiplier assuming 1080p screen.
|
||||
Real backend logic is exact.
|
||||
|
||||
Alternative: Use CSS 'container-type: size' on the parent!
|
||||
-->
|
||||
<span>
|
||||
{{ store.watermarkSettings.text }}
|
||||
</span>
|
||||
|
||||
@@ -136,12 +147,10 @@ const onMouseLeave = () => {
|
||||
|
||||
<style scoped>
|
||||
.image-container {
|
||||
container-type: size;
|
||||
/* Removed container-type: size to prevent layout collapse */
|
||||
}
|
||||
|
||||
span {
|
||||
/* Font size relative to container height (cqh) */
|
||||
font-size: v-bind('(store.watermarkSettings.scale * 100) + "cqh"');
|
||||
text-shadow: 0 1px 3px rgba(0,0,0,0.5);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -28,8 +28,14 @@ const onSelect = (index: number) => {
|
||||
@click="onSelect(index)"
|
||||
>
|
||||
<div class="h-full w-full bg-gray-800 flex items-center justify-center overflow-hidden rounded border border-gray-600">
|
||||
<!-- Use actual thumbnail path later -->
|
||||
<img :src="convertFileSrc(item.path)" class="w-full h-full object-cover" loading="lazy" />
|
||||
<!-- Use generated thumbnail -->
|
||||
<img
|
||||
:src="convertFileSrc(item.thumbnail)"
|
||||
class="w-full h-full object-cover"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
fetchpriority="low"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user