<template>
<div class="scroll-container" ref="container">
<section
v-for="(section, index) in sections"
:key="index"
:class="[{ active: currentIndex === index }, section.bgClass]"
>
<div class="section section-one" v-if="index === 0">
<div class="title">{{ section.title }}</div>
<img src="./img/phone.png" alt="" />
<div class="content">{{ section.content }}</div>
</div>
<div class="section section-two" v-if="index === 1">
<div class="title">{{ section.title }}</div>
<div class="content">{{ section.content }}</div>
</div>
<div class="section section-three" v-if="index === 2">
<div>
<img src="./img/phone3.png" alt="" />
</div>
<div>
<div class="title">{{ section.title }}</div>
<div class="content">{{ section.content }}</div>
</div>
</div>
<div class="section section-four" v-if="index === 3">
<div>
<img src="./img/phone4.png" alt="" />
</div>
<div>
<div class="title">{{ section.title }}</div>
<div class="content">{{ section.content }}</div>
</div>
</div>
<div class="section section-five" v-if="index === 4">
<div class="title">{{ section.title }}</div>
<img src="./img/phone5.png" alt="" />
<div class="content">{{ section.content }}</div>
</div>
</section>
<!-- 右侧导航圆点 -->
<div class="nav-dots">
<div
v-for="(dot, index) in sections"
:key="index"
class="dot"
:class="{ active: currentIndex === index }"
@click="scrollToSection(index)"
></div>
</div>
</div>
</template>
<script setup>
import {
ref,
onMounted,
// onUnmounted
} from "vue";
// 页面内容数据
const sections = ref([
{
title: "土豆星球",
content:
"现代人的生活压力通常很大,各行各业皆是如此,你的挚爱亲朋不理解你,你的公司领导瞧不上你,也许是你没能遇到一个懂你、理解你的知己,也许是你的脆弱不希望和身边的人去诉说。来T土豆星球,进行一次心灵测试,我们来帮你找到那个懂你,倾听你的他/她,让相似经历的你们,彼此陪伴,伴你走出人生的低谷。",
bgClass: "bg1",
},
{
title: "穿越过去",
content:
"每个人都曾经历过痛苦的离别,每个人的内心深处都有很多来不及说出的话,时空胶囊能让你和失去/逝去的人隔空对话,任何时间任何地点,点开土豆星球,打开时空胶囊,都能让你回到过去,跟爷爷奶奶说一句:“家里一切都好,你们好吗?” 跟父母说一句:“我爱你们”公司基于强大的技术实力和元宇宙的星现形式,为你补完内心深处的遗憾。",
bgClass: "bg2",
},
{
title: "心灵对话",
content:
"在遭受困难时,你会不会感叹命运的不公?为什么别人过的那么好,而你却什么也不是?很多人因此失去了人生的目标和对未来的希望。你是否希望未来的自己能穿越回现在给你指引方向?其实每个人都不普通,只是你还没找到自己的闪光点,让我们站在未来的高处,跨域时间和现实的梏,让未来的你,伸手将今天的自己拉出困境与低谷。 ",
bgClass: "bg3",
},
{
title: "匹配社交",
content:
"现代人的生活压力通常很大,各行各业皆是如此,你的挚爱亲朋不理解你,你的公司领导瞧不上你,也许是你没能遇到一个懂你、理解你的知己,也许是你的脆弱不希望和身边的人去诉说。来T土豆星球,进行一次心灵测试,我们来帮你找到那个懂你,倾听你的他/她,让相似经历的你们,彼此陪伴,伴你走出人生的低谷。",
bgClass: "bg4",
},
{
title: "寻找话题",
content:
"我们每个人都是不同的个体,有不同的价值观,或许事情没有绝对的对错,只是缺少聊得来的人。网络虽然大,但依旧无法分享你喜欢的聊天话题,那些在你心里积攒了无数个日月的话,想找别人分享,但一直没有找到分享的对象,那么土豆星球是一个你能够展示自己的平台,有一群和你志同道合的小伙伴在等着你!",
bgClass: "bg5",
},
]);
const container = ref(null);
const currentIndex = ref(0);
let isScrolling = false;
// 处理滚动事件
const handleWheel = (e) => {
if (isScrolling) return;
isScrolling = true;
const direction = e.deltaY > 0 ? 1 : -1;
const newIndex = Math.min(
Math.max(currentIndex.value + direction, 0),
sections.value.length - 1
);
if (newIndex !== currentIndex.value) {
currentIndex.value = newIndex;
container.value.scrollTo({
top: window.innerHeight * newIndex,
behavior: "smooth",
});
}
setTimeout(() => {
isScrolling = false;
}, 800);
};
// 添加键盘支持
const handleKeyDown = (e) => {
if (e.key === "ArrowDown") {
currentIndex.value = Math.min(
currentIndex.value + 1,
sections.value.length - 1
);
} else if (e.key === "ArrowUp") {
currentIndex.value = Math.max(currentIndex.value - 1, 0);
}
container.value.scrollTo({
top: window.innerHeight * currentIndex.value,
behavior: "smooth",
});
};
// 添加触摸滑动支持
let touchStartY = 0;
const handleTouchStart = (e) => {
touchStartY = e.touches[0].clientY;
};
const handleTouchEnd = (e) => {
const touchEndY = e.changedTouches[0].clientY;
const diff = touchStartY - touchEndY;
if (Math.abs(diff) > 50) {
const direction = diff > 0 ? 1 : -1;
const newIndex = Math.min(
Math.max(currentIndex.value + direction, 0),
sections.value.length - 1
);
if (newIndex !== currentIndex.value) {
currentIndex.value = newIndex;
container.value.scrollTo({
top: window.innerHeight * newIndex,
behavior: "smooth",
});
}
}
};
const scrollToSection = (index) => {
currentIndex.value = index;
container.value.scrollTo({
top: window.innerHeight * index,
behavior: "smooth",
});
};
// 生命周期钩子
onMounted(() => {
window.addEventListener("wheel", handleWheel, { passive: false });
window.addEventListener("keydown", handleKeyDown);
container.value.addEventListener("touchstart", handleTouchStart);
container.value.addEventListener("touchend", handleTouchEnd);
});
// onUnmounted(() => {
// window.removeEventListener('wheel', handleWheel)
// window.removeEventListener('keydown', handleKeyDown)
// container.value.removeEventListener('touchstart', handleTouchStart)
// container.value.removeEventListener('touchend', handleTouchEnd)
// })
</script>
<style scoped lang="scss">
.scroll-container {
height: 100vh;
overflow-y: hidden;
scroll-snap-type: y mandatory;
scroll-behavior: smooth;
position: relative;
}
section {
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
scroll-snap-align: start;
transition: background-color 0.5s ease;
position: relative;
background-size: 100% 100%;
background-repeat: no-repeat;
}
.bg1 {
background-image: url("./img/bg1.png");
}
.bg2 {
background-image: url("./img/bg2.png");
}
.bg3 {
background-image: url("./img/bg3.png");
}
.bg4 {
background-image: url("./img/bg4.png");
}
.bg5 {
background-image: url("./img/bg5.png");
}
.title {
font-family: Alibaba-PuHuiTi, Alibaba-PuHuiTi;
font-weight: 500;
font-size: 80px;
color: #e1e1e1;
text-align: left;
font-style: normal;
text-transform: none;
}
.content {
font-family: Adobe Heiti Std;
font-size: 14px;
color: #ffffff;
line-height: 30px;
text-align: justifyLeft;
font-style: normal;
text-transform: none;
}
.section-one {
width: 100%;
display: flex;
justify-content: space-around;
align-items: center;
.content {
width: 25%;
}
}
.section-two {
width: 30%;
position: absolute;
right: 150px;
bottom: 180px;
.content {
margin-top: 60px;
}
}
.section-three {
width: 100%;
display: flex;
flex-wrap: nowrap;
justify-content: space-around;
align-items: center;
.content {
width: 600px;
margin-top: 50px;
}
}
.section-four {
width: 100%;
display: flex;
justify-content: space-around;
.title {
font-size: 100px;
font-weight: 700;
margin-top: 100px;
}
.content {
width: 600px;
margin-top: 50px;
}
}
.section-five {
width: 100%;
display: flex;
justify-content: space-around;
position: relative;
.title {
position: relative;
margin-top: 500px;
}
.content {
position: relative;
margin-bottom: 200px;
width: 600px;
}
}
.nav-dots {
position: fixed;
right:40px;
top: 50%;
transform: translateY(-50%);
display: flex;
flex-direction: column;
gap: 16px;
z-index: 1000;
}
.dot {
width: 8px;
height: 8px;
background-color: rgba(255, 255, 255, 0.6);
border-radius: 50%;
cursor: pointer;
transition: background-color 0.3s ease;
}
.dot.active {
background-color: #363636;
transform: scale(1.7)
}
@keyframes bounce {
0%,
20%,
50%,
80%,
100% {
transform: translateY(0);
}
40% {
transform: translateY(-20px);
}
60% {
transform: translateY(-10px);
}
}
/* 最后一个区块不显示指示器 */
section:last-child .scroll-indicator {
display: none;
}
/* 响应式设计 */
@media (max-width: 768px) {
h1 {
font-size: 2rem;
}
p {
font-size: 1.2rem;
}
}
</style>
实现图片懒加载
最新发布