jiazhipeng 4 months ago
parent
commit
0f3f792c8d
  1. 1
      components/MusicControl.vue
  2. 4
      pages.json
  3. 254
      xxdf/chapter1/cover1.vue
  4. 356
      xxdf/chapter1/detail1.vue
  5. 354
      xxdf/chapter1/detail2.vue
  6. 345
      xxdf/chapter1/detail3.vue
  7. 450
      xxdf/chapter1/detail4.vue
  8. 343
      xxdf/chapter1/detail5.vue
  9. 10
      xxdf/home/home.vue

1
components/MusicControl.vue

@ -15,6 +15,7 @@ export default {
} }
}, },
mounted() { mounted() {
console.log('初始化')
// //
this.syncMusicState(); this.syncMusicState();

4
pages.json

@ -167,9 +167,9 @@
] ]
}, },
{ {
"root": "xxdf", "root": "xxdf/home",
"pages": [{ "pages": [{
"path": "home/home", "path": "home",
"style": { "style": {
"navigationBarTitleText": "", "navigationBarTitleText": "",
"navigationStyle": "custom" "navigationStyle": "custom"

254
xxdf/chapter1/cover1.vue

@ -1,133 +1,147 @@
<template> <template>
<view class="chapter-cover"> <view>
<image class="cover-img" src="/static/images/chapter1/cover2.png" mode=""></image> <view class="chapter-cover">
<view class="five-senses-content" @click="goFeel"> <image class="cover-img" src="/static/images/chapter1/cover2.png" mode=""></image>
<view class="box1"></view> <view class="five-senses-content" @click="goFeel">
<view class="senses-txt"> <view class="box1"></view>
触觉 <view class="senses-txt">
</view> 触觉
</view> </view>
<view class="five-senses-content vision" @click="goVision"> </view>
<view class="box1"></view> <view class="five-senses-content vision" @click="goVision">
<view class="senses-txt"> <view class="box1"></view>
视觉 <view class="senses-txt">
</view> 视觉
</view> </view>
<view class="five-senses-content hearing" @click="goHearing"> </view>
<view class="box1"></view> <view class="five-senses-content hearing" @click="goHearing">
<view class="senses-txt"> <view class="box1"></view>
听觉 <view class="senses-txt">
</view> 听觉
</view> </view>
<view class="five-senses-content olfactory" @click="goOlfactory"> </view>
<view class="box1"></view> <view class="five-senses-content olfactory" @click="goOlfactory">
<view class="senses-txt"> <view class="box1"></view>
嗅觉 <view class="senses-txt">
</view> 嗅觉
</view> </view>
<view class="five-senses-content gustation" @click="goGustation"> </view>
<view class="box1"></view> <view class="five-senses-content gustation" @click="goGustation">
<view class="senses-txt"> <view class="box1"></view>
味觉 <view class="senses-txt">
</view> 味觉
</view> </view>
<image @click="goback" class="btn" src="/static/images/chapter1/abandon-btn.png" mode=""></image> </view>
<image @click="goback" class="btn" src="/static/images/chapter1/abandon-btn.png" mode=""></image>
</view>
<MusicControl />
</view> </view>
<MusicControl />
</template> </template>
<script setup> <script>
const goback = ()=>{ export default {
uni.navigateBack({ methods: {
delta:1 goback() {
}) uni.navigateBack({
delta: 1
});
},
goFeel() {
uni.navigateTo({
url: '/xxdf/chapter1/detail1'
});
},
goVision() {
uni.navigateTo({
url: '/xxdf/chapter1/detail2'
});
},
goHearing() {
uni.navigateTo({
url: '/xxdf/chapter1/detail3'
});
},
goOlfactory() {
uni.navigateTo({
url: '/xxdf/chapter1/detail4'
});
},
goGustation() {
uni.navigateTo({
url: '/xxdf/chapter1/detail5'
});
}
}
};
</script>
<style scoped>
.chapter-cover {
width: 100%;
height: 100vh;
position: relative;
}
.cover-img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.five-senses-content {
position: absolute;
top: 32%;
right: 28%;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
} }
const goFeel = ()=>{
uni.navigateTo({ .vision {
url:'/pages/chapter1/detail1' top: 54% !important;
}) right: 47% !important;
} }
const goVision = ()=>{
uni.navigateTo({ .hearing {
url:'/pages/chapter1/detail2' top: 62% !important;
}) right: 8% !important;
} }
const goHearing = ()=>{
uni.navigateTo({ .olfactory {
url:'/pages/chapter1/detail3' top: 64% !important;
}) right: 76% !important;
} }
const goOlfactory = ()=>{
uni.navigateTo({ .gustation {
url:'/pages/chapter1/detail4' top: 73% !important;
}) right: 86% !important;
} }
const goGustation = ()=>{
uni.navigateTo({ .box1 {
url:'/pages/chapter1/detail5' background: #fff;
}) border-radius: 50%;
opacity: 0.4;
width: 40rpx;
height: 40rpx;
} }
</script>
<style scoped> .senses-txt {
.chapter-cover { font-size: 24rpx;
width: 100%; color: rgba(255, 255, 255, 0.8);
height: 100vh; margin-top: 20rpx;
position: relative; }
}
.cover-img { .btn {
position: absolute; position: absolute;
top: 0; left: 50%;
left: 0; bottom: 11%;
width: 100%; transform: translate(-50%, -50%);
height: 100%; z-index: 2;
z-index: 1; width: 280rpx;
} height: 60rpx;
.five-senses-content{ }
position: absolute;
top: 32%;
right: 28%;
z-index: 2;
display: flex;
flex-direction: column;
align-items: center;
}
.vision{
top: 54% !important;
right: 47% !important;
}
.hearing{
top: 62% !important;
right: 8% !important;
}
.olfactory{
top: 64% !important;
right: 76% !important;
}
.gustation{
top: 73% !important;
right: 86% !important;
}
.box1{
background: #fff;
border-radius: 50%;
opacity: 0.4;
width: 40rpx;
height: 40rpx;
}
.senses-txt{
font-size: 24rpx;
color: rgba(255, 255, 255, 0.8);
margin-top: 20rpx;
}
.btn{
position: absolute;
left: 50%;
bottom: 11%;
transform: translate(-50%,-50%);
z-index: 2;
width: 280rpx;
height: 60rpx;
}
</style> </style>

356
xxdf/chapter1/detail1.vue

@ -1,193 +1,177 @@
<template> <template>
<swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300"> <view>
<swiper-item> <swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300">
<view class="page-container home-page"> <swiper-item>
<template v-if="loadedPages[0]"> <view class="page-container home-page">
<image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/feel.png" mode="" <template v-if="loadedPages[0]">
:lazy-load="true"></image> <image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/feel.png" mode=""
<view v-show="shouldShowContent(0)" class="arrow-content"> :lazy-load="true"></image>
<image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image> <view v-show="shouldShowContent(0)" class="arrow-content">
</view> <image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image>
</template> </view>
</view> </template>
</swiper-item> </view>
</swiper-item>
<swiper-item>
<view class="page-container home-page"> <swiper-item>
<template v-if="loadedPages[1]"> <view class="page-container home-page">
<image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/feel2.png" <template v-if="loadedPages[1]">
mode="" :lazy-load="true"></image> <image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/feel2.png"
<view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]"> mode="" :lazy-load="true"></image>
<image class="feel2-img" src="/static/images/chapter1/feel2-img.png" mode="" :lazy-load="true"> <view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]">
</image> <image class="feel2-img" src="/static/images/chapter1/feel2-img.png" mode="" :lazy-load="true">
</view> </image>
<image v-show="shouldShowContent(1)" @click="goback" class="btn" src="/static/reselect-btn.png" </view>
mode="" :lazy-load="true"></image> <image v-show="shouldShowContent(1)" @click="goback" class="btn" src="/static/reselect-btn.png"
</template> mode="" :lazy-load="true"></image>
</view> </template>
</swiper-item> </view>
</swiper> </swiper-item>
<MusicControl /> </swiper>
<MusicControl />
</view>
</template> </template>
<script setup> <script>
import { import MusicControl from '@/components/MusicControl.vue';
ref, export default {
reactive, components: {MusicControl},
onMounted, data() {
onUnmounted, return {
watch isVisible: false,
} from 'vue'; currentIndex: 0,
loadedPages: {
const isVisible = ref(false); 0: false,
const currentIndex = ref(0); 1: false
},
// preloadBuffer: 1
const loadedPages = reactive({ };
0: false, },
1: false methods: {
}); shouldShowContent(index) {
return Math.abs(index - this.currentIndex) <= this.preloadBuffer;
// },
const preloadBuffer = 1; // 1 handleSwiperChange(e) {
this.currentIndex = e.detail.current;
// },
const shouldShowContent = (index) => { goback() {
// preloadBuffer uni.navigateBack({
return Math.abs(index - currentIndex.value) <= preloadBuffer; delta: 1
}; });
}
// currentIndex },
watch(currentIndex, (newIndex) => { watch: {
// buffer currentIndex: {
for (let i = Math.max(0, newIndex - preloadBuffer); i <= Math.min(1, newIndex + preloadBuffer); i++) { handler(newIndex) {
loadedPages[i] = true; for (let i = Math.max(0, newIndex - this.preloadBuffer); i <= Math.min(1, newIndex + this.preloadBuffer); i++) {
} this.loadedPages[i] = true;
}
// this.isVisible = newIndex === 1;
isVisible.value = newIndex === 1; },
}, { immediate: true
immediate: true }
}); },
mounted() {
const handleSwiperChange = (e) => { this.loadedPages[0] = true;
currentIndex.value = e.detail.current; if (this.preloadBuffer >= 1) {
}; this.loadedPages[1] = true;
}
const goback = () => { }
uni.navigateBack({ };
delta: 1
});
};
onMounted(() => {
//
loadedPages[0] = true;
// 1
if (preloadBuffer >= 1) {
loadedPages[1] = true;
}
});
</script> </script>
<style scoped> <style scoped>
.main-swiper { .main-swiper {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
} }
.page-container { .page-container {
height: 100vh; height: 100vh;
} }
.home-page { .home-page {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
.bg-image { .bg-image {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 1; z-index: 1;
} }
.animate-content {
.animate-content { position: absolute;
position: absolute; left: 0;
left: 0; top: 18%;
top: 18%; width: 100%;
width: 100%; display: flex;
display: flex; justify-content: center;
justify-content: center; z-index: 2;
z-index: 2; opacity: 0;
opacity: 0; transform: scale(0.9);
transform: scale(0.9); filter: blur(5px);
filter: blur(5px); transition: opacity 0.6s ease-out 0.2s,
transition: opacity 0.6s ease-out 0.2s, transform 0.6s ease-out 0.2s,
transform 0.6s ease-out 0.2s, filter 0.6s ease-out 0.2s;
filter 0.6s ease-out 0.2s; }
}
.animate-visible {
.animate-visible { opacity: 1;
opacity: 1; transform: scale(1);
transform: scale(1); filter: blur(0px);
filter: blur(0px); }
}
.feel2-img {
width: 89%;
.feel2-img { height: 248rpx;
width: 89%; }
height: 248rpx;
} .arrow-content {
width: 100%;
.arrow-content { position: absolute;
width: 100%; bottom: 5%;
position: absolute; left: 50%;
bottom: 5%; transform: translate(-50%, -50%);
left: 50%; display: flex;
transform: translate(-50%, -50%); align-items: center;
display: flex; justify-content: center;
align-items: center; z-index: 2;
justify-content: center; }
z-index: 2;
} .arrow-down {
width: 200rpx;
.arrow-down { height: 40rpx;
width: 200rpx; animation: bounce 1.5s infinite;
height: 40rpx; }
animation: bounce 1.5s infinite;
} .btn {
position: absolute;
.btn { left: 50%;
position: absolute; bottom: 12%;
left: 50%; transform: translate(-50%, -50%);
bottom: 12%; z-index: 2;
transform: translate(-50%, -50%); width: 180rpx;
z-index: 2; height: 56rpx;
width: 180rpx; }
height: 56rpx;
} @keyframes bounce {
0%,
@keyframes bounce { 20%,
50%,
0%, 80%,
20%, 100% {
50%, transform: translateY(0);
80%, }
100% { 40% {
transform: translateY(0); transform: translateY(-20rpx);
} }
60% {
40% { transform: translateY(-10rpx);
transform: translateY(-20rpx); }
} }
60% {
transform: translateY(-10rpx);
}
}
</style> </style>

354
xxdf/chapter1/detail2.vue

@ -1,193 +1,175 @@
<template> <template>
<swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300"> <view>
<swiper-item> <swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300">
<view class="page-container home-page"> <swiper-item>
<template v-if="loadedPages[0]"> <view class="page-container home-page">
<image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/vision.png" <template v-if="loadedPages[0]">
mode="" :lazy-load="true"></image> <image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/vision.png"
<view v-show="shouldShowContent(0)" class="arrow-content"> mode="" :lazy-load="true"></image>
<image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image> <view v-show="shouldShowContent(0)" class="arrow-content">
</view> <image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image>
</template> </view>
</view> </template>
</swiper-item> </view>
</swiper-item>
<swiper-item>
<view class="page-container home-page"> <swiper-item>
<template v-if="loadedPages[1]"> <view class="page-container home-page">
<image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/vision2.png" <template v-if="loadedPages[1]">
mode="" :lazy-load="true"></image> <image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/vision2.png"
<view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]"> mode="" :lazy-load="true"></image>
<image class="feel2-img" src="/static/images/chapter1/vision2-img.png" mode="" <view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]">
:lazy-load="true"></image> <image class="feel2-img" src="/static/images/chapter1/vision2-img.png" mode=""
</view> :lazy-load="true"></image>
<image v-show="shouldShowContent(1)" @click="goback" class="btn" src="/static/reselect-btn.png" </view>
mode="" :lazy-load="true"></image> <image v-show="shouldShowContent(1)" @click="goback" class="btn" src="/static/reselect-btn.png"
</template> mode="" :lazy-load="true"></image>
</view> </template>
</swiper-item> </view>
</swiper> </swiper-item>
<MusicControl /> </swiper>
<MusicControl />
</view>
</template> </template>
<script setup> <script>
import { export default {
ref, data() {
reactive, return {
onMounted, isVisible: false,
onUnmounted, currentIndex: 0,
watch loadedPages: {
} from 'vue'; 0: false,
1: false
const isVisible = ref(false); },
const currentIndex = ref(0); preloadBuffer: 1
};
// },
const loadedPages = reactive({ methods: {
0: false, shouldShowContent(index) {
1: false return Math.abs(index - this.currentIndex) <= this.preloadBuffer;
}); },
handleSwiperChange(e) {
// this.currentIndex = e.detail.current;
const preloadBuffer = 1; // 1 },
goback() {
// uni.navigateBack({
const shouldShowContent = (index) => { delta: 1
// preloadBuffer });
return Math.abs(index - currentIndex.value) <= preloadBuffer; }
}; },
watch: {
// currentIndex currentIndex: {
watch(currentIndex, (newIndex) => { handler(newIndex) {
// buffer for (let i = Math.max(0, newIndex - this.preloadBuffer); i <= Math.min(1, newIndex + this.preloadBuffer); i++) {
for (let i = Math.max(0, newIndex - preloadBuffer); i <= Math.min(1, newIndex + preloadBuffer); i++) { this.loadedPages[i] = true;
loadedPages[i] = true; }
} this.isVisible = newIndex === 1;
},
// immediate: true
isVisible.value = newIndex === 1; }
}, { },
immediate: true mounted() {
}); this.loadedPages[0] = true;
if (this.preloadBuffer >= 1) {
const handleSwiperChange = (e) => { this.loadedPages[1] = true;
currentIndex.value = e.detail.current; }
}; }
};
const goback = () => {
uni.navigateBack({
delta: 1
});
};
onMounted(() => {
//
loadedPages[0] = true;
// 1
if (preloadBuffer >= 1) {
loadedPages[1] = true;
}
});
</script> </script>
<style scoped> <style scoped>
.main-swiper { .main-swiper {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
} }
.page-container { .page-container {
height: 100vh; height: 100vh;
} }
.home-page { .home-page {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
.bg-image { .bg-image {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 1; z-index: 1;
} }
.animate-content {
.animate-content { position: absolute;
position: absolute; left: 0;
left: 0; top: 16%;
top: 16%; width: 100%;
width: 100%; display: flex;
display: flex; justify-content: center;
justify-content: center; z-index: 2;
z-index: 2; opacity: 0;
opacity: 0; transform: scale(0.9);
transform: scale(0.9); filter: blur(5px);
filter: blur(5px); transition: opacity 0.6s ease-out 0.2s,
transition: opacity 0.6s ease-out 0.2s, transform 0.6s ease-out 0.2s,
transform 0.6s ease-out 0.2s, filter 0.6s ease-out 0.2s;
filter 0.6s ease-out 0.2s; }
}
.animate-visible {
.animate-visible { opacity: 1;
opacity: 1; transform: scale(1);
transform: scale(1); filter: blur(0px);
filter: blur(0px); }
}
.feel2-img {
width: 89%;
.feel2-img { height: 248rpx;
width: 89%; }
height: 248rpx;
} .arrow-content {
width: 100%;
.arrow-content { position: absolute;
width: 100%; bottom: 5%;
position: absolute; left: 50%;
bottom: 5%; transform: translate(-50%, -50%);
left: 50%; display: flex;
transform: translate(-50%, -50%); align-items: center;
display: flex; justify-content: center;
align-items: center; z-index: 2;
justify-content: center; }
z-index: 2;
} .arrow-down {
width: 200rpx;
.arrow-down { height: 40rpx;
width: 200rpx; animation: bounce 1.5s infinite;
height: 40rpx; }
animation: bounce 1.5s infinite;
} .btn {
position: absolute;
.btn { left: 50%;
position: absolute; bottom: 12%;
left: 50%; transform: translate(-50%, -50%);
bottom: 12%; z-index: 2;
transform: translate(-50%, -50%); width: 180rpx;
z-index: 2; height: 56rpx;
width: 180rpx; }
height: 56rpx;
} @keyframes bounce {
0%,
@keyframes bounce { 20%,
50%,
0%, 80%,
20%, 100% {
50%, transform: translateY(0);
80%, }
100% { 40% {
transform: translateY(0); transform: translateY(-20rpx);
} }
60% {
40% { transform: translateY(-10rpx);
transform: translateY(-20rpx); }
} }
60% {
transform: translateY(-10rpx);
}
}
</style> </style>

345
xxdf/chapter1/detail3.vue

@ -1,188 +1,173 @@
<template> <template>
<swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300"> <view>
<swiper-item>
<view class="page-container home-page">
<template v-if="loadedPages[0]"> <swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300">
<image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/hearing.png" mode="" :lazy-load="true"></image> <swiper-item>
<view v-show="shouldShowContent(0)" class="arrow-content"> <view class="page-container home-page">
<image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image> <template v-if="loadedPages[0]">
</view> <image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/hearing.png" mode="" :lazy-load="true"></image>
</template> <view v-show="shouldShowContent(0)" class="arrow-content">
</view> <image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image>
</swiper-item> </view>
</template>
<swiper-item> </view>
<view class="page-container home-page"> </swiper-item>
<template v-if="loadedPages[1]">
<image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/hearing2.png" mode="" :lazy-load="true"></image> <swiper-item>
<view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]"> <view class="page-container home-page">
<image class="feel2-img" src="/static/images/chapter1/hearing2-img.png" mode="" :lazy-load="true"></image> <template v-if="loadedPages[1]">
</view> <image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/hearing2.png" mode="" :lazy-load="true"></image>
<image v-show="shouldShowContent(1)" @click="goback" class="btn" src="/static/reselect-btn.png" mode="" :lazy-load="true"></image> <view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]">
</template> <image class="feel2-img" src="/static/images/chapter1/hearing2-img.png" mode="" :lazy-load="true"></image>
</view> </view>
</swiper-item> <image v-show="shouldShowContent(1)" @click="goback" class="btn" src="/static/reselect-btn.png" mode="" :lazy-load="true"></image>
</swiper> </template>
<MusicControl /> </view>
</swiper-item>
</swiper>
<MusicControl />
</view>
</template> </template>
<script setup> <script>
import { export default {
ref, data() {
reactive, return {
onMounted, isVisible: false,
onUnmounted, currentIndex: 0,
watch loadedPages: {
} from 'vue'; 0: false,
1: false
const isVisible = ref(false); },
const currentIndex = ref(0); preloadBuffer: 1
};
// },
const loadedPages = reactive({ methods: {
0: false, shouldShowContent(index) {
1: false return Math.abs(index - this.currentIndex) <= this.preloadBuffer;
}); },
handleSwiperChange(e) {
// this.currentIndex = e.detail.current;
const preloadBuffer = 1; },
goback() {
// uni.navigateBack({
const shouldShowContent = (index) => { delta: 1
// preloadBuffer });
return Math.abs(index - currentIndex.value) <= preloadBuffer; }
}; },
watch: {
// currentIndex currentIndex: {
watch(currentIndex, (newIndex) => { handler(newIndex) {
// buffer for (let i = Math.max(0, newIndex - this.preloadBuffer); i <= Math.min(1, newIndex + this.preloadBuffer); i++) {
for (let i = Math.max(0, newIndex - preloadBuffer); i <= Math.min(1, newIndex + preloadBuffer); i++) { this.loadedPages[i] = true;
loadedPages[i] = true; }
} this.isVisible = newIndex === 1;
},
// immediate: true
isVisible.value = newIndex === 1; }
}, { immediate: true }); },
mounted() {
const handleSwiperChange = (e) => { this.loadedPages[0] = true;
currentIndex.value = e.detail.current; if (this.preloadBuffer >= 1) {
this.loadedPages[1] = true;
}
}
}; };
const goback = () => {
uni.navigateBack({
delta: 1
});
};
onMounted(() => {
//
loadedPages[0] = true;
// 1
if(preloadBuffer >= 1) {
loadedPages[1] = true;
}
});
</script> </script>
<style scoped> <style scoped>
.main-swiper { .main-swiper {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
} }
.page-container { .page-container {
height: 100vh; height: 100vh;
} }
.home-page { .home-page {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
.bg-image { .bg-image {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 1; z-index: 1;
} }
.animate-content {
.animate-content { position: absolute;
position: absolute; left: 0;
left: 0; top: 16%;
top: 16%; width: 100%;
width: 100%; display: flex;
display: flex; justify-content: center;
justify-content: center; z-index: 2;
z-index: 2; opacity: 0;
opacity: 0; transform: scale(0.9);
transform: scale(0.9); filter: blur(5px);
filter: blur(5px); transition: opacity 0.6s ease-out 0.2s,
transition: opacity 0.6s ease-out 0.2s, transform 0.6s ease-out 0.2s,
transform 0.6s ease-out 0.2s, filter 0.6s ease-out 0.2s;
filter 0.6s ease-out 0.2s; }
}
.animate-visible {
.animate-visible { opacity: 1;
opacity: 1; transform: scale(1);
transform: scale(1); filter: blur(0px);
filter: blur(0px); }
}
.feel2-img {
width: 89%;
.feel2-img { height: 228rpx;
width: 89%; }
height: 228rpx;
} .arrow-content {
width: 100%;
.arrow-content { position: absolute;
width: 100%; bottom: 5%;
position: absolute; left: 50%;
bottom: 5%; transform: translate(-50%, -50%);
left: 50%; display: flex;
transform: translate(-50%, -50%); align-items: center;
display: flex; justify-content: center;
align-items: center; z-index: 2;
justify-content: center; }
z-index: 2;
} .arrow-down {
width: 200rpx;
.arrow-down { height: 40rpx;
width: 200rpx; animation: bounce 1.5s infinite;
height: 40rpx; }
animation: bounce 1.5s infinite;
} .btn {
position: absolute;
.btn { left: 50%;
position: absolute; bottom: 12%;
left: 50%; transform: translate(-50%, -50%);
bottom: 12%; z-index: 2;
transform: translate(-50%, -50%); width: 180rpx;
z-index: 2; height: 56rpx;
width: 180rpx; }
height: 56rpx;
} @keyframes bounce {
0%,
@keyframes bounce { 20%,
50%,
0%, 80%,
20%, 100% {
50%, transform: translateY(0);
80%, }
100% { 40% {
transform: translateY(0); transform: translateY(-20rpx);
} }
60% {
40% { transform: translateY(-10rpx);
transform: translateY(-20rpx); }
} }
60% {
transform: translateY(-10rpx);
}
}
</style> </style>

450
xxdf/chapter1/detail4.vue

@ -1,239 +1,227 @@
<template> <template>
<swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300"> <view>
<swiper-item>
<view class="page-container home-page">
<template v-if="loadedPages[0]"> <swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300">
<image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/olfactory.png" mode="" :lazy-load="true"></image> <swiper-item>
<view v-show="shouldShowContent(0)" class="arrow-content"> <view class="page-container home-page">
<image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image> <template v-if="loadedPages[0]">
</view> <image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/olfactory.png" mode="" :lazy-load="true"></image>
</template> <view v-show="shouldShowContent(0)" class="arrow-content">
</view> <image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image>
</swiper-item> </view>
</template>
<swiper-item> </view>
<view class="page-container home-page"> </swiper-item>
<template v-if="loadedPages[1]">
<image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/olfactory2.png" mode="" :lazy-load="true"></image> <swiper-item>
<view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]"> <view class="page-container home-page">
<image class="feel2-img" src="/static/images/chapter1/olfactory2-img.png" mode="" :lazy-load="true"></image> <template v-if="loadedPages[1]">
</view> <image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/olfactory2.png" mode="" :lazy-load="true"></image>
</template> <view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]">
</view> <image class="feel2-img" src="/static/images/chapter1/olfactory2-img.png" mode="" :lazy-load="true"></image>
</swiper-item> </view>
</template>
<swiper-item> </view>
<view class="page-container home-page"> </swiper-item>
<template v-if="loadedPages[2]">
<image v-show="shouldShowContent(2)" class="bg-image" src="/static/images/chapter1/olfactory4.png" mode="" :lazy-load="true"></image> <swiper-item>
<view v-show="shouldShowContent(2)" :class="['animate-content2', {'animate-visible': isVisible2}]"> <view class="page-container home-page">
<image class="feel4-img" src="/static/images/chapter1/olfactory4-img.png" mode="" :lazy-load="true"></image> <template v-if="loadedPages[2]">
</view> <image v-show="shouldShowContent(2)" class="bg-image" src="/static/images/chapter1/olfactory4.png" mode="" :lazy-load="true"></image>
</template> <view v-show="shouldShowContent(2)" :class="['animate-content2', {'animate-visible': isVisible2}]">
</view> <image class="feel4-img" src="/static/images/chapter1/olfactory4-img.png" mode="" :lazy-load="true"></image>
</swiper-item> </view>
</template>
<swiper-item> </view>
<view class="page-container home-page"> </swiper-item>
<template v-if="loadedPages[3]">
<image v-show="shouldShowContent(3)" class="bg-image" src="/static/images/chapter1/olfactory3.png" mode="" :lazy-load="true"></image> <swiper-item>
<image v-show="shouldShowContent(3)" class="feel3-img" src="/static/images/chapter1/olfactory3-img.png" mode="" :lazy-load="true"></image> <view class="page-container home-page">
<image v-show="shouldShowContent(3)" @click="goback" class="btn" src="/static/seek-btn.png" mode="" :lazy-load="true"></image> <template v-if="loadedPages[3]">
</template> <image v-show="shouldShowContent(3)" class="bg-image" src="/static/images/chapter1/olfactory3.png" mode="" :lazy-load="true"></image>
</view> <image v-show="shouldShowContent(3)" class="feel3-img" src="/static/images/chapter1/olfactory3-img.png" mode="" :lazy-load="true"></image>
</swiper-item> <image v-show="shouldShowContent(3)" @click="goback" class="btn" src="/static/seek-btn.png" mode="" :lazy-load="true"></image>
</swiper> </template>
<MusicControl /> </view>
</swiper-item>
</swiper>
<MusicControl />
</view>
</template> </template>
<script setup> <script>
import { export default {
ref, data() {
reactive, return {
onMounted, isVisible: false,
onUnmounted, isVisible2: false,
watch currentIndex: 0,
} from 'vue'; loadedPages: {
0: false,
const isVisible = ref(false); 1: false,
const isVisible2 = ref(false); 2: false,
const currentIndex = ref(0); 3: false
},
// preloadBuffer: 1
const loadedPages = reactive({ };
0: false, },
1: false, methods: {
2: false, shouldShowContent(index) {
3: false return Math.abs(index - this.currentIndex) <= this.preloadBuffer;
}); },
handleSwiperChange(e) {
// this.currentIndex = e.detail.current;
const preloadBuffer = 1; },
goback() {
// const app = getApp();
const shouldShowContent = (index) => { app.globalData.mainSliderIndex = 3;
// preloadBuffer uni.navigateTo({
return Math.abs(index - currentIndex.value) <= preloadBuffer; url: '/xxdf/home/home'
});
}
},
watch: {
currentIndex: {
handler(newIndex) {
for (let i = Math.max(0, newIndex - this.preloadBuffer); i <= Math.min(3, newIndex + this.preloadBuffer); i++) {
this.loadedPages[i] = true;
}
this.isVisible = newIndex === 1;
this.isVisible2 = newIndex === 2;
},
immediate: true
}
},
mounted() {
this.loadedPages[0] = true;
if (this.preloadBuffer >= 1) {
this.loadedPages[1] = true;
}
}
}; };
// currentIndex
watch(currentIndex, (newIndex) => {
// buffer
for (let i = Math.max(0, newIndex - preloadBuffer); i <= Math.min(3, newIndex + preloadBuffer); i++) {
loadedPages[i] = true;
}
//
isVisible.value = newIndex === 1;
isVisible2.value = newIndex === 2;
}, { immediate: true });
const handleSwiperChange = (e) => {
currentIndex.value = e.detail.current;
};
const goback = () => {
const app = getApp();
app.globalData.mainSliderIndex = 3;
uni.navigateTo({
url: '/pages/home/home'
});
};
onMounted(() => {
//
loadedPages[0] = true;
//
if(preloadBuffer >= 1) {
loadedPages[1] = true;
}
});
</script> </script>
<style scoped> <style scoped>
.main-swiper { .main-swiper {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
} }
.page-container { .page-container {
height: 100vh; height: 100vh;
} }
.home-page { .home-page {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
.bg-image { .bg-image {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 1; z-index: 1;
} }
.animate-content2 { .animate-content2 {
position: absolute; position: absolute;
left: 0; left: 0;
top: 25%; top: 25%;
width: 100%; width: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
z-index: 2; z-index: 2;
opacity: 0; opacity: 0;
transform: scale(0.9); transform: scale(0.9);
filter: blur(5px); filter: blur(5px);
transition: opacity 0.6s ease-out 0.2s, transition: opacity 0.6s ease-out 0.2s,
transform 0.6s ease-out 0.2s, transform 0.6s ease-out 0.2s,
filter 0.6s ease-out 0.2s; filter 0.6s ease-out 0.2s;
} }
.animate-content { .animate-content {
position: absolute; position: absolute;
left: 6%; left: 6%;
top: 32%; top: 32%;
width: 100%; width: 100%;
display: flex; display: flex;
z-index: 2; z-index: 2;
/* 初始状态 */ /* 初始状态 */
opacity: 0; opacity: 0;
transform: translateX(-50px) scale(0.95); transform: translateX(-50px) scale(0.95);
filter: blur(2px); filter: blur(2px);
/* 过渡效果 */ /* 过渡效果 */
transition: opacity 0.7s ease-out 0.3s, transition: opacity 0.7s ease-out 0.3s,
transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) 0.3s, transform 0.8s cubic-bezier(0.2, 0.8, 0.2, 1) 0.3s,
filter 0.6s ease-out 0.3s; filter 0.6s ease-out 0.3s;
} }
.animate-visible { .animate-visible {
opacity: 1; opacity: 1;
transform: translateX(0) scale(1); transform: translateX(0) scale(1);
filter: blur(0); filter: blur(0);
} }
.feel2-img {
.feel2-img { width: 300rpx;
width: 300rpx; }
}
.feel3-img {
.feel3-img { width: 100%;
width: 100%; height: 650rpx;
height: 650rpx; z-index: 2;
z-index: 2; position: relative
position: relative }
}
.feel4-img{ .feel4-img {
width: 100%; width: 100%;
height: 400rpx; height: 400rpx;
} }
.arrow-content {
width: 100%; .arrow-content {
position: absolute; width: 100%;
bottom: 5%; position: absolute;
left: 50%; bottom: 5%;
transform: translate(-50%, -50%); left: 50%;
display: flex; transform: translate(-50%, -50%);
align-items: center; display: flex;
justify-content: center; align-items: center;
z-index: 2; justify-content: center;
} z-index: 2;
}
.arrow-down {
width: 200rpx; .arrow-down {
height: 40rpx; width: 200rpx;
animation: bounce 1.5s infinite; height: 40rpx;
} animation: bounce 1.5s infinite;
}
.btn {
position: absolute; .btn {
left: 50%; position: absolute;
bottom: 12%; left: 50%;
transform: translate(-50%, -50%); bottom: 12%;
z-index: 2; transform: translate(-50%, -50%);
width: 270rpx; z-index: 2;
height: 60rpx; width: 270rpx;
} height: 60rpx;
}
@keyframes bounce {
@keyframes bounce {
0%, 0%,
20%, 20%,
50%, 50%,
80%, 80%,
100% { 100% {
transform: translateY(0); transform: translateY(0);
} }
40% {
40% { transform: translateY(-20rpx);
transform: translateY(-20rpx); }
} 60% {
transform: translateY(-10rpx);
60% { }
transform: translateY(-10rpx); }
}
}
</style> </style>

343
xxdf/chapter1/detail5.vue

@ -1,187 +1,172 @@
<template> <template>
<swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300"> <view>
<swiper-item>
<view class="page-container home-page">
<template v-if="loadedPages[0]"> <swiper class="main-swiper" :vertical="true" :current="currentIndex" @change="handleSwiperChange" :duration="300">
<image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/gustation.png" mode="" :lazy-load="true"></image> <swiper-item>
<view v-show="shouldShowContent(0)" class="arrow-content"> <view class="page-container home-page">
<image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image> <template v-if="loadedPages[0]">
</view> <image v-show="shouldShowContent(0)" class="bg-image" src="/static/images/chapter1/gustation.png" mode="" :lazy-load="true"></image>
</template> <view v-show="shouldShowContent(0)" class="arrow-content">
</view> <image class="arrow-down" src="/static/arrow-icon-black.png" mode="" :lazy-load="true"></image>
</swiper-item> </view>
</template>
<swiper-item> </view>
<view class="page-container home-page"> </swiper-item>
<template v-if="loadedPages[1]">
<image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/gustation2.png" mode="" :lazy-load="true"></image> <swiper-item>
<view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]"> <view class="page-container home-page">
<image class="feel2-img" src="/static/images/chapter1/gustation2-img.png" mode="" :lazy-load="true"></image> <template v-if="loadedPages[1]">
</view> <image v-show="shouldShowContent(1)" class="bg-image" src="/static/images/chapter1/gustation2.png" mode="" :lazy-load="true"></image>
<image v-show="shouldShowContent(1)" @click="goback" class="btn" src="/static/reselect-btn.png" mode="" :lazy-load="true"></image> <view v-show="shouldShowContent(1)" :class="['animate-content', {'animate-visible': isVisible}]">
</template> <image class="feel2-img" src="/static/images/chapter1/gustation2-img.png" mode="" :lazy-load="true"></image>
</view> </view>
</swiper-item> <image v-show="shouldShowContent(1)" @click="goback" class="btn" src="/static/reselect-btn.png" mode="" :lazy-load="true"></image>
</swiper> </template>
<MusicControl /> </view>
</swiper-item>
</swiper>
<MusicControl />
</view>
</template> </template>
<script setup> <script>
import { export default {
ref, data() {
reactive, return {
onMounted, isVisible: false,
onUnmounted, currentIndex: 0,
watch loadedPages: {
} from 'vue'; 0: false,
1: false
const isVisible = ref(false); },
const currentIndex = ref(0); preloadBuffer: 1
};
// },
const loadedPages = reactive({ methods: {
0: false, shouldShowContent(index) {
1: false return Math.abs(index - this.currentIndex) <= this.preloadBuffer;
}); },
handleSwiperChange(e) {
// this.currentIndex = e.detail.current;
const preloadBuffer = 1; },
goback() {
// uni.navigateBack({
const shouldShowContent = (index) => { delta: 1
// preloadBuffer });
return Math.abs(index - currentIndex.value) <= preloadBuffer; }
}; },
watch: {
// currentIndex currentIndex: {
watch(currentIndex, (newIndex) => { handler(newIndex) {
// buffer for (let i = Math.max(0, newIndex - this.preloadBuffer); i <= Math.min(1, newIndex + this.preloadBuffer); i++) {
for (let i = Math.max(0, newIndex - preloadBuffer); i <= Math.min(1, newIndex + preloadBuffer); i++) { this.loadedPages[i] = true;
loadedPages[i] = true; }
} this.isVisible = newIndex === 1;
},
// immediate: true
isVisible.value = newIndex === 1; }
}, { immediate: true }); },
mounted() {
const handleSwiperChange = (e) => { this.loadedPages[0] = true;
currentIndex.value = e.detail.current; if (this.preloadBuffer >= 1) {
this.loadedPages[1] = true;
}
}
}; };
const goback = () => {
uni.navigateBack({
delta: 1
});
};
onMounted(() => {
//
loadedPages[0] = true;
// 1
if(preloadBuffer >= 1) {
loadedPages[1] = true;
}
});
</script> </script>
<style scoped> <style scoped>
.main-swiper { .main-swiper {
width: 100%; width: 100%;
height: 100vh; height: 100vh;
} }
.page-container { .page-container {
height: 100vh; height: 100vh;
} }
.home-page { .home-page {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
} }
.bg-image { .bg-image {
position: absolute; position: absolute;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 1; z-index: 1;
} }
.animate-content {
.animate-content { position: absolute;
position: absolute; right: 6%;
right: 6%; top: 24%;
top: 24%; display: flex;
display: flex; justify-content: center;
justify-content: center; z-index: 2;
z-index: 2; opacity: 0;
opacity: 0; transform: scale(0.9);
transform: scale(0.9); filter: blur(5px);
filter: blur(5px); transition: opacity 0.6s ease-out 0.2s,
transition: opacity 0.6s ease-out 0.2s, transform 0.6s ease-out 0.2s,
transform 0.6s ease-out 0.2s, filter 0.6s ease-out 0.2s;
filter 0.6s ease-out 0.2s; }
}
.animate-visible {
.animate-visible { opacity: 1;
opacity: 1; transform: scale(1);
transform: scale(1); filter: blur(0px);
filter: blur(0px); }
}
.feel2-img {
width: 310rpx;
.feel2-img { height: 410rpx;
width: 310rpx; }
height: 410rpx;
} .arrow-content {
width: 100%;
.arrow-content { position: absolute;
width: 100%; bottom: 5%;
position: absolute; left: 50%;
bottom: 5%; transform: translate(-50%, -50%);
left: 50%; display: flex;
transform: translate(-50%, -50%); align-items: center;
display: flex; justify-content: center;
align-items: center; z-index: 2;
justify-content: center; }
z-index: 2;
} .arrow-down {
width: 200rpx;
.arrow-down { height: 40rpx;
width: 200rpx; animation: bounce 1.5s infinite;
height: 40rpx; }
animation: bounce 1.5s infinite;
} .btn {
position: absolute;
.btn { left: 50%;
position: absolute; bottom: 12%;
left: 50%; transform: translate(-50%, -50%);
bottom: 12%; z-index: 2;
transform: translate(-50%, -50%); width: 180rpx;
z-index: 2; height: 56rpx;
width: 180rpx; }
height: 56rpx;
} @keyframes bounce {
0%,
@keyframes bounce { 20%,
50%,
0%, 80%,
20%, 100% {
50%, transform: translateY(0);
80%, }
100% { 40% {
transform: translateY(0); transform: translateY(-20rpx);
} }
60% {
40% { transform: translateY(-10rpx);
transform: translateY(-20rpx); }
} }
60% {
transform: translateY(-10rpx);
}
}
</style> </style>

10
xxdf/home/home.vue

@ -154,22 +154,22 @@ export default {
}, },
navigateToChapter1() { navigateToChapter1() {
uni.navigateTo({ uni.navigateTo({
url: '/pages/chapter1/cover1' url: '/xxdf/chapter1/cover1'
}); });
}, },
navigateToChapter2() { navigateToChapter2() {
uni.navigateTo({ uni.navigateTo({
url: '/pages/chapter2/cover' url: '/xxdf/chapter2/cover'
}); });
}, },
navigateToChapter3() { navigateToChapter3() {
uni.navigateTo({ uni.navigateTo({
url: '/pages/chapter3/cover' url: '/xxdf/chapter3/cover'
}); });
}, },
navigateToChapter4() { navigateToChapter4() {
uni.navigateTo({ uni.navigateTo({
url: '/pages/chapter4/cover' url: '/xxdf/chapter4/cover'
}); });
} }
}, },
@ -205,7 +205,7 @@ export default {
return { return {
title: '细嗅东方|「Epic Soul」阅读体 issue02', title: '细嗅东方|「Epic Soul」阅读体 issue02',
mpId: 'wx8954209bb3ad489e', mpId: 'wx8954209bb3ad489e',
path: '/pages/chapter4/cover', path: '/xxdf/chapter4/cover',
imageUrl: '/static/share-img.jpg' imageUrl: '/static/share-img.jpg'
}; };
}, },

Loading…
Cancel
Save