更新页面效果

This commit is contained in:
李琦
2026-07-31 17:21:41 +08:00
parent cbceb8e6a6
commit e8efc178a3
2 changed files with 36 additions and 9 deletions

View File

@@ -38,9 +38,9 @@
<!-- 九宫格 -->
<div v-else-if="page.type === 'nine-grid'" class="grid grid-cols-3 gap-1.5 px-4 mt-6">
<div v-for="(img, imgIdx) in page.images" :key="imgIdx" v-reveal="{ variant: 'scale', delay: imgIdx * 60 }"
class="aspect-square relative" :class="frameClass">
<img :src="img" class="hover:scale-105 transition-transform duration-700" />
<div v-for="(img, imgIdx) in page.images" :key="imgIdx" v-reveal="{ variant: 'up', delay: imgIdx * 24 }"
class="nine-grid-reveal aspect-square relative" :class="frameClass">
<img :src="img" loading="lazy" decoding="async" class="nine-grid-img" />
</div>
</div>
@@ -144,6 +144,26 @@ function polaroidTransform(i) {
.gallery-subtitle { font-family: var(--font-display); }
.gallery-desc { font-family: var(--font-kai); }
.nine-grid-reveal.reveal {
transform: translate3d(0, 12px, 0);
transition:
opacity 420ms ease-out,
transform 420ms cubic-bezier(0.22, 1, 0.36, 1);
will-change: opacity, transform;
}
.nine-grid-reveal.reveal--in {
transform: translate3d(0, 0, 0);
}
.nine-grid-img {
width: 100%;
height: 100%;
object-fit: cover;
transform: translateZ(0);
transition: transform 420ms ease-out;
backface-visibility: hidden;
}
.nine-grid-img:hover { transform: translateZ(0) scale(1.03); }
/* 错落双图:高度随视口缩放并封顶,保证标题+图片总高始终落在页高预算内 */
.overlap-wrap { height: clamp(320px, 54vh, 460px); }

View File

@@ -324,6 +324,7 @@ const rsvpForm = reactive({ name: '', guest_count: '1', wishes: '' })
const rsvpOptions = [ { value: '1', label: '1 人出席' }, { value: '2', label: '2 人出席' }, { value: '3', label: '3 人及以上' }, { value: '0', label: '遗憾缺席' } ]
let rafId = null, snapTimer = null, pauseTimer = null, introTimer = null, freeTimer = null, animId = null, scrollStartTimer = null, bottomReturnTimer = null
let freeScrollLastTs = 0
const BOTTOM_RETURN_DELAY = 30000
// 后台可配置的滚动参数(带默认值兜底,防止脏数据)
@@ -464,24 +465,30 @@ const startAutoScroll = () => {
clearTimeout(scrollStartTimer)
clearInterval(snapTimer)
clearInterval(freeTimer)
cancelAnimationFrame(rafId)
if (data.value.scrollMode === 'snap') {
if (isAutoScroll.value && !isInteracting.value && !isDrawerOpen.value) goNextSection()
snapTimer = setInterval(() => {
if (isAutoScroll.value && !isInteracting.value && !isDrawerOpen.value) goNextSection()
}, 4500)
} else {
// 自由滚动:setInterval 按后台配置的间隔匀速推进(间隔越小越快)
freeTimer = setInterval(() => {
// 自由滚动:按浏览器帧率匀速推进,速度仍由后台间隔控制(间隔越小越快)
freeScrollLastTs = 0
const tickFreeScroll = (now) => {
const dt = freeScrollLastTs ? Math.min(34, now - freeScrollLastTs) : 16.7
freeScrollLastTs = now
const el = scrollContainerRef.value
if (el && isAutoScroll.value && !isInteracting.value && !isDrawerOpen.value) {
if (isAtBottom(el)) {
scheduleBottomReturn()
return
} else {
el.scrollTop += dt * (1.2 / freeInterval.value)
if (isAtBottom(el)) scheduleBottomReturn()
}
el.scrollTop += 1.2
if (isAtBottom(el)) scheduleBottomReturn()
}
}, freeInterval.value)
rafId = requestAnimationFrame(tickFreeScroll)
}
rafId = requestAnimationFrame(tickFreeScroll)
}
}