diff --git a/vite-tailwindcss/src/components/PhotoGallery.vue b/vite-tailwindcss/src/components/PhotoGallery.vue index db085c4..3fc37dd 100644 --- a/vite-tailwindcss/src/components/PhotoGallery.vue +++ b/vite-tailwindcss/src/components/PhotoGallery.vue @@ -38,19 +38,27 @@ - +
- - +
@@ -92,7 +100,9 @@ import { ref, computed, watch, nextTick } from 'vue' import { borderClass } from '@/composables/borderStyles' -const DECODE_TIMEOUT_MS = 4000 +const BATCH_SIZE = 3 +const BATCH_GAP_MS = 140 +const BATCH_DECODE_TIMEOUT_MS = 2500 const props = defineProps({ page: { type: Object, required: true }, @@ -102,37 +112,65 @@ const props = defineProps({ const emit = defineEmits(['preview-image', 'ready']) const nineGridRef = ref(null) +const nineShownCount = ref(0) let readyEmitted = false const frameClass = computed(() => borderClass(props.page.borderStyle)) -const waitImagesReady = async () => { - await nextTick() - const root = nineGridRef.value - if (!root) return - const imgs = [...root.querySelectorAll('img[src]')] - if (!imgs.length) return - const decodeAll = Promise.allSettled( - imgs.map((img) => { - if (typeof img.decode === 'function') return img.decode().catch(() => {}) - if (img.complete) return Promise.resolve() - return new Promise((resolve) => { - img.addEventListener('load', resolve, { once: true }) - img.addEventListener('error', resolve, { once: true }) - }) - }) - ) - await Promise.race([ - decodeAll, - new Promise((resolve) => setTimeout(resolve, DECODE_TIMEOUT_MS)), - ]) +const decodeImg = (img) => { + if (!img) return Promise.resolve() + if (typeof img.decode === 'function') return img.decode().catch(() => {}) + if (img.complete) return Promise.resolve() + return new Promise((resolve) => { + img.addEventListener('load', resolve, { once: true }) + img.addEventListener('error', resolve, { once: true }) + }) +} + +const yieldToMain = () => new Promise((resolve) => { + if (typeof requestAnimationFrame === 'function') { + requestAnimationFrame(() => resolve()) + } else { + setTimeout(resolve, 0) + } +}) + +const runBatchedReveal = async () => { + const images = props.page.images || [] + const total = images.length + if (!total) return + + for (let start = 0; start < total; start += BATCH_SIZE) { + nineShownCount.value = Math.min(total, start + BATCH_SIZE) + await nextTick() + await yieldToMain() + + const root = nineGridRef.value + const end = nineShownCount.value + const imgs = root + ? [...root.querySelectorAll('img[data-nine-idx]')].filter((el) => { + const i = Number(el.getAttribute('data-nine-idx')) + return i >= start && i < end + }) + : [] + + await Promise.race([ + Promise.allSettled(imgs.map(decodeImg)), + new Promise((resolve) => setTimeout(resolve, BATCH_DECODE_TIMEOUT_MS)), + ]) + + if (end < total) { + await new Promise((resolve) => setTimeout(resolve, BATCH_GAP_MS)) + await yieldToMain() + } + } } watch( () => props.activate && props.page?.type === 'nine-grid', async (on) => { if (!on || readyEmitted) return - await waitImagesReady() + await runBatchedReveal() if (readyEmitted) return readyEmitted = true emit('ready') diff --git a/vite-tailwindcss/src/views/index/index.vue b/vite-tailwindcss/src/views/index/index.vue index 11c6f62..b1418f1 100644 --- a/vite-tailwindcss/src/views/index/index.vue +++ b/vite-tailwindcss/src/views/index/index.vue @@ -117,7 +117,7 @@
{{ data.formalText1 }} {{ data.formalText2 }} - 见证我们的幸福 + 见证我们的幸福 诚挚邀请您
@@ -353,7 +353,8 @@ let nineGridRevealTimer = null const nineGridDone = new Set() const BOTTOM_RETURN_DELAY = 30000 const FREE_SCROLL_BASE_STEP = 1.2 -const NINE_GRID_REVEAL_HOLD_MS = 900 +/** 分批入场已占时间,收尾再略停一下即可 */ +const NINE_GRID_REVEAL_HOLD_MS = 400 const NINE_GRID_FULL_RATIO = 0.9 const freeInterval = computed(() => {