You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

372 lines
8.9 KiB

<template>
<view>
<TitleHeader />
<swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange"
:duration="300" :style="{ height: `calc(100vh - ${titleHeight}px)` }">
<swiper-item>
<view class="page-container">
<template v-if="loadedPages[0]">
<image v-show="shouldShowContent(0)" class="bg-image" src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/bg1.png"
:lazy-load="true" mode="aspectFill"></image>
<image v-show="shouldShowContent(0)" class="layer-img1"
:class="{'rotate-bounce-in': animationStates[0], 'hidden': !animationStates[0]}"
src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/bg1-info.png" :lazy-load="true" mode="aspectFill">
</image>
<image v-show="shouldShowContent(0)" class="layer-info" src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/bg1-info2.png"
mode="aspectFill"></image>
</template>
</view>
</swiper-item>
<swiper-item>
<view class="page-container">
<template v-if="loadedPages[1]">
<image v-show="shouldShowContent(1)" class="bg-image" src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/bg2.png"
:lazy-load="true" mode="aspectFill"></image>
<view v-show="shouldShowContent(1)" class="layer-content">
<view class="item">
<image class="item-gif" src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/liu.gif" mode="aspectFill"></image>
<view class="layer-item-txt">
来!备的草编席垫送你,<br />咱席地而坐,边吃边唠,<br />便是人间好时节。
</view>
<view class="layer-item-tx2">
刘备 / 挚友款 · 同心桃
</view>
</view>
</view>
</template>
</view>
</swiper-item>
<swiper-item>
<view class="page-container">
<template v-if="loadedPages[2]">
<image v-show="shouldShowContent(2)" class="bg-image" src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/bg3.png"
:lazy-load="true" mode="aspectFill"></image>
<view v-show="shouldShowContent(2)" class="layer-content">
<view class="item">
<image class="item-gif" src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/guan.gif" mode="aspectFill"></image>
<view class="layer-item-txt">
某卖的不是桃,<br />是当年与兄长、三弟<br />在桃林下对饮的春秋。
</view>
<view class="layer-item-tx2">
关羽 / 挚知己款 · 对饮桃
</view>
</view>
</view>
</template>
</view>
</swiper-item>
<swiper-item>
<view class="page-container">
<template v-if="loadedPages[3]">
<image v-show="shouldShowContent(3)" class="bg-image" src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/bg4.png"
:lazy-load="true" mode="aspectFill"></image>
<view v-show="shouldShowContent(3)" class="layer-content">
<view class="item">
<image class="item-gif" src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/zhang.gif" mode="aspectFill"></image>
<view class="layer-item-txt">
瞧这桃!跟俺张飞的脾气<br />一样爽利,咬下去<br />「噗嗤」爆汁,<br />比俺大笑还痛快!
</view>
<view class="layer-item-tx2">
张飞 / 热辣款款 · 快哉桃
</view>
</view>
</view>
</template>
</view>
</swiper-item>
<swiper-item>
<view class="page-container">
<template v-if="loadedPages[4]">
<image v-show="shouldShowContent(4)" class="bg-image" src="https://static.ticket.sz-trip.com/epicSoul/taozi/chapter3/bg5.png"
:lazy-load="true" mode="aspectFill"></image>
<view class="layer2-content"
:class="{'fade-slide-up': animationStates[4], 'hidden': !animationStates[4]}">
<view class="item">
<view class="bottom-tit">
一起回桃园
</view>
<view class="bottom-tit2">
桃园不是起点,而是时间里的约定
</view>
<image class="bottom-img" src="https://static.ticket.sz-trip.com/epicSoul/taozi/home/forewordThree_icon.png" mode="aspectFill"></image>
</view>
</view>
<view @click="goBack" class="back-btn" type="default">
<image class="back-icon" src="https://static.ticket.sz-trip.com/epicSoul/taozi/back.png" mode="aspectFill"></image>
</view>
</template>
</view>
</swiper-item>
</swiper>
<AudioControl :top="'230rpx'" audioSrc="https://des.js-dyyj.com/data/2025/09/05/286e6a8d-4433-4d69-b705-74b3f4237667.MP3" />
</view>
</template>
<script>
import AudioControl from '@/components/AudioControl.vue';
import TitleHeader from '@/components/TitleHeader.vue';
export default {
components: {
TitleHeader,
AudioControl
},
data() {
return {
currentIndex: 0,
loadedPages: {
0: false,
1: false,
2: false,
3: false
},
animationStates: {
0: false,
1: false,
2: false,
3: false
},
preloadBuffer: 1,
titleHeight: 0
};
},
watch: {
currentIndex(newIndex) {
for (let i = Math.max(0, newIndex - this.preloadBuffer); i <= Math.min(9, newIndex + this
.preloadBuffer); i++) {
this.loadedPages[i] = true;
}
}
},
mounted() {
this.titleHeight = uni.getStorageSync('titleHeight')
for (let i = 0; i <= Math.min(1 + this.preloadBuffer, 9); i++) {
this.loadedPages[i] = true;
}
setTimeout(() => {
this.animationStates[this.currentIndex] = true;
}, 50);
},
methods: {
handleSwiperChange(e) {
const newIndex = e.detail.current;
this.currentIndex = newIndex;
this.animationStates[newIndex] = false;
setTimeout(() => {
this.animationStates[newIndex] = true;
}, 50);
},
shouldShowContent(index) {
return Math.abs(index - this.currentIndex) <= this.preloadBuffer;
},
goBack() {
uni.navigateTo({
url: '/taozi/home/home?targetIndex=7'
});
}
}
};
</script>
<style lang="scss" scoped>
.main-swiper {
width: 100%;
height: 100vh;
}
.page-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
position: relative;
overflow: hidden;
}
.bg-image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.layer-img1 {
z-index: 2;
position: absolute;
bottom: 300rpx;
right: 60rpx;
width: 300rpx;
height: 300rpx;
}
.layer-info {
width: 100%;
height: 280rpx;
z-index: 2;
position: absolute;
bottom: 0;
left: 0;
}
.layer-content {
position: absolute;
top: 36%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 2;
.item {
position: relative;
.item-gif {
width: 600rpx;
height: 650rpx;
}
.layer-item-txt {
position: absolute;
top: -50rpx;
left: 0;
font-size: 46rpx;
color: #e5007f;
font-weight: 600;
}
.layer-item-tx2 {
position: absolute;
right: 0;
top: -40rpx;
font-size: 36rpx;
writing-mode: vertical-rl;
text-orientation: mixed;
color: #e5007f;
font-weight: 600;
}
}
}
.layer2-content {
width: 100%;
height: 100%;
display: flex;
justify-content: flex-end;
flex-direction: column;
align-items: center;
z-index: 2;
.item {
display: flex;
flex-direction: column;
align-items: center;
width: calc(100% - 100rpx);
margin: 80rpx 0;
.bottom-img {
width: 100%;
height: 190rpx;
margin-top: 50rpx;
}
.bottom-tit {
width: 100%;
text-align: justify;
text-align-last: justify;
font-size: 100rpx;
display: inline-block;
}
.bottom-tit2 {
width: 100%;
color: #e40080;
text-align: justify;
text-align-last: justify;
display: inline-block;
}
}
}
.back-btn {
position: absolute;
top: 50rpx;
left: 50rpx;
z-index: 2;
background-color: rgb(0 0 0 / 0.3);
border-radius: 50%;
width: 80rpx;
height: 80rpx;
display: flex;
align-items: center;
justify-content: center;
}
.back-icon {
width: 50rpx;
height: 50rpx;
}
.rotate-bounce-in {
animation: rotateBounceIn 1.2s cubic-bezier(0.215, 0.610, 0.355, 1.000) forwards;
}
@keyframes rotateBounceIn {
0% {
opacity: 0;
transform: rotate(-180deg) scale(0.3);
}
40% {
opacity: 0.6;
transform: rotate(25deg) scale(0.9);
}
60% {
opacity: 0.8;
transform: rotate(-15deg) scale(1.1);
}
80% {
opacity: 0.9;
transform: rotate(5deg) scale(0.95);
}
100% {
opacity: 1;
transform: rotate(0deg) scale(1);
}
}
.slide-in-from-right {
animation: slideInRight 1.2s ease-out forwards;
}
@keyframes slideInRight {
0% {
opacity: 0;
transform: translateX(100px);
}
100% {
opacity: 1;
transform: translateX(0);
}
}
.fade-slide-up {
animation: fadeSlideUp 1s ease-out forwards;
}
@keyframes fadeSlideUp {
0% {
opacity: 0;
transform: translateY(30px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
</style>