officialWebsite/src/views/companyprofil/size375/index.vue
2025-02-24 09:10:16 +08:00

903 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

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="page-container">
<n-divider class="divider1" vertical />
<n-divider class="divider5" vertical />
<header className="header flex items-center justify-between">
<div class="logo">
<img src="@/assets/image/logo.png" alt="logo" />
</div>
<div class="tabs">
<div
class="tab-item"
:class="{ active: currentTab === 'home' }"
@click="handleTabClick('home')"
>
{{ $t("home.nav.home") }}
</div>
<div
class="tab-item"
:class="{ active: currentTab === 'companyprofil' }"
@click="handleTabClick('companyprofil')"
>
{{ $t("home.nav.company") }}
</div>
<div
class="tab-item"
:class="{ active: currentTab === 'businessintroduction' }"
@click="handleTabClick('businessintroduction')"
>
{{ $t("home.nav.businessintroduction") }}
</div>
</div>
</header>
<main>
<section style="background: #ffffff" className="relative">
<div class="relative section-first h-[3990px] box-contain pt-[2300px]">
<div
class="w-full title ml-[184px]"
:ref="
(el) => {
moveRefs[0].value = el;
}
"
>
<div>{{ $t("companyprofil.slogan.title1") }}</div>
<div>{{ $t("companyprofil.slogan.title2") }}</div>
</div>
<div
:ref="
(el) => {
moveRefs[1].value = el;
}
"
class="text-[51px] text-[#8B59F7] w-[1413px] ml-[184px] mt-[61px]"
>
{{ $t("companyprofil.slogan.desc") }}
</div>
</div>
<div ref="moveRef3" class="absolute top-[686px] left-[266px]">
<img
class="w-[1140px]"
src="@/assets/image/companyprofil/375/image-q.png"
/>
</div>
<div class="w-[1920px] absolute bottom-[-160px] z-4">
<img
src="@/assets/image/companyprofil/375/icon-lang.png"
alt="logo"
/>
</div>
</section>
<section style="background: #f8f9ff">
<div class="flex flex-wrap justify-center">
<div class="w-full px-[184px] mt-[400px]">
<div class="text-[#8B59F7] text-[72px]">
{{ $t("companyprofil.intro.label") }}
</div>
</div>
<div class="w-full title px-[179px] mt-[87px]">
<div>{{ $t("companyprofil.intro.title1") }}</div>
<div>{{ $t("companyprofil.intro.title2") }}</div>
</div>
<div class="w-full px-[184px] mt-[140px]">
<div
:ref="
(el) => {
moveRefs[2].value = el;
}
"
class="text-[#455363] text-[72px] w-[1413px]"
>
{{ $t("companyprofil.intro.desc") }}
</div>
<div
:ref="
(el) => {
moveRefs[3].value = el;
}
"
class="mt-[60px] text-[#455363] text-[72px] w-[1413px]"
>
{{ $t("companyprofil.intro.desc") }}
</div>
</div>
<div
:ref="
(el) => {
moveRefs[4].value = el;
}
"
class="mt-[287px] mb-[512px] overflow-hidden"
>
<img
:ref="
(el) => {
moveRefs[5].value = el;
}
"
class="w-[1625px] h-[1038px]"
src="@/assets/image/companyprofil/375/imageshow-2.png"
/>
</div>
</div>
</section>
<section class="relative" style="background: #fff">
<div class="flex flex-wrap justify-center">
<div class="w-full px-[184px] mt-[451px]">
<div class="text-[#8B59F7] text-[72px]">
{{ $t("companyprofil.team.label") }}
</div>
</div>
<div class="w-full title px-[179px] mt-[87px]">
<div>{{ $t("companyprofil.team.title1") }}</div>
<div>{{ $t("companyprofil.team.title2") }}</div>
</div>
<div class="w-full px-[184px] mt-[140px]">
<div
:ref="
(el) => {
moveRefs[6].value = el;
}
"
class="text-[#455363] text-[72px] w-[1413px] subTitle"
>
{{ $t("companyprofil.team.desc") }}
</div>
</div>
<div class="mt-[287px] mb-[399px]">
<img
:ref="
(el) => {
moveRefs[7].value = el;
}
"
class="w-[1715px]"
src="@/assets/image/companyprofil/375/imageshow-3.png"
/>
</div>
<div class="w-full px-[184px]">
<img
class="w-[229px] h-[229px]"
src="@/assets/image/companyprofil/375/icon-lun.png"
/>
<div
class="w-full mt-[102px] text-[#10253E] text-[82px] font-semibold"
>
{{ $t("companyprofil.team.features.global.title") }}
</div>
<div class="mt-[87px] text-[#455363] text-[72px] w-[1498px]">
{{ $t("companyprofil.team.features.global.desc") }}
</div>
</div>
<div class="w-full px-[184px] mt-[410px]">
<img
class="w-[229px] h-[196px]"
src="@/assets/image/companyprofil/375/icon-love.png"
/>
<div
class="w-full mt-[133px] text-[#10253E] text-[82px] font-semibold"
>
{{ $t("companyprofil.team.features.fans.title") }}
</div>
<div class="mt-[87px] text-[#455363] text-[72px] w-[1498px]">
{{ $t("companyprofil.team.features.fans.desc") }}
</div>
</div>
<div class="w-full px-[184px] mt-[389px] mb-[250px]">
<img
class="w-[229px] h-[222px]"
src="@/assets/image/companyprofil/375/icon-p.png"
/>
<div
class="w-full mt-[123px] text-[#10253E] text-[82px] font-semibold"
>
{{ $t("companyprofil.team.features.talent.title") }}
</div>
<div
class="mt-[87px] mb-[100px] text-[#455363] text-[72px] w-[1498px]"
>
{{ $t("companyprofil.team.features.talent.desc") }}
</div>
</div>
<div class="icon-langmul z-4">
<img
class="w-[1205px]"
src="@/assets/image/companyprofil/375/icon-langmul.png"
/>
</div>
</div>
</section>
<section class="section-four">
<div class="flex flex-wrap justify-center">
<div class="w-full px-[184px] mt-[445px]">
<div class="text-[#8B59F7] text-[72px]">
{{ $t("companyprofil.achievement.label") }}
</div>
</div>
<div
:ref="
(el) => {
moveRefs[8].value = el;
}
"
class="w-full title px-[179px] mt-[87px]"
>
<div>{{ $t("companyprofil.achievement.title1") }}</div>
<div>{{ $t("companyprofil.achievement.title2") }}</div>
</div>
<div class="w-full px-[184px] mt-[159px]">
<div
:ref="
(el) => {
moveRefs[9].value = el;
}
"
class="text-[#455363] text-[72px] w-[1413px]"
>
{{ $t("companyprofil.achievement.desc") }}
</div>
</div>
<div
:ref="
(el) => {
moveRefs[10].value = el;
}
"
class="w-full mt-[532px] px-[184px] text-[92px] font-semibold"
>
<div>
{{ $t("companyprofil.achievement.certification.title1") }}
</div>
<div>
{{ $t("companyprofil.achievement.certification.title2") }}
</div>
</div>
<div
:ref="
(el) => {
moveRefs[11].value = el;
}
"
class="w-full px-[184px] mt-[60px]"
>
<div class="text-[#455363] text-[72px] w-[1413px]">
{{ $t("companyprofil.achievement.certification.desc") }}
</div>
</div>
<div
:ref="
(el) => {
moveRefs[12].value = el;
}
"
class="mt-[287px] overflow-hidden"
>
<img
class="w-[1625px] h-[1038px]"
src="@/assets/image/companyprofil/375/imageshow-4.png"
/>
</div>
<div
:ref="
(el) => {
moveRefs[13].value = el;
}
"
class="w-full mt-[532px] px-[184px] text-[92px] font-semibold"
>
<div>{{ $t("companyprofil.achievement.platform.title1") }}</div>
<div>{{ $t("companyprofil.achievement.platform.title2") }}</div>
</div>
<div class="w-full px-[184px] mt-[128px]">
<div
:ref="
(el) => {
moveRefs[14].value = el;
}
"
class="text-[#455363] text-[72px] w-[1413px]"
>
<div>
{{ $t("companyprofil.achievement.platform.desc") }}
</div>
</div>
</div>
<div class="mt-[287px] mb-[364px] overflow-hidden">
<img
:ref="
(el) => {
moveRefs[15].value = el;
}
"
class="w-[1625px] h-[1038px]"
src="@/assets/image/companyprofil/375/imageshow-5.png"
/>
</div>
</div>
</section>
<section style="background: #fff">
<div class="flex flex-wrap justify-center">
<div class="w-full px-[184px] mt-[364px]">
<div class="text-[#8B59F7] text-[72px]">
{{ $t("companyprofil.news.label") }}
</div>
</div>
<div
:ref="
(el) => {
moveRefs[16].value = el;
}
"
class="w-full title px-[179px] mt-[87px]"
>
<div>{{ $t("companyprofil.news.title1") }}</div>
<div>{{ $t("companyprofil.news.title2") }}</div>
</div>
<div class="w-full px-[184px] mt-[159px]">
<div
:ref="
(el) => {
moveRefs[17].value = el;
}
"
class="text-[#455363] text-[72px] w-[1413px]"
>
{{ $t("companyprofil.news.desc") }}
</div>
</div>
<div class="w-full mt-[200px] flex flex-wrap justify-end">
<div class="flex flex-wrap">
<div class="arrow-btn" @click="handlePrev">
<img
class="w-[195px] h-[195px]"
src="@/assets/image/companyprofil/375/icon-left.png"
/>
</div>
<div class="arrow-btn ml-[128px] mr-[133px]" @click="handleNext">
<img
class="w-[195px] h-[195px]"
src="@/assets/image/companyprofil/375/icon-right.png"
/>
</div>
</div>
</div>
<div
class="mt-[148px] mb-[246px] carousel-container px-[80px] py-[40px]"
>
<div
ref="carouselTrack"
class="carousel-track"
:style="{
transform: `translateX(-${getSlideOffset()}px)`,
}"
@mousedown="handleDragStart"
@mousemove="handleDragMove"
@mouseup="handleDragEnd"
@mouseleave="handleDragEnd"
@touchstart="handleDragStart"
@touchmove="handleDragMove"
@touchend="handleDragEnd"
>
<div
v-for="(item, idx) in getVisibleItems()"
:key="idx"
class="carousel-item mr-[120px]"
@click="handleCarouselClick(item, $event)"
>
<img class="carousel-image" :src="item.imgUrl" />
<div class="carousel-content">
<div class="carousel-title">
<div>
{{
$t(
`companyprofil.news.carousel.item${item.titleNo}.title`
)
}}
</div>
</div>
<div class="carousel-subtitle">
{{
$t(`companyprofil.news.carousel.item${item.titleNo}.desc`)
}}
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<section
style="background: #fff"
className="flex flex-wrap justify-center"
>
<img
class="w-[891px] h-[87px] mt-[61px] mb-[56px]"
src="@/assets/image/image-footer.png"
alt="logo"
/>
</section>
</main>
</div>
</template>
<script setup>
import { NDivider } from "naive-ui";
import { onUnmounted, ref, onMounted, reactive, nextTick } from "vue";
import gsap from "gsap";
import { ScrollTrigger } from "gsap/ScrollTrigger";
import { useHome } from "@/store/home/index.js";
import { useTransitionComposable } from "@/composables/transition-composable";
// 定义组件的自定义事件
defineEmits(["sendCode"]);
// 注册 ScrollTrigger 插件
gsap.registerPlugin(ScrollTrigger);
const { transitionState } = useTransitionComposable();
const moveRefs = ref(
Array(18)
.fill(null)
.map(() => ref(null))
);
const { currentTab } = useHome();
let ctx;
// 导入图片
import carouselShow1 from "@/assets/image/companyprofil/375/carouselShow-1.png";
import carouselShow2 from "@/assets/image/companyprofil/375/carouselShow-2.png";
import carouselShow3 from "@/assets/image/companyprofil/375/carouselShow-3.png";
import carouselShow4 from "@/assets/image/companyprofil/375/carouselShow-4.png";
import carouselShow5 from "@/assets/image/companyprofil/375/carouselShow-5.png";
const state = reactive({
marqueeArr: [
{
titleNo: "1",
imgUrl: carouselShow1,
},
{
titleNo: "2",
imgUrl: carouselShow2,
},
{
titleNo: "3",
imgUrl: carouselShow3,
},
{
titleNo: "4",
imgUrl: carouselShow4,
},
{
titleNo: "5",
imgUrl: carouselShow5,
},
],
});
const carouselTrack = ref(null);
const currentIndex = ref(0);
const isTransitioning = ref(false);
const getVisibleItems = () => {
const items = state.marqueeArr;
// 创建一个包含所有项目的数组,前后各复制一组用于无缝循环
return [...items, ...items, ...items];
};
// 计算实际滑动距离
const getSlideOffset = () => {
if (!carouselTrack.value) return 0;
const firstItem = carouselTrack.value.querySelector(".carousel-item");
if (!firstItem) return 0;
const itemWidth = firstItem.offsetWidth;
const itemMargin = parseInt(window.getComputedStyle(firstItem).marginRight);
const totalWidth = itemWidth + itemMargin;
const len = state.marqueeArr.length;
if (currentIndex.value <= -len) {
currentIndex.value = -currentIndex.value % len;
} else if (currentIndex.value >= len) {
currentIndex.value = currentIndex.value % len;
}
// 初始偏移一组数据的长度
const initialOffset = len * totalWidth + 8;
return initialOffset + currentIndex.value * totalWidth;
};
// 定义 resize 处理函数
const handleResize = () => {
if (carouselTrack.value) {
carouselTrack.value.style.transform = `translateX(-${getSlideOffset()}px)`;
}
};
// 监听窗口大小变化
onMounted(() => {
ctx = gsap.context(() => {
moveRefs.value.forEach((moveRef, index) => {
if (moveRef.value) {
// 修改初始状态设置
gsap.set(moveRef.value, {
opacity: 0,
// 使用 translateX 替代 x并且初始位置设置在元素自身宽度范围内
transform: `translateX(${index % 2 === 0 ? "-100%" : "100%"})`,
// 添加 overflow: hidden 确保不会影响布局
overflow: "hidden",
});
// 修改动画设置
gsap.to(moveRef.value, {
opacity: 1,
transform: "translateX(0)", // 使用 transform 替代 x
duration: 1.2,
ease: "power2.out",
scrollTrigger: {
trigger: moveRef.value,
start: "top 80%",
end: "top 40%",
toggleActions: "play none none reverse",
markers: false,
},
});
}
});
});
// 使用定义的 handleResize 函数
window.addEventListener("resize", handleResize);
// 初始化位置为第二组的开头
currentIndex.value = 0;
nextTick(() => {
if (carouselTrack.value) {
carouselTrack.value.style.transition = "none";
carouselTrack.value.style.transform = `translateX(-${getSlideOffset()}px)`;
// 重新启用过渡效果
setTimeout(() => {
carouselTrack.value.style.transition = "transform 0.5s ease-in-out";
}, 50);
}
});
});
onUnmounted(() => {
if (ctx) {
ctx.revert();
}
ScrollTrigger.killAll();
// 移除事件监听
window.removeEventListener("resize", handleResize);
});
const handleTabClick = (tab) => {
currentTab.value = tab;
router.push("/" + tab);
};
const goToSection = (i) => {
ctx.data.forEach((e) => {
if (e.vars && e.vars.id === "scrollTween") {
e.kill();
}
});
ctx.add(() => {
scrollTween = gsap.to(window, {
scrollTo: { y: i * window.innerHeight, autoKill: false },
duration: 1,
id: "scrollTween",
onComplete: () => (scrollTween = null),
overwrite: true,
});
});
};
// 向前滑动
const handlePrev = () => {
if (isTransitioning.value) return;
isTransitioning.value = true;
if (!carouselTrack.value) return;
carouselTrack.value.style.transition = "transform 0.5s ease-in-out";
currentIndex.value--;
if (currentIndex.value < -state.marqueeArr.length) {
setTimeout(() => {
carouselTrack.value.style.transition = "none";
currentIndex.value = -1;
carouselTrack.value.offsetHeight;
carouselTrack.value.style.transition = "transform 0.5s ease-in-out";
isTransitioning.value = false;
}, 500);
} else {
setTimeout(() => {
isTransitioning.value = false;
}, 500);
}
};
// 向后滑动
const handleNext = () => {
if (isTransitioning.value) return;
isTransitioning.value = true;
if (!carouselTrack.value) return;
carouselTrack.value.style.transition = "transform 0.5s ease-in-out";
currentIndex.value++;
if (currentIndex.value >= state.marqueeArr.length) {
setTimeout(() => {
carouselTrack.value.style.transition = "none";
currentIndex.value = 0;
carouselTrack.value.offsetHeight;
carouselTrack.value.style.transition = "transform 0.5s ease-in-out";
isTransitioning.value = false;
}, 500);
} else {
setTimeout(() => {
isTransitioning.value = false;
}, 500);
}
};
// 添加滑动相关的状态
const isDragging = ref(false);
const startX = ref(0);
const scrollLeft = ref(0);
// 处理鼠标/触摸按下事件
const handleDragStart = (e) => {
isDragging.value = true;
startX.value = e.type === "mousedown" ? e.pageX : e.touches[0].pageX;
scrollLeft.value = getSlideOffset();
// 禁用过渡效果,实现平滑拖动
if (carouselTrack.value) {
carouselTrack.value.style.transition = "none";
}
};
// 处理鼠标/触摸移动事件
const handleDragMove = (e) => {
if (!isDragging.value) return;
e.preventDefault();
const x = e.type === "mousemove" ? e.pageX : e.touches[0].pageX;
const walk = startX.value - x;
if (carouselTrack.value) {
carouselTrack.value.style.transform = `translateX(-${
scrollLeft.value + walk
}px)`;
}
};
// 处理鼠标/触摸释放事件
const handleDragEnd = (e) => {
if (!isDragging.value) return;
isDragging.value = false;
if (carouselTrack.value) {
// 恢复过渡效果
carouselTrack.value.style.transition = "transform 0.5s ease-in-out";
const x = e.type === "mouseup" ? e.pageX : e.changedTouches[0].pageX;
const walk = startX.value - x;
// 获取单个项目的宽度
const firstItem = carouselTrack.value.querySelector(".carousel-item");
if (!firstItem) return;
const itemWidth = firstItem.offsetWidth;
const itemMargin = parseInt(window.getComputedStyle(firstItem).marginRight);
const totalWidth = itemWidth + itemMargin;
// 根据滑动距离决定是否切换到下一个/上一个
if (Math.abs(walk) > totalWidth / 3) {
if (walk > 0) {
handleNext();
} else {
handlePrev();
}
} else {
// 如果滑动距离不够,回到当前位置
carouselTrack.value.style.transform = `translateX(-${getSlideOffset()}px)`;
}
}
};
import { useRouter } from "vue-router";
const router = useRouter();
const handleCarouselClick = (item, event) => {
// 检查事件类型是否为点击
if (event.type === "click") {
event.stopPropagation(); // 阻止事件传播
event.preventDefault(); // 阻止默认行为
router.push({
path: "/companyprofildetail",
query: {
titleNo: item.titleNo,
},
});
}
};
</script>
<style scoped lang="scss">
.page-container {
width: 100%;
overflow-x: hidden;
position: relative;
}
.header {
width: 100%;
height: 260px;
position: fixed;
z-index: 10;
top: 0;
left: 0;
right: 0;
padding: 0 138px;
background-color: #fff;
}
.logo {
img {
width: 399px;
height: 128px;
}
}
.tabs {
display: flex;
gap: 128px;
margin-right: 32px;
margin-left: 60px;
}
.tab-item {
display: flex;
align-items: center;
font-size: 61px;
color: #000000;
cursor: pointer;
transition: color 0.3s ease;
padding: 4px 8px;
&.active {
color: #8b59fa;
}
&:hover {
color: #8b59fa;
}
}
.title {
font-size: 113px;
font-weight: 600;
color: #10253e;
line-height: 143px;
}
.subTitle {
line-height: 102px;
}
.section-first {
background: url("@/assets/image/companyprofil/375/image-x.png");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.section-four {
background: url("@/assets/image/companyprofil/375/bg-3.png");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.icon-langmul {
position: absolute;
bottom: -206px;
right: 0;
}
.carousel-container {
width: 96%;
position: relative;
}
.arrow-btn {
cursor: pointer;
}
.carousel-track {
display: flex;
will-change: transform;
cursor: grab;
user-select: none;
&:active {
cursor: grabbing;
}
}
.carousel-item {
width: 1710px;
flex: 0 0 auto;
display: block;
padding: 46px 36px 118px 51px;
border-radius: 61px;
box-shadow: 0 15px 72px 5px rgba(0, 0, 0, 0.16);
}
.carousel-image {
width: 1623px;
height: 1152px;
object-fit: cover;
display: block;
}
.carousel-content {
padding: 0 20px 0 60px;
margin-top: 87px;
}
.carousel-title {
font-size: 92px;
font-weight: 500;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.5;
max-height: calc(1.5em * 5);
}
.carousel-subtitle {
margin-top: 51px;
color: #455363;
display: -webkit-box;
-webkit-line-clamp: 4;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
line-height: 102px;
max-height: calc(1.5em * 4);
}
// 添加一个通用的溢出控制类
.overflow-hidden {
overflow: hidden;
}
.divider1 {
position: absolute;
z-index: 3;
left: 64px;
width: 1px;
height: 100%;
background-color: rgba(230, 234, 238, 0.5) !important;
}
.divider5 {
position: absolute;
z-index: 3;
right: 60px;
width: 1px;
height: 100%;
background-color: rgba(230, 234, 238, 0.5) !important;
}
</style>