officialWebsite/src/views/investor/size375/index.vue

972 lines
25 KiB
Vue
Raw Normal View History

2025-03-14 09:05:00 +00:00
<template>
<div class="page-container">
<n-divider class="divider1" vertical />
<n-divider class="divider5" vertical />
<AppHeader />
<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, watch, 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";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
// 定义组件的自定义事件
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 { useRouter } from "vue-router";
const router = useRouter();
// 导入图片
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 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)`;
}
}
};
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 102px;
background-color: #fff;
}
.logo {
img {
width: 399px;
height: 128px;
}
}
.tabs {
display: flex;
gap: 77px;
margin-left: 67px;
}
.tab-item {
display: flex;
align-items: center;
font-size: 61px;
color: #000000;
max-width: 251px;
cursor: pointer;
transition: color 0.3s ease;
padding: 4px 8px;
&.active {
color: #8b59fa;
}
&:hover {
color: #8b59fa;
}
}
.ellipsis {
white-space: nowrap; /* 防止文本换行 */
overflow: hidden; /* 隐藏溢出内容 */
text-overflow: ellipsis; /* 文本溢出时显示省略号 */
}
.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;
}
/* 语言选择模态框样式 */
.language-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1000;
touch-action: none; /* 防止触摸事件影响背景 */
}
.language-modal-backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
z-index: 1001;
}
.language-modal-content {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
max-height: 90vh; /* 最大高度为视口高度的90% */
background-color: #fff;
z-index: 1002;
box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.1);
display: flex;
flex-direction: column;
overflow: hidden; /* 内容溢出隐藏 */
}
.modal-header {
padding: 67px 77px 113px 77px;
display: flex;
justify-content: space-between;
align-items: center;
font-size: 82px;
color: #000000;
position: relative;
flex-shrink: 0; /* 不允许头部收缩 */
}
.close-btn {
cursor: pointer;
}
.language-modal-body {
padding: 10px 0;
overflow-y: auto; /* 只有内容区域可滚动 */
-webkit-overflow-scrolling: touch; /* 为iOS设备提供平滑滚动 */
flex: 1; /* 内容区域填充剩余空间 */
}
.language-option {
padding: 30px 0;
font-size: 72px;
color: #333;
cursor: pointer;
transition: background-color 0.3s;
text-align: center;
}
.language-option:hover,
.language-option.active {
background-color: #f5f5f5;
color: #8b59f7;
}
.language-modal-footer {
padding: 113px 77px;
display: flex;
justify-content: center;
flex-shrink: 0; /* 不允许底部收缩 */
}
.confirm-btn {
background-color: #8b59f7;
color: white;
border: none;
border-radius: 20px;
padding: 46px 0;
width: 100%;
font-size: 82px;
cursor: pointer;
}
.confirm-btn:hover {
background-color: #7a48e6;
}
</style>