更新页面效果
This commit is contained in:
@@ -47,6 +47,10 @@
|
||||
<a-form-item label="农历 / 星期">
|
||||
<a-input v-model:value="cfg.lunar" placeholder="如 农历四月初四 星期三" />
|
||||
</a-form-item>
|
||||
<a-form-item label="日历圈选日期">
|
||||
<a-input v-model:value="cfg.calendarDate" placeholder="如 2026-09-04" />
|
||||
<div class="text-[11px] text-[#8A8680] mt-1">前台婚礼日历会展示该日期所在月份,并用爱心圈出这一天。</div>
|
||||
</a-form-item>
|
||||
<a-form-item label="酒店名称">
|
||||
<a-input v-model:value="cfg.hotel" placeholder="宴会酒店" />
|
||||
</a-form-item>
|
||||
@@ -100,6 +104,12 @@
|
||||
<a-form-item label="背景音乐">
|
||||
<div class="text-[12px] text-[#8A8680] leading-relaxed">多首背景音乐的上传、试听与「设为播放」请在 <span class="text-[#a88c6b]">背景音乐</span> 标签页管理。</div>
|
||||
</a-form-item>
|
||||
<a-form-item label="入场揭幕退场方式">
|
||||
<a-select v-model:value="cfg.introExitEffect">
|
||||
<a-select-option v-for="opt in INTRO_EXIT_EFFECTS" :key="opt.value" :value="opt.value">{{ opt.label }}</a-select-option>
|
||||
</a-select>
|
||||
<div class="text-[11px] text-[#8A8680] mt-1">点击开启请柬时的退场动画,可按婚礼调性选择更轻盈或更有仪式感的方式。</div>
|
||||
</a-form-item>
|
||||
<a-form-item label="滚动方式">
|
||||
<a-radio-group v-model:value="cfg.scrollMode">
|
||||
<a-radio value="snap">整页 / 分屏吸附滚动</a-radio>
|
||||
@@ -410,11 +420,13 @@ function defaultConfig() {
|
||||
groom: '李明', bride: '王华', date: '2026-05-20', lunar: '农历四月初四 星期三',
|
||||
hotel: '杭州星光万丽大酒店', address: '杭州市西湖区星光大道88号\n3楼大宴会厅',
|
||||
formalText1: '两姓联姻 一堂缔约', formalText2: '良缘永结 匹配同称', formalPageHeight: '100vh',
|
||||
calendarDate: '2026-09-04',
|
||||
heroImg: 'https://images.unsplash.com/photo-1583939003579-730e3918a45a?auto=format&fit=crop&w=800&q=80',
|
||||
endImg: 'https://images.unsplash.com/photo-1519741497674-611481863552?auto=format&fit=crop&w=800&q=80',
|
||||
musicList: [{ url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3', name: '背景音乐 1' }],
|
||||
activeMusicUrl: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
|
||||
scrollMode: 'snap', petalEnabled: true, bubbleEnabled: true, introEnabled: true,
|
||||
introExitEffect: 'wind',
|
||||
freeScrollInterval: 50, pageSwitchDuration: 800, firstScreenDuration: 4500,
|
||||
photoPages: [
|
||||
{ type: 'single', title: '初遇', subtitle: 'FIRST MET', desc: '世界那么大,还是遇见了你。\n于千万人之中,没有早一步也没有晚一步。', img1: 'https://images.unsplash.com/photo-1606800052052-a08af7148866?auto=format&fit=crop&w=600&q=80', height: '100vh', borderStyle: 'mat' },
|
||||
@@ -456,6 +468,12 @@ const HEIGHT_PRESETS = [
|
||||
{ label: '自适应(内容高度)', value: 'auto' },
|
||||
{ label: '自定义', value: '__custom__' },
|
||||
]
|
||||
const INTRO_EXIT_EFFECTS = [
|
||||
{ label: '风吹纸页', value: 'wind' },
|
||||
{ label: '翻书开启', value: 'book' },
|
||||
{ label: '上提淡出', value: 'lift' },
|
||||
{ label: '双门揭幕', value: 'doors' },
|
||||
]
|
||||
function heightSelectValue(page) {
|
||||
return heightFieldSelectValue(page.height)
|
||||
}
|
||||
@@ -688,6 +706,8 @@ onMounted(async () => {
|
||||
loaded.endImg = loaded.endImg || loaded.heroImg || cfg.endImg
|
||||
Object.assign(cfg, loaded)
|
||||
cfg.formalPageHeight = cfg.formalPageHeight || '100vh'
|
||||
cfg.calendarDate = cfg.calendarDate || '2026-09-04'
|
||||
cfg.introExitEffect = cfg.introExitEffect || 'wind'
|
||||
cfg.photoPages = (cfg.photoPages || []).map(ensurePageShape)
|
||||
setActivePhotoIndex(currentPhotoIndex.value)
|
||||
// 数值型参数兜底(兼容旧配置)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="wrapper relative w-full h-[100vh] bg-[#Fdfbf7] overflow-hidden text-[#2c2c2c]">
|
||||
|
||||
<!-- 入场揭幕帘幕(请柬封面) -->
|
||||
<div v-show="showIntro" class="curtain-root" :class="{ 'is-opening': introOpening }" @click="openInvitation" @transitionend="onIntroTransitionEnd">
|
||||
<div v-show="showIntro" class="curtain-root" :class="[{ 'is-opening': introOpening }, introExitClass]" @click="openInvitation">
|
||||
<div class="curtain-bg" :style="curtainBg"></div>
|
||||
<div class="curtain-veil"></div>
|
||||
<div class="curtain-door curtain-door-left"><span class="door-sheen"></span></div>
|
||||
@@ -129,6 +129,43 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 婚礼日历 -->
|
||||
<div class="page-section wedding-calendar-page px-6 py-10 relative" :class="data.scrollMode === 'snap' ? 'snap-start' : ''">
|
||||
<div v-reveal="'up'" class="calendar-card">
|
||||
<div class="calendar-kicker">Save The Date</div>
|
||||
<div class="calendar-title">
|
||||
<span>{{ calendarTitle.year }}</span>
|
||||
<i></i>
|
||||
<span>{{ calendarTitle.monthText }}</span>
|
||||
</div>
|
||||
<div class="calendar-date-line">{{ data.groom }} & {{ data.bride }} · {{ weddingDateText }}</div>
|
||||
<div class="calendar-weekdays">
|
||||
<span v-for="w in calendarWeekdays" :key="w">{{ w }}</span>
|
||||
</div>
|
||||
<div class="calendar-grid">
|
||||
<span
|
||||
v-for="(day, idx) in calendarDays"
|
||||
:key="idx"
|
||||
class="calendar-day"
|
||||
:class="{ 'is-empty': !day, 'is-selected': day === weddingDay }"
|
||||
>
|
||||
<span v-if="day" class="calendar-day-num">{{ day }}</span>
|
||||
<span v-if="day === weddingDay" class="heart-ring" aria-hidden="true">
|
||||
<svg viewBox="0 0 64 58" role="img">
|
||||
<path class="heart-brush heart-brush-shadow" d="M32 51 C17 39 8 30 8 19 C8 10 15 6 22 8 C27 9 30 13 32 17 C34 13 38 9 43 8 C51 7 57 12 57 21 C57 32 47 41 32 51 Z" />
|
||||
<path class="heart-brush heart-brush-main" d="M32 51 C17 39 8 30 8 19 C8 10 15 6 22 8 C27 9 30 13 32 17 C34 13 38 9 43 8 C51 7 57 12 57 21 C57 32 47 41 32 51 Z" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="calendar-note">
|
||||
<span>良辰已定</span>
|
||||
<i></i>
|
||||
<span>敬候光临</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 婚礼流程 -->
|
||||
<div class="page-section bg-transparent px-6 z-10 justify-center relative" :class="data.scrollMode === 'snap' ? 'snap-start' : ''">
|
||||
<div class="absolute inset-0 bg-[#Fdfbf7]/60 backdrop-blur-[2px] -z-10"></div>
|
||||
@@ -251,6 +288,8 @@ const DEFAULTS = {
|
||||
pageSwitchDuration: 800, // 页面切换速度:翻页动画时长 ms
|
||||
firstScreenDuration: 4500, // 首屏停留时间:首屏效果结束后再开始自动滚动
|
||||
formalPageHeight: '100vh',
|
||||
calendarDate: '2026-09-04',
|
||||
introExitEffect: 'wind',
|
||||
}
|
||||
|
||||
const data = ref({
|
||||
@@ -295,6 +334,42 @@ const firstScreenDuration = computed(() => {
|
||||
|
||||
const curtainBg = computed(() => ({ backgroundImage: `url(${data.value.heroImg})` }))
|
||||
const endImage = computed(() => data.value.endImg || data.value.heroImg)
|
||||
const introExitClass = computed(() => {
|
||||
const effect = ['wind', 'book', 'lift', 'doors'].includes(data.value.introExitEffect) ? data.value.introExitEffect : 'wind'
|
||||
return `intro-exit-${effect}`
|
||||
})
|
||||
const introExitDuration = computed(() => ({ wind: 1280, book: 1220, lift: 980, doors: 1180 }[data.value.introExitEffect] || 1280))
|
||||
|
||||
const calendarWeekdays = ['一', '二', '三', '四', '五', '六', '日']
|
||||
const monthNames = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
|
||||
const parsedCalendarDate = computed(() => {
|
||||
const m = /^(\d{4})-(\d{1,2})-(\d{1,2})/.exec(data.value.calendarDate || '')
|
||||
const fallback = { year: 2026, month: 9, day: 4 }
|
||||
if (!m) return fallback
|
||||
const year = Number(m[1])
|
||||
const month = Math.min(12, Math.max(1, Number(m[2])))
|
||||
const last = new Date(year, month, 0).getDate()
|
||||
const day = Math.min(last, Math.max(1, Number(m[3])))
|
||||
return { year, month, day }
|
||||
})
|
||||
const weddingDay = computed(() => parsedCalendarDate.value.day)
|
||||
const calendarTitle = computed(() => ({
|
||||
year: parsedCalendarDate.value.year,
|
||||
monthText: monthNames[parsedCalendarDate.value.month - 1],
|
||||
}))
|
||||
const weddingDateText = computed(() => {
|
||||
const d = parsedCalendarDate.value
|
||||
return `${d.year}年${d.month}月${d.day}日`
|
||||
})
|
||||
const calendarDays = computed(() => {
|
||||
const { year, month } = parsedCalendarDate.value
|
||||
const firstDay = new Date(year, month - 1, 1).getDay()
|
||||
const leading = (firstDay + 6) % 7
|
||||
const days = new Date(year, month, 0).getDate()
|
||||
const cells = [...Array.from({ length: leading }, () => null), ...Array.from({ length: days }, (_, i) => i + 1)]
|
||||
const trailing = (7 - (cells.length % 7)) % 7
|
||||
return [...cells, ...Array.from({ length: trailing }, () => null)]
|
||||
})
|
||||
|
||||
// 页面高度:支持 100vh / 80vh / 60vh / auto / 自定义 vh
|
||||
const sectionHeightStyle = (height) => {
|
||||
@@ -414,13 +489,6 @@ const completeIntro = () => {
|
||||
startAutoScroll()
|
||||
}
|
||||
|
||||
const onIntroTransitionEnd = (e) => {
|
||||
if (!introOpening.value) return
|
||||
if (!e.target?.classList?.contains('curtain-door-right')) return
|
||||
if (e.propertyName !== 'transform') return
|
||||
completeIntro()
|
||||
}
|
||||
|
||||
const toggleAutoScroll = () => {
|
||||
isAutoScroll.value = !isAutoScroll.value
|
||||
const el = scrollContainerRef.value
|
||||
@@ -433,7 +501,7 @@ const openInvitation = () => {
|
||||
if (introOpening.value) return
|
||||
clearTimeout(introTimer)
|
||||
introOpening.value = true
|
||||
introTimer = setTimeout(() => completeIntro(), 1800)
|
||||
introTimer = setTimeout(() => completeIntro(), introExitDuration.value)
|
||||
// 点击揭幕是明确的用户手势:直接尝试播放背景音乐(最可靠的自动播放路径)
|
||||
if (data.value.musicList.length) audio.play()
|
||||
}
|
||||
@@ -503,6 +571,8 @@ onMounted(async () => {
|
||||
? Number(loaded.firstScreenDuration)
|
||||
: DEFAULTS.firstScreenDuration
|
||||
loaded.formalPageHeight = loaded.formalPageHeight || DEFAULTS.formalPageHeight
|
||||
loaded.calendarDate = loaded.calendarDate || DEFAULTS.calendarDate
|
||||
loaded.introExitEffect = loaded.introExitEffect || DEFAULTS.introExitEffect
|
||||
data.value = { ...data.value, ...DEFAULTS, ...loaded }
|
||||
}
|
||||
} catch (e) { /* 使用默认配置 */ }
|
||||
@@ -589,6 +659,96 @@ onUnmounted(() => {
|
||||
font-family: var(--font-serif);
|
||||
}
|
||||
|
||||
/* ---------- 婚礼日历 ---------- */
|
||||
.wedding-calendar-page {
|
||||
min-height: 76vh;
|
||||
background:
|
||||
linear-gradient(180deg, rgba(253,251,247,0.72), rgba(247,246,242,0.94)),
|
||||
radial-gradient(circle at 18% 12%, rgba(232,201,210,0.18), transparent 30%),
|
||||
radial-gradient(circle at 82% 82%, rgba(168,140,107,0.12), transparent 28%);
|
||||
}
|
||||
.calendar-card {
|
||||
width: min(100%, 352px); margin: 0 auto; padding: 30px 24px 28px;
|
||||
color: #4a3f30; text-align: center; position: relative;
|
||||
background:
|
||||
linear-gradient(135deg, rgba(255,255,255,0.66), rgba(255,255,255,0.28)),
|
||||
repeating-linear-gradient(0deg, rgba(112,82,47,0.025) 0 1px, transparent 1px 8px),
|
||||
rgba(253,251,247,0.72);
|
||||
border: 1px solid rgba(168,140,107,0.24);
|
||||
box-shadow: 0 18px 50px rgba(95,70,39,0.13), inset 0 0 0 8px rgba(255,255,255,0.34);
|
||||
}
|
||||
.calendar-card::before {
|
||||
content: ''; position: absolute; inset: 12px;
|
||||
border: 1px solid rgba(168,140,107,0.16); pointer-events: none;
|
||||
}
|
||||
.calendar-kicker {
|
||||
color: #a88c6b; font-family: var(--font-display);
|
||||
font-size: 10px; letter-spacing: 0.46em; padding-left: 0.46em; text-transform: uppercase;
|
||||
}
|
||||
.calendar-title {
|
||||
display: flex; align-items: center; justify-content: center; gap: 14px;
|
||||
margin-top: 12px; color: #3f3428; font-family: var(--font-display);
|
||||
font-size: 30px; line-height: 1.2; letter-spacing: 0.12em;
|
||||
}
|
||||
.calendar-title i {
|
||||
width: 34px; height: 1px; background: linear-gradient(90deg, transparent, rgba(168,140,107,0.8), transparent);
|
||||
}
|
||||
.calendar-date-line {
|
||||
margin: 10px auto 22px; color: #806f5c; font-size: 11px;
|
||||
letter-spacing: 0.16em; font-family: var(--font-serif);
|
||||
}
|
||||
.calendar-weekdays,
|
||||
.calendar-grid {
|
||||
display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 8px;
|
||||
}
|
||||
.calendar-weekdays {
|
||||
margin-bottom: 9px; color: #a88c6b; font-size: 10px;
|
||||
font-family: var(--font-kai); font-weight: 700;
|
||||
}
|
||||
.calendar-day {
|
||||
position: relative; aspect-ratio: 1; display: flex; align-items: center; justify-content: center;
|
||||
color: #4b443c; font-family: var(--font-number); font-size: 15px;
|
||||
}
|
||||
.calendar-day.is-empty { visibility: hidden; }
|
||||
.calendar-day-num {
|
||||
position: relative; z-index: 2;
|
||||
}
|
||||
.calendar-day.is-selected .calendar-day-num {
|
||||
color: #8f4d5a; font-weight: 700; text-shadow: 0 1px 0 rgba(255,255,255,0.75);
|
||||
}
|
||||
.heart-ring {
|
||||
position: absolute; inset: -9px; display: flex; align-items: center; justify-content: center;
|
||||
z-index: 1; animation: heartBeat 1.65s ease-in-out infinite;
|
||||
filter: drop-shadow(0 6px 10px rgba(151,76,91,0.18));
|
||||
}
|
||||
.heart-ring svg {
|
||||
width: 56px; height: 50px; overflow: visible;
|
||||
}
|
||||
.heart-brush {
|
||||
fill: rgba(182,106,120,0.06);
|
||||
stroke: #a94f62;
|
||||
stroke-width: 4.2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-dasharray: 176;
|
||||
stroke-dashoffset: 176;
|
||||
animation: brushHeartDraw 1.25s cubic-bezier(0.18, 0.78, 0.24, 1) forwards;
|
||||
}
|
||||
.heart-brush-shadow {
|
||||
stroke: rgba(126,76,54,0.22);
|
||||
stroke-width: 6;
|
||||
transform: translate(1px, 1px) rotate(-2deg);
|
||||
animation-delay: .06s;
|
||||
}
|
||||
.calendar-note {
|
||||
display: flex; align-items: center; justify-content: center; gap: 10px;
|
||||
margin-top: 24px; color: #806f5c; font-family: var(--font-kai);
|
||||
font-size: 13px; font-weight: 700; letter-spacing: 0.2em;
|
||||
}
|
||||
.calendar-note i {
|
||||
width: 20px; height: 1px; background: rgba(168,140,107,0.45);
|
||||
}
|
||||
|
||||
/* ---------- 入场揭幕(雅致象牙金) ---------- */
|
||||
.curtain-root { position: fixed; inset: 0; z-index: 100; overflow: hidden; cursor: pointer; font-family: var(--font-sans); background: #fbf6ef; perspective: 1200px; }
|
||||
.curtain-bg {
|
||||
@@ -629,7 +789,45 @@ onUnmounted(() => {
|
||||
position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; z-index: 3; padding: 28px;
|
||||
transition: opacity 0.8s ease, transform 0.9s ease; animation: emblemIn 1.1s ease both;
|
||||
}
|
||||
.curtain-root.is-opening .curtain-emblem { opacity: 0; transform: scale(1.25); }
|
||||
.curtain-root.is-opening .curtain-emblem { opacity: 0; transform: scale(0.98); }
|
||||
.curtain-root.is-opening .curtain-veil { animation: veilFade 1.2s ease both; }
|
||||
.curtain-root.is-opening.intro-exit-wind .curtain-emblem {
|
||||
opacity: 1; transform: none;
|
||||
}
|
||||
.curtain-root.is-opening.intro-exit-wind .curtain-door-left { transform: translateX(-82%) rotateY(-8deg); }
|
||||
.curtain-root.is-opening.intro-exit-wind .curtain-door-right { transform: translateX(82%) rotateY(8deg); }
|
||||
.curtain-root.is-opening.intro-exit-wind .emblem-inner { animation: inviteContentExit 520ms cubic-bezier(0.4, 0, 1, 1) 90ms forwards; }
|
||||
.curtain-root.is-opening.intro-exit-wind .invite-cover {
|
||||
transform-origin: 72% 24%;
|
||||
will-change: transform, opacity, filter;
|
||||
animation: inviteWindExit 1180ms cubic-bezier(0.4, 0, 1, 1) forwards;
|
||||
}
|
||||
.curtain-root.is-opening.intro-exit-book .curtain-emblem {
|
||||
opacity: 1; transform: none;
|
||||
}
|
||||
.curtain-root.is-opening.intro-exit-book .emblem-inner { animation: inviteContentExit 480ms cubic-bezier(0.4, 0, 1, 1) 70ms forwards; }
|
||||
.curtain-root.is-opening.intro-exit-book .invite-cover {
|
||||
transform-style: preserve-3d;
|
||||
transform-origin: 0% 50%;
|
||||
will-change: transform, opacity, filter;
|
||||
animation: inviteBookExit 1120ms cubic-bezier(0.4, 0, 1, 1) forwards;
|
||||
}
|
||||
.curtain-root.is-opening.intro-exit-lift .curtain-emblem {
|
||||
opacity: 1; transform: none;
|
||||
}
|
||||
.curtain-root.is-opening.intro-exit-lift .emblem-inner { animation: inviteContentExit 420ms cubic-bezier(0.4, 0, 1, 1) 50ms forwards; }
|
||||
.curtain-root.is-opening.intro-exit-lift .invite-cover {
|
||||
transform-origin: 50% 18%;
|
||||
will-change: transform, opacity, filter;
|
||||
animation: inviteLiftExit 900ms cubic-bezier(0.4, 0, 1, 1) forwards;
|
||||
}
|
||||
.curtain-root.is-opening.intro-exit-doors .curtain-emblem {
|
||||
opacity: 1; transform: none;
|
||||
}
|
||||
.curtain-root.is-opening.intro-exit-doors .emblem-inner { animation: inviteContentExit 430ms cubic-bezier(0.4, 0, 1, 1) forwards; }
|
||||
.curtain-root.is-opening.intro-exit-doors .invite-cover {
|
||||
animation: inviteDoorsExit 860ms cubic-bezier(0.4, 0, 1, 1) forwards;
|
||||
}
|
||||
.invite-cover {
|
||||
position: relative; width: min(82vw, 360px); min-height: min(72vh, 560px);
|
||||
display: flex; align-items: center; justify-content: center; padding: 34px 24px;
|
||||
@@ -863,4 +1061,48 @@ onUnmounted(() => {
|
||||
|
||||
@keyframes emblemIn { from { opacity: 0; transform: scale(0.85) translateY(10px); } to { opacity: 1; transform: scale(1) translateY(0); } }
|
||||
@keyframes hintPulse { 0%,100% { transform: scale(1); opacity: 0.6; } 50% { transform: scale(1.7); opacity: 1; } }
|
||||
@keyframes heartBeat {
|
||||
0%, 100% { transform: scale(1); opacity: .92; }
|
||||
18% { transform: scale(1.16); opacity: 1; }
|
||||
34% { transform: scale(.96); }
|
||||
52% { transform: scale(1.1); }
|
||||
}
|
||||
@keyframes brushHeartDraw {
|
||||
0% { stroke-dashoffset: 176; opacity: .34; }
|
||||
66% { stroke-dashoffset: 0; opacity: 1; }
|
||||
100% { stroke-dashoffset: 0; opacity: 1; }
|
||||
}
|
||||
@keyframes veilFade {
|
||||
from { opacity: 1; }
|
||||
to { opacity: 0; }
|
||||
}
|
||||
@keyframes inviteContentExit {
|
||||
0% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
|
||||
100% { opacity: 0; transform: translateY(-7px) scale(.975); filter: blur(1px); }
|
||||
}
|
||||
@keyframes inviteWindExit {
|
||||
0% { opacity: 1; transform: translate3d(0, 0, 0) rotate(0deg) scale(1); filter: blur(0); }
|
||||
8% { opacity: 1; transform: translate3d(-7px, 5px, 0) rotate(-1.4deg) scale(.982); filter: blur(0); }
|
||||
28% { opacity: 1; transform: translate3d(20px, -18px, 0) rotate(4deg) scale(.985); filter: blur(0); }
|
||||
58% { opacity: .82; transform: translate3d(46vw, -18vh, 0) rotate(13deg) scale(.93); filter: blur(.3px); }
|
||||
100% { opacity: 0; transform: translate3d(96vw, -42vh, 0) rotate(24deg) scale(.82); filter: blur(2px); }
|
||||
}
|
||||
@keyframes inviteBookExit {
|
||||
0% { opacity: 1; transform: rotateY(0deg) translateX(0) translateZ(0) scale(1); filter: brightness(1); }
|
||||
9% { opacity: 1; transform: rotateY(0deg) translateX(7px) translateZ(0) scale(.985); filter: brightness(.98); }
|
||||
38% { opacity: 1; transform: rotateY(-42deg) translateX(-10px) translateZ(36px) scale(.975); filter: brightness(.94); }
|
||||
72% { opacity: .72; transform: rotateY(-88deg) translateX(-34px) translateZ(26px) scale(.95); filter: brightness(.9) blur(.4px); }
|
||||
100% { opacity: 0; transform: rotateY(-112deg) translateX(-70px) translateZ(0) scale(.9); filter: brightness(.85) blur(1.8px); }
|
||||
}
|
||||
@keyframes inviteLiftExit {
|
||||
0% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
|
||||
10% { opacity: 1; transform: translateY(8px) scale(.975, .988); filter: blur(0); }
|
||||
46% { opacity: .96; transform: translateY(-28px) scale(1.018, 1.03); filter: blur(0); }
|
||||
100% { opacity: 0; transform: translateY(-116px) scale(1.08); filter: blur(2.4px); }
|
||||
}
|
||||
@keyframes inviteDoorsExit {
|
||||
0% { opacity: 1; transform: translateY(0) scale(1); filter: blur(0); }
|
||||
12% { opacity: 1; transform: translateY(4px) scale(.98); filter: blur(0); }
|
||||
100% { opacity: 0; transform: translateY(-12px) scale(.94); filter: blur(1.4px); }
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user