恢复滚动方案

This commit is contained in:
李琦
2026-08-01 14:55:21 +08:00
parent a6dec89d09
commit f65000336a
97 changed files with 98 additions and 3197 deletions

View File

@@ -1,60 +0,0 @@
import { onMounted, onUnmounted } from 'vue'
/**
* 提前约 1.5 屏预热区块内图片解码,避免滚入视口时与 free-scroll rAF 撞车。
* onBusyChange(true/false) 供父级短暂降低 canvas 粒子负载。
*/
export function useImageWarmup(rootRef, { onBusyChange } = {}) {
let observer = null
let busy = false
let warmToken = 0
const setBusy = (next) => {
if (busy === next) return
busy = next
onBusyChange?.(next)
}
const warmImages = async (el) => {
const token = ++warmToken
setBusy(true)
const imgs = el.querySelectorAll('img[src]')
await 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 })
})
})
)
if (token === warmToken) setBusy(false)
}
onMounted(() => {
const el = rootRef.value
if (!el || typeof IntersectionObserver === 'undefined') return
const scrollRoot = el.closest('.scrollable-area-body')
observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) warmImages(el)
else {
warmToken += 1
setBusy(false)
}
},
{ root: scrollRoot, rootMargin: '150% 0px', threshold: 0 }
)
observer.observe(el)
})
onUnmounted(() => {
warmToken += 1
observer?.disconnect()
observer = null
setBusy(false)
})
}