feat: home页轮播图i18n

This commit is contained in:
2026-06-02 15:15:30 +08:00
parent d98ddd2940
commit 407678d166
5 changed files with 275 additions and 149 deletions

View File

@@ -11,12 +11,7 @@
:autoplay="false"
:interval="1000"
>
<article
v-for="slide in slides"
:key="slide.id"
ref="slideEls"
class="carousel-slide"
>
<article v-for="slide in slides" :key="slide.id" ref="slideEls" class="carousel-slide">
<div class="mask"></div>
<div class="banner-title" v-if="slide.title">{{ slide.title }}</div>
<img
@@ -81,20 +76,24 @@
</template>
<script setup lang="ts">
import { Carousel as KagolCarousel } from '@kagol/vue-carousel'
import '@kagol/vue-carousel/dist/style.css'
import { gsap } from 'gsap'
import {
nextTick,
onBeforeUnmount,
onMounted,
shallowRef,
useTemplateRef,
watch
watch,
computed,
ref
} from 'vue'
import { gsap } from 'gsap'
import { Carousel as KagolCarousel } from '@kagol/vue-carousel'
import '@kagol/vue-carousel/dist/style.css'
import mainBanner01 from '../../../assets/images/home/mainbanner01.jpg'
import mainBanner02 from '../../../assets/images/home/mainbanner02.jpg'
import Video from '@/assets/images/home/hero-desktop.mp4'
import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n()
type HomeSlide = {
id: string
@@ -109,42 +108,60 @@
const activePage = shallowRef(1)
const isAutoplayEnabled = shallowRef(false)
const slideEls = useTemplateRef<HTMLElement[]>('slideEls')
const slides: readonly HomeSlide[] = [
const windowWidth = ref(typeof window !== 'undefined' ? window.innerWidth : 768)
const getVideoUrl = () => {
const isMobile = windowWidth.value < 768
const isEnglish = locale.value === 'en'
if (isEnglish) {
return isMobile
? 'https://code-create.com.hk/wp-content/uploads/2023/06/codec_brand_vid_EN_1x1_SUB.mp4'
: 'https://code-create.com.hk/wp-content/uploads/2023/06/codec_brand_vid_16x9_ENG_SUB.mp4'
} else {
// 中文(简体和繁体都使用中文版本)
return isMobile
? 'https://code-create.com.hk/wp-content/uploads/2023/05/codec_brand_video_SC_1x1_SUB.mp4'
: 'https://code-create.com.hk/wp-content/uploads/2023/05/codec_brand_video_SC_16x9_SUB.mp4'
}
}
const slides = computed<HomeSlide[]>(() => [
{
id: 'aida',
image: mainBanner01,
video: '',
alt: 'Code Create product banner',
title: 'Shaping the future\nof fashion design',
alt: t('Home.banner1slogan'),
title: t('Home.banner1slogan'),
number: '01',
description:
"World's first and only designer-led AI system that streamlines ideation from hours to seconds"
description: t('Home.banner1desc')
},
{
id: 'mixi',
image: mainBanner02,
video: '',
alt: 'Code Create product banner',
title: 'Be the game changer,\n subscribe now!',
title: t('Home.banner2slogan'),
number: '02',
description: 'Make the first move to streamline and facilitate your inspiration process'
description: t('Home.banner2desc')
},
{
id: 'video',
image: '',
video: Video,
video: getVideoUrl(),
alt: 'Code Create product video banner'
}
]
])
const descAnimationDelay = 1
let activeSlideIndex: number | null = null
let descAnimationFrame = 0
let descTimeline: ReturnType<typeof gsap.timeline> | null = null
let handleResize: (() => void) | null = null
function getActiveSlideIndex() {
const slideCount = slides.length
const slideCount = slides.value.length
return ((activePage.value - 1) % slideCount + slideCount) % slideCount
return (((activePage.value - 1) % slideCount) + slideCount) % slideCount
}
function prefersReducedMotion() {
@@ -233,6 +250,12 @@
onMounted(() => {
resumeAutoplay()
queueDescAnimation()
// 监听窗口resize事件以更新视频选择
handleResize = () => {
windowWidth.value = window.innerWidth
}
window.addEventListener('resize', handleResize)
})
onBeforeUnmount(() => {
@@ -241,6 +264,11 @@
}
descTimeline?.kill()
// 移除resize监听
if (handleResize) {
window.removeEventListener('resize', handleResize)
}
})
watch(activePage, queueDescAnimation)
@@ -309,7 +337,7 @@
background: #a51f24;
pointer-events: none;
}
.desc-index-group {
position: relative;
z-index: 1;