203 lines
4.1 KiB
Vue
203 lines
4.1 KiB
Vue
<template>
|
|
<div class="bloom flex flex-col align-center">
|
|
<div
|
|
class="title"
|
|
ref="titleRef"
|
|
>
|
|
{{ $t('AwardsPage.bloomYourCreativity') }}
|
|
</div>
|
|
|
|
<div
|
|
class="season"
|
|
ref="subtitleRef"
|
|
>
|
|
{{ $t('AwardsPage.themeOf2026') }}
|
|
</div>
|
|
<div
|
|
class="desc"
|
|
ref="textRef"
|
|
>
|
|
<p class="section-1">
|
|
{{ $t('AwardsPage.bloomText.desc1.regular1') }}
|
|
<span class="arial-bold">
|
|
{{ $t('AwardsPage.bloomText.desc1.bold1') }}
|
|
</span>
|
|
{{ $t('AwardsPage.bloomText.desc1.regular2') }}
|
|
<span class="arial-bold">
|
|
{{ $t('AwardsPage.bloomText.desc1.bold2') }}
|
|
</span>
|
|
{{ $t('AwardsPage.bloomText.desc1.regular3') }}
|
|
<span class="arial-bold">
|
|
{{ $t('AwardsPage.bloomText.desc1.bold3') }}
|
|
</span>
|
|
{{ $t('AwardsPage.bloomText.desc1.regular4') }}
|
|
<span class="arial-bold">
|
|
{{ $t('AwardsPage.bloomText.desc1.bold4') }}
|
|
</span>
|
|
{{ $t('AwardsPage.bloomText.desc1.regular5') }}
|
|
</p>
|
|
<p class="section-2">
|
|
{{ $t('AwardsPage.bloomText.desc2.regular1') }}
|
|
<span class="arial-bold">
|
|
{{ $t('AwardsPage.bloomText.desc2.bold1') }}
|
|
</span>
|
|
{{ $t('AwardsPage.bloomText.desc2.regular2') }}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
|
|
import { useI18n } from 'vue-i18n'
|
|
import { gsap } from 'gsap'
|
|
|
|
const { t } = useI18n()
|
|
|
|
const titleRef = ref<HTMLElement | null>(null)
|
|
const subtitleRef = ref<HTMLElement | null>(null)
|
|
const textRef = ref<HTMLElement | null>(null)
|
|
|
|
const hasPlayedBloomAnim = ref(false)
|
|
let bloomObserver: IntersectionObserver | null = null
|
|
|
|
const setupBloomInitialState = () => {
|
|
const titleEls = [titleRef.value, subtitleRef.value].filter(
|
|
Boolean
|
|
) as HTMLElement[]
|
|
if (titleEls.length) {
|
|
gsap.set(titleEls, {
|
|
opacity: 0,
|
|
// start larger than final size, then animate down to scale:1
|
|
scale: 1.6,
|
|
transformOrigin: '50% 50%'
|
|
})
|
|
}
|
|
|
|
if (textRef.value) {
|
|
// start below and hidden
|
|
gsap.set(textRef.value, {
|
|
opacity: 0,
|
|
y: 60
|
|
})
|
|
}
|
|
}
|
|
|
|
const playBloomAnimation = () => {
|
|
if (hasPlayedBloomAnim.value) return
|
|
const titleEls = [titleRef.value, subtitleRef.value].filter(
|
|
Boolean
|
|
) as HTMLElement[]
|
|
const textEl = textRef.value
|
|
if (!titleEls.length || !textEl) return
|
|
|
|
const tl = gsap.timeline({ defaults: { ease: 'power2.out' } })
|
|
|
|
tl.to(titleEls, {
|
|
opacity: 1,
|
|
scale: 1,
|
|
duration: 0.9,
|
|
ease: 'back.out(1.6)',
|
|
stagger: 0.12
|
|
})
|
|
|
|
tl.to(
|
|
textEl,
|
|
{
|
|
opacity: 1,
|
|
y: -12,
|
|
scale: 1.05,
|
|
duration: 0.3,
|
|
ease: 'power2.out'
|
|
},
|
|
'-=0.3'
|
|
)
|
|
tl.to(
|
|
textEl,
|
|
{
|
|
y: 0,
|
|
scale: 1,
|
|
duration: 0.18,
|
|
ease: 'bounce.out'
|
|
},
|
|
'+=0.08'
|
|
)
|
|
|
|
hasPlayedBloomAnim.value = true
|
|
bloomObserver?.disconnect()
|
|
}
|
|
|
|
onMounted(() => {
|
|
nextTick(() => {
|
|
setupBloomInitialState()
|
|
if ('IntersectionObserver' in window) {
|
|
bloomObserver = new IntersectionObserver(
|
|
entries => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
playBloomAnimation()
|
|
}
|
|
})
|
|
},
|
|
{ threshold: 0.3 }
|
|
)
|
|
if (titleRef.value) {
|
|
bloomObserver.observe(titleRef.value)
|
|
}
|
|
} else {
|
|
// fallback
|
|
playBloomAnimation()
|
|
}
|
|
})
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
bloomObserver?.disconnect()
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
p {
|
|
margin: 0;
|
|
padding: 0;
|
|
}
|
|
.arial-bold {
|
|
font-family: 'ArialBold';
|
|
font-weight: 700;
|
|
}
|
|
.bloom {
|
|
height: 108rem;
|
|
padding-top: 12.8rem;
|
|
font-family: 'Poppins';
|
|
background: url('@/assets/images/award/bloom_bg.png') no-repeat;
|
|
background-size: 100% 100%;
|
|
.title {
|
|
font-size: 4rem;
|
|
color: #232323;
|
|
margin-bottom: 2.4rem;
|
|
}
|
|
.logo {
|
|
margin-bottom: 2.2rem;
|
|
}
|
|
.season {
|
|
font-size: 3rem;
|
|
color: #c7342c;
|
|
margin-bottom: 6.6rem;
|
|
}
|
|
.desc {
|
|
font-family: 'Arial';
|
|
font-weight: 400;
|
|
font-size: 2.4rem;
|
|
color: #585858;
|
|
text-align: center;
|
|
padding: 0 21.5rem;
|
|
line-height: 4.5rem;
|
|
margin-bottom: 12.3rem;
|
|
white-space: pre-line;
|
|
.section-2 {
|
|
margin-top: 4rem;
|
|
}
|
|
}
|
|
}
|
|
</style>
|