@fy-/fws-vue 2.3.15 → 2.3.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ui/DefaultGallery.vue +58 -10
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# This file has been completely rewritten and optimized
|
|
1
2
|
<script setup lang="ts">
|
|
2
3
|
import type { Component } from 'vue'
|
|
3
4
|
import type { APIPaging } from '../../composables/rest'
|
|
@@ -59,8 +60,8 @@ const availableHeight = computed(() => {
|
|
|
59
60
|
height -= infoPanelHeight.value
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
//
|
|
63
|
-
return `${height
|
|
63
|
+
// Use direct pixel values
|
|
64
|
+
return `${height}px`
|
|
64
65
|
})
|
|
65
66
|
|
|
66
67
|
// Use VueUse's useFullscreen for better fullscreen handling
|
|
@@ -146,6 +147,14 @@ const currentImage = computed(() => {
|
|
|
146
147
|
const imageCount = computed(() => props.images.length)
|
|
147
148
|
const currentIndex = computed(() => modelValue.value + 1)
|
|
148
149
|
|
|
150
|
+
// Helper function to adjust image size based on natural dimensions
|
|
151
|
+
function adjustImageSize(img: HTMLImageElement, availableHeightPx: number) {
|
|
152
|
+
if (img.naturalHeight > 0) {
|
|
153
|
+
const maxHeight = Math.min(img.naturalHeight, availableHeightPx)
|
|
154
|
+
img.style.maxHeight = `${maxHeight}px`
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
149
158
|
// Image size and positioning
|
|
150
159
|
const calculateImageSize = useDebounceFn(() => {
|
|
151
160
|
if (!imageContainerRef.value) return
|
|
@@ -155,30 +164,57 @@ const calculateImageSize = useDebounceFn(() => {
|
|
|
155
164
|
|
|
156
165
|
if (!imageElements || imageElements.length === 0) return
|
|
157
166
|
|
|
167
|
+
// Get current panel heights for accurate calculations
|
|
168
|
+
const topControlsCurrentHeight = topControlsRef.value?.offsetHeight || 0
|
|
169
|
+
const infoPanelCurrentHeight = infoPanel.value && infoPanelRef.value ? infoPanelRef.value.offsetHeight : 0
|
|
170
|
+
|
|
171
|
+
// Prepare for image sizing calculation
|
|
172
|
+
|
|
158
173
|
imageElements.forEach((img) => {
|
|
159
174
|
// Reset to ensure proper recalculation
|
|
160
175
|
img.style.maxHeight = ''
|
|
176
|
+
img.style.maxWidth = ''
|
|
161
177
|
// Force browser to recalculate styles
|
|
162
178
|
void img.offsetHeight
|
|
163
179
|
|
|
164
|
-
//
|
|
165
|
-
|
|
180
|
+
// Apply exact pixel measurements based on actual UI elements
|
|
181
|
+
const topHeight = topControlsCurrentHeight || 0
|
|
182
|
+
const infoHeight = infoPanelCurrentHeight || 0
|
|
183
|
+
const availableHeightPx = windowHeight.value - topHeight - infoHeight - 32 // 32px for padding
|
|
166
184
|
|
|
167
|
-
// Adjust image size based on screen size
|
|
168
185
|
if (windowWidth.value <= 768) {
|
|
169
|
-
|
|
170
|
-
img.style.maxHeight =
|
|
186
|
+
// Mobile specific sizing - use pixel values directly
|
|
187
|
+
img.style.maxHeight = `${availableHeightPx}px`
|
|
188
|
+
img.style.maxWidth = '90vw'
|
|
171
189
|
}
|
|
172
190
|
else {
|
|
173
|
-
|
|
191
|
+
// Desktop sizing - account for sidebar if present
|
|
192
|
+
const sidebarWidth = sidePanel.value ? sidePanelRef.value?.offsetWidth || 256 : 0
|
|
193
|
+
const availableWidthPx = windowWidth.value - sidebarWidth - 48 // 48px for padding
|
|
194
|
+
|
|
195
|
+
img.style.maxHeight = `${availableHeightPx}px`
|
|
196
|
+
img.style.maxWidth = `${availableWidthPx}px`
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// For images, add special handling for natural dimensions
|
|
200
|
+
if (img instanceof HTMLImageElement) {
|
|
201
|
+
if (img.complete) {
|
|
202
|
+
adjustImageSize(img, availableHeightPx)
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
img.onload = () => adjustImageSize(img, availableHeightPx)
|
|
206
|
+
}
|
|
174
207
|
}
|
|
175
208
|
})
|
|
176
209
|
})
|
|
177
210
|
}, 50)
|
|
178
211
|
|
|
179
|
-
// Update all layout measurements
|
|
212
|
+
// Update all layout measurements when any relevant state changes
|
|
180
213
|
const updateLayout = useDebounceFn(() => {
|
|
181
|
-
|
|
214
|
+
// Recalculate image size with a small delay to ensure all DOM updates are processed
|
|
215
|
+
setTimeout(() => {
|
|
216
|
+
calculateImageSize()
|
|
217
|
+
}, 10)
|
|
182
218
|
}, 50)
|
|
183
219
|
|
|
184
220
|
// Modal controls
|
|
@@ -246,6 +282,11 @@ function goNextImage() {
|
|
|
246
282
|
modelValue.value = 0
|
|
247
283
|
}
|
|
248
284
|
resetControlsTimer()
|
|
285
|
+
|
|
286
|
+
// Force layout update when image changes
|
|
287
|
+
nextTick(() => {
|
|
288
|
+
updateLayout()
|
|
289
|
+
})
|
|
249
290
|
}
|
|
250
291
|
|
|
251
292
|
function goPrevImage() {
|
|
@@ -257,6 +298,11 @@ function goPrevImage() {
|
|
|
257
298
|
modelValue.value = props.images.length - 1 > 0 ? props.images.length - 1 : 0
|
|
258
299
|
}
|
|
259
300
|
resetControlsTimer()
|
|
301
|
+
|
|
302
|
+
// Force layout update when image changes
|
|
303
|
+
nextTick(() => {
|
|
304
|
+
updateLayout()
|
|
305
|
+
})
|
|
260
306
|
}
|
|
261
307
|
|
|
262
308
|
// UI control functions
|
|
@@ -447,6 +493,7 @@ watch(
|
|
|
447
493
|
galleryHeight,
|
|
448
494
|
topControlsHeight,
|
|
449
495
|
infoPanelHeight,
|
|
496
|
+
modelValue, // Watch for model value changes to update layout
|
|
450
497
|
],
|
|
451
498
|
() => {
|
|
452
499
|
updateLayout()
|
|
@@ -650,6 +697,7 @@ onUnmounted(() => {
|
|
|
650
697
|
:style="{ maxHeight: availableHeight }"
|
|
651
698
|
:src="modelValueSrc"
|
|
652
699
|
:alt="`Gallery image ${modelValue + 1}`"
|
|
700
|
+
@load="updateLayout"
|
|
653
701
|
>
|
|
654
702
|
<component
|
|
655
703
|
:is="imageComponent"
|