Files
aida_front/src/views/AwardPage/components/Bloom.vue

201 lines
4.1 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="bloom flex flex-col align-center">
<div
class="title"
ref="titleRef"
>
Bloom Your Creativity
</div>
<div
class="season"
ref="subtitleRef"
>
Theme of 2026
</div>
<div
class="desc"
ref="textRef"
>
<p class="section-1">
The
<span class="arial-bold">AiDA Global Design Award 2026</span>
is an
<span class="arial-bold">international design competition</span>
hosted by
<span class="arial-bold">CodeCreate</span>
, a globally leading
<br />
<span class="arial-bold">AI fashion solutions provider,</span>
celebrating the future of creativity powered by artificial intelligence.
<br />
Bringing together designers from around the world, AiDA empowers AI as a
creative partnerpushing fashion beyond
<br />
traditional boundaries and unlocking new possibilities where technology
amplifies human imagination.
</p>
<p class="section-2">
Under the theme
<span class="arial-bold">
Where Imagination Meets Innovation, Creativity Blooms,
</span>
participants are invited to transform bold ideas
<br />
into extraordinary designs, seamlessly merging human artistry with
artificial intelligence to shape the next era of fashion.
</p>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { gsap } from 'gsap'
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;
.section-2{
margin-top: 4rem;
}
}
}
</style>