style: slogan区域移动端样式
This commit is contained in:
@@ -1,156 +1,280 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div class="blocks-list flex" ref="root" :class="{ 'in-view': inView }">
|
||||||
class="blocks-list flex"
|
<div
|
||||||
ref="root"
|
class="block-item flex flex-col flex-center"
|
||||||
:class="{ 'in-view': inView }"
|
v-for="(item, idx) in blocksList"
|
||||||
>
|
:key="item.number"
|
||||||
<div
|
:style="{ '--delay': `${idx * 0.18}s` }"
|
||||||
class="block-item flex flex-col flex-center"
|
>
|
||||||
v-for="(item, idx) in blocksList"
|
<div class="number">{{ $t(item.number) }}</div>
|
||||||
:key="item.number"
|
<div class="label">{{ $t(item.label) }}</div>
|
||||||
:style="{ '--delay': `${idx * 0.18}s` }"
|
<div class="line"></div>
|
||||||
>
|
</div>
|
||||||
<div class="number">{{ $t(item.number) }}</div>
|
</div>
|
||||||
<div class="label">{{ $t(item.label) }}</div>
|
|
||||||
<div class="line"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, onMounted, onUnmounted } from 'vue'
|
import { computed, ref, onMounted, onUnmounted } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const blocksList = ref([
|
const blocksList = ref([
|
||||||
{
|
{
|
||||||
number: 'AwardsPage.totalCashPrizes',
|
number: 'AwardsPage.totalCashPrizes',
|
||||||
label: 'AwardsPage.totalCashPrizesLabel'
|
label: 'AwardsPage.totalCashPrizesLabel'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
number: 'AwardsPage.globalMediaExpose',
|
number: 'AwardsPage.globalMediaExpose',
|
||||||
label: 'AwardsPage.globalMediaExposeLabel'
|
label: 'AwardsPage.globalMediaExposeLabel'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
number: 'AwardsPage.networkingOpportunities',
|
number: 'AwardsPage.networkingOpportunities',
|
||||||
label: 'AwardsPage.networkingOpportunitiesLabel'
|
label: 'AwardsPage.networkingOpportunitiesLabel'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
number: 'AwardsPage.awardCeremonyHongKong',
|
number: 'AwardsPage.awardCeremonyHongKong',
|
||||||
label: 'AwardsPage.awardCeremonyLabel'
|
label: 'AwardsPage.awardCeremonyLabel'
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
const root = ref<HTMLElement | null>(null)
|
const root = ref<HTMLElement | null>(null)
|
||||||
const inView = ref(false)
|
const inView = ref(false)
|
||||||
let io: IntersectionObserver | null = null
|
let io: IntersectionObserver | null = null
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
io = new IntersectionObserver(
|
io = new IntersectionObserver(
|
||||||
entries => {
|
(entries) => {
|
||||||
for (const entry of entries) {
|
for (const entry of entries) {
|
||||||
if (entry.isIntersecting) {
|
if (entry.isIntersecting) {
|
||||||
// 延迟 0.5s 后触发动画并断开观察
|
// 延迟 0.5s 后触发动画并断开观察
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
inView.value = true
|
inView.value = true
|
||||||
}, 500)
|
}, 500)
|
||||||
if (io) {
|
if (io) {
|
||||||
io.disconnect()
|
io.disconnect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ threshold: 0.05 }
|
{ threshold: 0.05 }
|
||||||
)
|
)
|
||||||
if (root.value) {
|
if (root.value) {
|
||||||
io.observe(root.value)
|
io.observe(root.value)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
io?.disconnect()
|
io?.disconnect()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.blocks-list {
|
.blocks-list {
|
||||||
height: 31.4rem;
|
height: 31.4rem;
|
||||||
background: linear-gradient(98.55deg, #232323 18.22%, #898989 101.1%);
|
background: linear-gradient(98.55deg, #232323 18.22%, #898989 101.1%);
|
||||||
|
|
||||||
.block-item {
|
.block-item {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
position: relative;
|
position: relative;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
row-gap: 3rem;
|
row-gap: 3rem;
|
||||||
/* text scale-in animations */
|
/* text scale-in animations */
|
||||||
.number {
|
.number {
|
||||||
font-size: 3.6rem;
|
font-size: 3.6rem;
|
||||||
font-family: 'PoppinsBold';
|
font-family: 'PoppinsBold';
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
will-change: transform, opacity;
|
will-change: transform, opacity;
|
||||||
}
|
}
|
||||||
.label {
|
.label {
|
||||||
font-size: 2.4rem;
|
font-size: 2.4rem;
|
||||||
font-family: 'Arial';
|
font-family: 'Arial';
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
letter-spacing: 0.05em;
|
letter-spacing: 0.05em;
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
will-change: transform, opacity;
|
will-change: transform, opacity;
|
||||||
}
|
}
|
||||||
/* vertical line grows top -> bottom */
|
/* vertical line grows top -> bottom */
|
||||||
.line {
|
.line {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
/* 固定 top 为最终高度的一半位置,这样 height 从 0 -> 27.4rem 时会从上向下增长 */
|
/* 固定 top 为最终高度的一半位置,这样 height 从 0 -> 27.4rem 时会从上向下增长 */
|
||||||
top: calc(50% - 13.7rem);
|
top: calc(50% - 13.7rem);
|
||||||
width: 0.1rem;
|
width: 0.1rem;
|
||||||
height: 0;
|
height: 0;
|
||||||
background-color: #8d8d8d;
|
background-color: #8d8d8d;
|
||||||
will-change: height;
|
will-change: height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 当组件进入视口并且等待 0.5s 后,.in-view 会加入根节点,下面规则触发动画 */
|
/* 当组件进入视口并且等待 0.5s 后,.in-view 会加入根节点,下面规则触发动画 */
|
||||||
.in-view .block-item .number {
|
.in-view .block-item .number {
|
||||||
animation: scaleIn 0.48s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
animation: scaleIn 0.48s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
||||||
animation-delay: var(--delay);
|
animation-delay: var(--delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
.in-view .block-item .label {
|
.in-view .block-item .label {
|
||||||
animation: scaleIn 0.48s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
animation: scaleIn 0.48s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
||||||
animation-delay: calc(var(--delay) + 0.12s);
|
animation-delay: calc(var(--delay) + 0.12s);
|
||||||
}
|
}
|
||||||
|
|
||||||
.in-view .block-item .line {
|
.in-view .block-item .line {
|
||||||
animation: growLine 0.7s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
animation: growLine 0.7s cubic-bezier(0.2, 0.9, 0.2, 1) forwards;
|
||||||
animation-delay: calc(var(--delay) + 0.18s);
|
animation-delay: calc(var(--delay) + 0.18s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keyframes */
|
/* keyframes */
|
||||||
@keyframes scaleIn {
|
@keyframes scaleIn {
|
||||||
from {
|
from {
|
||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes growLine {
|
@keyframes growLine {
|
||||||
from {
|
from {
|
||||||
height: 0;
|
height: 0;
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
height: 27.4rem;
|
height: 27.4rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 移动端 <= 1200px 四宫格布局 */
|
||||||
|
@media (max-width: 1200px) {
|
||||||
|
.blocks-list {
|
||||||
|
height: auto;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
padding: 2rem 1.5rem;
|
||||||
|
column-gap: 0;
|
||||||
|
row-gap: 0;
|
||||||
|
|
||||||
|
.block-item {
|
||||||
|
flex: none;
|
||||||
|
width: 50%;
|
||||||
|
height: 18rem;
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
.number {
|
||||||
|
font-size: 2.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.line {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&:nth-child(1)::after,
|
||||||
|
&:nth-child(2)::after,
|
||||||
|
&:nth-child(3)::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
background-color: #8d8d8d;
|
||||||
|
}
|
||||||
|
/* 第一行的两个item底部需要分隔线 */
|
||||||
|
&:nth-child(1)::after,
|
||||||
|
&:nth-child(2)::after {
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 第一个item右侧需要分隔线 */
|
||||||
|
&:nth-child(1)::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
width: 0.1rem;
|
||||||
|
background-color: #8d8d8d;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:nth-child(4)::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 0.1rem;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #8d8d8d;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.in-view {
|
||||||
|
.block-item {
|
||||||
|
&:nth-child(1)::before {
|
||||||
|
transform-origin: bottom;
|
||||||
|
transform: scaleY(0);
|
||||||
|
animation: growUp 2s cubic-bezier(0.4, 0, 0.2, 1) forwards;
|
||||||
|
animation-delay: calc(var(--delay) + 0.5s);
|
||||||
|
}
|
||||||
|
&:nth-child(1)::after {
|
||||||
|
transform-origin: right;
|
||||||
|
transform: scaleX(0);
|
||||||
|
animation: growRight 2s cubic-bezier(0.4, 0, 0.2, 1) forwards;
|
||||||
|
animation-delay: calc(var(--delay) + 0.5s);
|
||||||
|
}
|
||||||
|
&:nth-child(2)::after {
|
||||||
|
transform-origin: left;
|
||||||
|
transform: scaleX(0);
|
||||||
|
animation: growLeft 2s cubic-bezier(0.4, 0, 0.2, 1) forwards;
|
||||||
|
animation-delay: calc(var(--delay) + 0.5s);
|
||||||
|
}
|
||||||
|
&:nth-child(4)::before {
|
||||||
|
transform: translateX(-100%) scaleY(0);
|
||||||
|
transform-origin: top;
|
||||||
|
animation: growDown 2s cubic-bezier(0.4, 0, 0.2, 1) forwards;
|
||||||
|
animation-delay: calc(var(--delay) + 0.5s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes growUp {
|
||||||
|
0% {
|
||||||
|
transform: scaleY(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scaleY(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes growDown {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%) scaleY(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: translateX(-100%) scaleY(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes growLeft {
|
||||||
|
0% {
|
||||||
|
transform: scaleX(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes growRight {
|
||||||
|
0% {
|
||||||
|
transform: scaleX(0);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user