255 lines
5.6 KiB
Vue
255 lines
5.6 KiB
Vue
<template>
|
|
<div
|
|
class="prizes-container container flex align-center space-between"
|
|
ref="prizesRef"
|
|
>
|
|
<div class="left flex flex-col flex-center">
|
|
<div
|
|
class="title"
|
|
ref="prizesTitleRef"
|
|
>
|
|
Award & Prizes
|
|
</div>
|
|
<!-- <img src="@/assets/images/award/bloom_logo.png" class="logo" /> -->
|
|
<div
|
|
class="desc"
|
|
ref="prizesSubTitleRef"
|
|
>
|
|
Recongnition
|
|
</div>
|
|
</div>
|
|
<div
|
|
class="right"
|
|
ref="prizesRightRef"
|
|
>
|
|
<div
|
|
class="prize-item flex flex-col flex-center"
|
|
:class="{ smaller: item.smaller }"
|
|
v-for="item in prizes"
|
|
:key="item.name"
|
|
>
|
|
<div class="prize-money">
|
|
{{ item.money }}
|
|
</div>
|
|
<div class="prize-name">{{ item.name }}</div>
|
|
<div class="prize-desc flex flex-col flex-center">
|
|
<div
|
|
class="desc-item"
|
|
v-for="el in item.desc"
|
|
>
|
|
{{ el }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { nextTick, onBeforeUnmount, onMounted, ref } from 'vue'
|
|
import { gsap } from 'gsap'
|
|
|
|
const prizes = [
|
|
{
|
|
money: 'US$5000',
|
|
name: 'Grand Awards',
|
|
desc: ['Cash Award', 'Award Ceritificate', 'Global Media Exposure']
|
|
},
|
|
{
|
|
money: 'US$3000',
|
|
name: 'Gold Awards',
|
|
desc: ['Cash Award', 'Award Ceritificate', 'Global Media Exposure']
|
|
},
|
|
{
|
|
money: 'US$2000',
|
|
name: 'Silver Awards',
|
|
desc: ['Cash Award', 'Award Ceritificate', 'Global Media Exposure']
|
|
},
|
|
{
|
|
money: 'Award\nCertification',
|
|
name: 'Finalists',
|
|
desc: ['Award Ceritificate', 'Global Media Exposure'],
|
|
smaller: true
|
|
}
|
|
]
|
|
|
|
const prizesRef = ref<HTMLElement | null>(null)
|
|
const prizesTitleRef = ref<HTMLElement | null>(null)
|
|
const prizesSubTitleRef = ref<HTMLElement | null>(null)
|
|
const prizesRightRef = ref<HTMLElement | null>(null)
|
|
const hasPlayedPrizesAnim = ref(false)
|
|
let prizesObserver: IntersectionObserver | null = null
|
|
|
|
const setupPrizesInitialState = () => {
|
|
const titleEls = [prizesTitleRef.value, prizesSubTitleRef.value].filter(
|
|
Boolean
|
|
) as HTMLElement[]
|
|
if (titleEls.length) {
|
|
gsap.set(titleEls, {
|
|
opacity: 0,
|
|
scale: 0,
|
|
transformOrigin: '50% 50%'
|
|
})
|
|
}
|
|
if (prizesRightRef.value) {
|
|
gsap.set(prizesRightRef.value, {
|
|
'opacity': 0,
|
|
'y': 40,
|
|
'scale': 1.08,
|
|
'--prize-row-gap': '2rem',
|
|
'--prize-col-gap': '2rem'
|
|
})
|
|
}
|
|
}
|
|
|
|
const playPrizesAnimation = () => {
|
|
if (hasPlayedPrizesAnim.value) return
|
|
const titleEls = [prizesTitleRef.value, prizesSubTitleRef.value].filter(
|
|
Boolean
|
|
) as HTMLElement[]
|
|
|
|
const tl = gsap.timeline({ defaults: { ease: 'power2.out' } })
|
|
if (titleEls.length) {
|
|
tl.to(titleEls, {
|
|
opacity: 1,
|
|
scale: 1,
|
|
duration: 0.6,
|
|
ease: 'back.out(1.6)',
|
|
stagger: 0.1
|
|
})
|
|
}
|
|
if (prizesRightRef.value) {
|
|
tl.to(
|
|
prizesRightRef.value,
|
|
{
|
|
'opacity': 1,
|
|
'y': 0,
|
|
'scale': 1,
|
|
'--prize-row-gap': '4.2rem',
|
|
'--prize-col-gap': '4.4rem',
|
|
'duration': 0.55,
|
|
'ease': 'back.out(1.4)'
|
|
},
|
|
titleEls.length ? '-=0.15' : 0
|
|
)
|
|
}
|
|
|
|
hasPlayedPrizesAnim.value = true
|
|
prizesObserver?.disconnect()
|
|
}
|
|
|
|
onMounted(() => {
|
|
nextTick(() => {
|
|
setupPrizesInitialState()
|
|
if ('IntersectionObserver' in window) {
|
|
prizesObserver = new IntersectionObserver(
|
|
entries => {
|
|
entries.forEach(entry => {
|
|
if (entry.isIntersecting) {
|
|
playPrizesAnimation()
|
|
}
|
|
})
|
|
},
|
|
{ threshold: 0.25 }
|
|
)
|
|
if (prizesRef.value) prizesObserver.observe(prizesRef.value)
|
|
} else {
|
|
playPrizesAnimation()
|
|
}
|
|
})
|
|
})
|
|
|
|
onBeforeUnmount(() => {
|
|
prizesObserver?.disconnect()
|
|
})
|
|
</script>
|
|
|
|
<style scoped lang="less">
|
|
.prizes-container {
|
|
background: url('@/assets/images/award/prizes_bg.png') no-repeat;
|
|
background-size: 100% 100%;
|
|
padding: 0 21.4rem 0 34.2rem;
|
|
box-sizing: border-box;
|
|
.left {
|
|
row-gap: 3.6rem;
|
|
.title {
|
|
text-align: center;
|
|
font-family: 'PoppinsBold';
|
|
font-weight: 600;
|
|
font-size: 4rem;
|
|
color: #fff;
|
|
}
|
|
.desc {
|
|
text-align: center;
|
|
color: #f95750;
|
|
font-family: 'Poppins';
|
|
font-weight: 400;
|
|
font-size: 3rem;
|
|
}
|
|
}
|
|
.right {
|
|
// height: 45.4rem;
|
|
// padding: 4.6rem 6.1rem 4.6rem 0;
|
|
box-sizing: border-box;
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
grid-template-rows: repeat(2, 1fr);
|
|
row-gap: var(--prize-row-gap, 4.2rem);
|
|
column-gap: var(--prize-col-gap, 4.4rem);
|
|
// flex: 1;
|
|
.prize-item {
|
|
width: 35.5rem;
|
|
height: 32.8rem;
|
|
color: #fff;
|
|
padding: 4.5rem 0 4.8rem 0;
|
|
justify-content: space-between;
|
|
background: url('@/assets/images/award/first_bg.png') no-repeat;
|
|
background-size: 100% 100%;
|
|
&:nth-of-type(2) {
|
|
background: url('@/assets/images/award/second_bg.png') no-repeat;
|
|
background-size: 100% 100%;
|
|
}
|
|
&:nth-of-type(3) {
|
|
background: url('@/assets/images/award/grand_bg.png') no-repeat;
|
|
background-size: 100% 100%;
|
|
}
|
|
&:nth-of-type(4) {
|
|
background: url('@/assets/images/award/certification_bg.png')
|
|
no-repeat;
|
|
background-size: 100% 100%;
|
|
}
|
|
&.smaller {
|
|
.prize-money {
|
|
font-size: 3.6rem;
|
|
line-height: 3.8rem;
|
|
}
|
|
}
|
|
.prize-money {
|
|
font-family: 'PoppinsBold';
|
|
font-weight: bold;
|
|
font-size: 4rem;
|
|
white-space: pre-line;
|
|
text-align: center;
|
|
line-height: 7.6rem;
|
|
&.smaller {
|
|
font-size: 3.6rem;
|
|
}
|
|
}
|
|
.prize-name {
|
|
font-family: 'PoppinsMedium';
|
|
font-weight: 500;
|
|
font-size: 2.8rem;
|
|
}
|
|
.prize-desc {
|
|
color: #e0e0e0;
|
|
font-family: 'Arial';
|
|
font-weight: 400;
|
|
font-size: 2rem;
|
|
line-height: 3rem;
|
|
height: 8.9rem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|