更新页面效果

This commit is contained in:
李琦
2026-08-01 09:15:40 +08:00
parent 4dcffcd500
commit 832be572cf
7 changed files with 95 additions and 134 deletions

View File

@@ -2,8 +2,8 @@
<div class="gallery">
<!-- 标题区 -->
<div v-reveal="'up'" class="text-center mb-5 px-4">
<span class="gallery-title text-xl text-[#a88c6b] tracking-[0.3em] font-light block mb-2">{{ page.title }}</span>
<span class="gallery-subtitle text-[9px] text-[#8A8680] uppercase tracking-[0.4em] block mb-4">{{ page.subtitle }}</span>
<span class="gallery-title calligraphy text-xl text-[#a88c6b] tracking-[0.3em] font-bold block mb-2">{{ page.title }}</span>
<span class="gallery-subtitle text-[9px] text-[#8A8680] first-letter:uppercase lowercase tracking-[0.4em] block mb-4">{{ page.subtitle }}</span>
<span class="gallery-desc text-[12px] text-[#6b6863] font-light leading-relaxed mx-auto max-w-[280px] tracking-widest block whitespace-pre-wrap">{{ page.desc }}</span>
</div>
@@ -37,14 +37,9 @@
</div>
<!-- 九宫格 -->
<div v-else-if="page.type === 'nine-grid'" class="nine-grid grid grid-cols-3 gap-1.5 px-4 mt-6">
<div v-else-if="page.type === 'nine-grid'" v-reveal="{ variant: 'up', delay: 80 }" class="nine-grid grid grid-cols-3 gap-1.5 px-4 mt-6">
<div v-for="(img, imgIdx) in page.images" :key="imgIdx"
data-aos="nine-grid-zoom"
:data-aos-delay="imgIdx * 200"
data-aos-duration="500"
data-aos-easing="ease-out-cubic"
data-aos-once="true"
class="nine-grid-reveal aspect-square relative" :class="frameClass">
class="aspect-square relative" :class="frameClass">
<img :src="img" loading="lazy" decoding="async" class="nine-grid-img" />
</div>
</div>
@@ -145,24 +140,13 @@ function polaroidTransform(i) {
<style scoped>
.gallery { width: 100%; font-family: var(--font-sans); }
.gallery-title { font-family: var(--font-serif); }
.gallery-subtitle { font-family: var(--font-display); }
.gallery-title {
font-family: var(--font-calligraphy);
font-weight: 700;
}
/*.gallery-subtitle { font-family: var(--font-display); }*/
.gallery-desc { font-family: var(--font-kai); }
.nine-grid-reveal {
opacity: 1;
transform: translate3d(0, 0, 0);
}
[data-aos='nine-grid-zoom'] {
opacity: 0;
transform: translate3d(0, 10px, 0) scale(0.94);
transition-property: opacity, transform;
will-change: opacity, transform;
}
[data-aos='nine-grid-zoom'].aos-animate {
opacity: 1;
transform: translate3d(0, 0, 0) scale(1);
}
.nine-grid-img {
width: 100%;
height: 100%;

View File

@@ -4,7 +4,6 @@ import Antd from 'ant-design-vue'
import './style.css'
import './styles/animations.css'
import './styles/frames.css'
import 'aos/dist/aos.css'
import App from './App.vue'
import '@fortawesome/fontawesome-free/css/all.css' // 引入所有样式
// 注册路由

View File

@@ -1,4 +1,6 @@
@import "tailwindcss";
@import "@fontsource/great-vibes/400.css";
@import "@fontsource/ma-shan-zheng/400.css";
:root {
--font-sans: "Avenir Next", "Helvetica Neue", "PingFang SC", "Microsoft YaHei", sans-serif;
@@ -6,6 +8,7 @@
--font-display: "Didot", "Bodoni 72", "Cormorant Garamond", "Times New Roman", serif;
--font-kai: "Kaiti SC", "STKaiti", "KaiTi", "FangSong", serif;
--font-brush: "HanziPen SC", "STXingkai", "华文行楷", "FZKai-Z03S", "Kaiti SC", "STKaiti", "KaiTi", "FangSong", serif;
--font-calligraphy: "Great Vibes", "Ma Shan Zheng", cursive, serif;
--font-number: "Cochin", "Georgia", "Times New Roman", serif;
}
@@ -13,3 +16,16 @@ html,
body {
font-family: var(--font-sans);
}
.calligraphy {
font-family: var(--font-calligraphy) !important;
}
.gallery-subtitle {
font-family: var(--font-calligraphy) !important;
font-weight: bold;
}
.calligraphy-strong {
font-family: var(--font-calligraphy) !important;
font-weight: 700;
}

View File

@@ -12,15 +12,15 @@
<span class="cover-filigree cover-filigree-top" aria-hidden="true"></span>
<span class="cover-filigree cover-filigree-bottom" aria-hidden="true"></span>
<div class="emblem-inner">
<span class="emblem-kicker">WEDDING INVITATION</span>
<span class="emblem-kicker first-letter:uppercase lowercase calligraphy">WEDDING INVITATION</span>
<div class="emblem-seal" aria-hidden="true">
<i class="fa-solid fa-feather-pointed"></i>
</div>
<div class="emblem-names">{{ data.groom }}<span class="amp">&amp;</span>{{ data.bride }}</div>
<div class="emblem-names calligraphy-strong">{{ data.groom }}<span class="amp">&amp;</span>{{ data.bride }}</div>
<div class="emblem-rule"></div>
<div class="emblem-date">{{ data.date }}</div>
<div class="emblem-invite-title">岁序更替</div>
<div class="emblem-invite-copy">始于初见止于终老时光煮雨人事静好盼与您分享我们的幸福时刻</div>
<div class="emblem-date calligraphy">{{ data.date }}</div>
<div class="emblem-invite-title calligraphy-strong">岁序更替</div>
<div class="emblem-invite-copy calligraphy">始于初见止于终老时光煮雨人事静好盼与您分享我们的幸福时刻</div>
<div class="emblem-hint"><span class="dot"></span>轻触开启请柬</div>
</div>
</div>
@@ -78,7 +78,7 @@
<div class="page-section" :class="data.scrollMode === 'snap' ? 'snap-start' : ''">
<div class="flex flex-col items-center justify-between py-12 h-full w-full relative border-[0.5px] border-[#a88c6b]/20 bg-white/40">
<div v-reveal="'down'" class="text-center mt-6 z-10">
<span class="cover-kicker text-[10px] tracking-[0.5em] uppercase text-[#a88c6b] font-light block">Wedding Invitation</span>
<span class="cover-kicker calligraphy text-[10px] tracking-[0.5em] uppercase text-[#a88c6b] font-bold block">Wedding Invitation</span>
<div class="w-6 h-[0.5px] bg-[#a88c6b] mx-auto opacity-50 mt-4"></div>
</div>
@@ -89,10 +89,10 @@
</div>
</div>
<div v-reveal="{ variant: 'up', delay: 200 }" class="text-center z-10 mb-10 space-y-4 px-4">
<div class="cover-names flex items-end justify-center gap-6 text-3xl font-light tracking-[0.2em]">
<div v-reveal="{ variant: 'up', delay: 200 }" class="text-center z-10 mb-10 space-y-4 px-4 mt-8">
<div class="cover-names calligraphy-strong flex items-end justify-center gap-6 text-3xl font-light tracking-[0.2em]">
<span>{{ data.groom }}</span>
<span class="text-[#a88c6b] text-xl pb-1 italic font-serif">&amp;</span>
<span class="text-[#a88c6b] text-xl pb-1 italic calligraphy">&amp;</span>
<span>{{ data.bride }}</span>
</div>
<div class="cover-date flex flex-col items-center text-[11px] text-[#8A8680] tracking-[0.2em] mt-4 uppercase">
@@ -111,9 +111,9 @@
<div v-reveal="'blur'" class="flex flex-col items-center w-full">
<div class="text-3xl opacity-60 mb-12 text-[#a88c6b] font-serif float-soft"></div>
<div class="formal-copy flex justify-center gap-9 h-[22rem] text-[#3A3A3A]">
<span class="vertical-text formal-main">{{ data.formalText1 }}</span>
<span class="vertical-text formal-main formal-main-offset">{{ data.formalText2 }}</span>
<span class="vertical-text formal-side ml-4 border-l-[0.5px] border-[#a88c6b]/30 pl-6 h-64 mt-8 tracking-[0.28em]">诚挚邀请您见证我们的幸福</span>
<span class="vertical-text formal-main calligraphy-strong">{{ data.formalText1 }}</span>
<span class="vertical-text formal-main formal-main-offset calligraphy-strong">{{ data.formalText2 }}</span>
<span class="vertical-text formal-side calligraphy ml-4 border-l-[0.5px] border-[#a88c6b]/30 pl-6 h-64 mt-8 tracking-[0.28em]">诚挚邀请您见证我们的幸福</span>
</div>
</div>
</div>
@@ -190,7 +190,7 @@
<!-- 婚礼流程 -->
<div class="page-section schedule-page px-6 z-10 justify-center relative" :class="data.scrollMode === 'snap' ? 'snap-start' : ''">
<div v-reveal="'up'" class="schedule-heading">
<span class="schedule-title">婚礼流程</span>
<span class="schedule-title calligraphy">婚礼流程</span>
<span class="schedule-kicker">Wedding Schedule</span>
</div>
<div class="schedule-list">
@@ -222,7 +222,7 @@
<img :src="endImage" class="w-full h-full bg-[#F7F6F2] object-cover" alt="婚礼尾页照片" />
</div>
<div v-reveal="{ variant: 'up', delay: 180 }" class="ending-copy">
<span class="ending-title">期待您的光临</span>
<span class="ending-title calligraphy">期待您的光临</span>
<span class="ending-names">{{ data.groom }} &amp; {{ data.bride }}</span>
<span class="ending-date">{{ data.date }}</span>
</div>
@@ -296,12 +296,11 @@
</template>
<script setup>
import { ref, reactive, computed, onMounted, onUnmounted, nextTick, watch } from 'vue'
import { ref, reactive, computed, onMounted, onUnmounted, watch } from 'vue'
import { getConfig, submitRsvp } from '@/api/wedding'
import { useAudio } from '@/composables/useAudio'
import CanvasEffects from '@/components/CanvasEffects.vue'
import PhotoGallery from '@/components/PhotoGallery.vue'
import AOS from 'aos'
const DEFAULTS = {
scrollMode: 'snap', petalEnabled: true, bubbleEnabled: true, introEnabled: true,
@@ -496,13 +495,6 @@ const syncPageScrollMode = () => {
document.documentElement.classList.toggle('page-scroll-snap', data.value.scrollMode === 'snap')
}
const refreshAos = () => {
requestAnimationFrame(() => {
AOS.refreshHard()
setTimeout(() => AOS.refresh(), 250)
})
}
const scheduleAutoScrollStart = () => {
clearTimeout(scrollStartTimer)
scrollStartTimer = setTimeout(() => startAutoScroll(), firstScreenDuration.value)
@@ -621,18 +613,6 @@ onMounted(async () => {
scheduleAutoScrollStart()
}
await nextTick()
AOS.init({
offset: 40,
duration: 500,
easing: 'ease-out-cubic',
once: true,
mirror: false,
throttleDelay: 120,
debounceDelay: 80,
disableMutationObserver: true,
})
refreshAos()
window.addEventListener('scroll', handleScroll, { passive: true })
handleScroll()
})
@@ -677,7 +657,7 @@ watch(freeScrollSignature, restartAutoScroll)
align-items: center;
}
.formal-main {
font-family: var(--font-brush);
font-family: var(--font-calligraphy);
font-size: 25px;
line-height: 1.9;
font-weight: 800;
@@ -689,7 +669,7 @@ watch(freeScrollSignature, restartAutoScroll)
padding-top: 3.25rem;
}
.formal-side {
font-family: var(--font-brush);
font-family: var(--font-calligraphy);
color: #806f5c;
font-size: 15px;
line-height: 1.8;
@@ -701,16 +681,18 @@ watch(freeScrollSignature, restartAutoScroll)
.cover-kicker,
.schedule-kicker {
font-family: var(--font-display);
font-family: var(--font-calligraphy);
}
.cover-names {
font-family: var(--font-serif);
font-family: var(--font-calligraphy);
font-weight: 700;
}
.cover-date {
font-family: var(--font-number);
}
.schedule-title {
font-family: var(--font-serif);
font-family: var(--font-calligraphy);
font-weight: 700;
}
/* ---------- 婚礼流程 ---------- */
@@ -732,7 +714,7 @@ watch(freeScrollSignature, restartAutoScroll)
}
.schedule-title {
display: block; color: #a88c6b; font-size: 26px; line-height: 1.25;
letter-spacing: 0.28em; padding-left: 0.28em; font-weight: 400;
letter-spacing: 0.28em; padding-left: 0.28em; font-weight: 700;
}
.schedule-kicker {
display: block; margin-top: 10px; color: #8A8680; font-size: 10px;
@@ -1042,7 +1024,7 @@ watch(freeScrollSignature, restartAutoScroll)
.cover-filigree-top { top: 42px; }
.cover-filigree-bottom { bottom: 42px; transform: translateX(-50%) rotate(180deg); }
.emblem-inner { position: relative; z-index: 1; width: 100%; text-align: center; color: #5b4a36; padding: 42px 16px 34px; }
.emblem-kicker { display: block; letter-spacing: 0.48em; font-size: 10px; color: #a88c6b; text-transform: uppercase; margin-bottom: 24px; padding-left: 0.48em; font-family: var(--font-display); }
.emblem-kicker { display: block; letter-spacing: 0.48em; font-size: 18px; color: #a88c6b; margin-bottom: 24px; padding-left: 0.48em; font-family: var(--font-calligraphy); font-weight: 700; }
.emblem-seal {
width: 56px; height: 56px; margin: 0 auto 22px; border-radius: 9999px;
display: flex; align-items: center; justify-content: center;
@@ -1050,17 +1032,17 @@ watch(freeScrollSignature, restartAutoScroll)
background: rgba(255,255,255,0.34); box-shadow: inset 0 0 0 5px rgba(168,140,107,0.07);
}
.emblem-seal i { font-size: 18px; }
.emblem-names { font-family: var(--font-serif); font-size: clamp(31px, 8vw, 44px); line-height: 1.22; letter-spacing: 0.14em; font-weight: 500; color: #403527; }
.emblem-names .amp { font-style: italic; color: #b89a78; margin: 0 9px; font-family: var(--font-display); font-weight: 300; }
.emblem-names { font-family: var(--font-calligraphy); font-size: clamp(25px, 8vw, 35px); line-height: 1.22; letter-spacing: 0.14em; font-weight: 700; color: #403527; }
.emblem-names .amp { font-style: italic; color: #b89a78; margin: 0 9px; font-family: var(--font-calligraphy); font-weight: 700; }
.emblem-rule { width: 72px; height: 1px; background: linear-gradient(90deg, transparent, #b89a78, transparent); margin: 22px auto 18px; }
.emblem-date { font-family: var(--font-number); font-size: 12px; letter-spacing: 0.34em; padding-left: 0.34em; color: #806a4d; }
.emblem-date { font-family: var(--font-calligraphy); font-size: 12px; letter-spacing: 0.34em; padding-left: 0.34em; color: #806a4d; }
.emblem-invite-title {
margin-top: 30px; color: #4a3f30; font-family: var(--font-brush);
margin-top: 30px; color: #4a3f30; font-family: var(--font-calligraphy);
font-size: 24px; line-height: 1.35; letter-spacing: 0.1em; font-weight: 800;
}
.emblem-invite-copy {
max-width: 276px; margin: 13px auto 0; color: #5f503d;
font-family: var(--font-kai); font-size: 15px; line-height: 2.05;
font-family: var(--font-calligraphy); font-size: 15px; line-height: 2.05;
letter-spacing: 0.09em; font-weight: 600;
}
.emblem-hint { margin-top: 30px; font-size: 12px; letter-spacing: 0.26em; color: #9b825e;
@@ -1090,7 +1072,7 @@ watch(freeScrollSignature, restartAutoScroll)
.ending-kicker {
display: flex; flex-direction: column; align-items: center; gap: 10px;
margin-bottom: 18px; color: #a88c6b; font-size: 10px; letter-spacing: 0.45em;
text-transform: uppercase; padding-left: 0.45em; font-family: var(--font-display);
text-transform: uppercase; padding-left: 0.45em; font-family: var(--font-calligraphy); font-weight: 700;
}
.ending-kicker i {
display: block; width: 34px; height: 1px;
@@ -1108,11 +1090,11 @@ watch(freeScrollSignature, restartAutoScroll)
}
.ending-title {
display: block; color: #a88c6b; font-size: 20px; line-height: 1.3;
letter-spacing: 0.28em; padding-left: 0.28em; font-weight: 300; font-family: var(--font-serif);
letter-spacing: 0.28em; padding-left: 0.28em; font-weight: 700; font-family: var(--font-calligraphy);
}
.ending-names {
display: block; margin-top: 10px; color: #3A3A3A; font-size: 14px;
letter-spacing: 0.16em; font-family: var(--font-display);
letter-spacing: 0.16em; font-family: var(--font-calligraphy); font-weight: 700;
}
.ending-date {
display: block; margin-top: 8px; color: #8A8680; font-size: 10px;