poster scroll
This commit is contained in:
+79
-11
@@ -22,10 +22,14 @@ const props = defineProps<{
|
||||
|
||||
const sunEle = useTemplateRef('sun-ani');
|
||||
const sunEndEle = useTemplateRef('sun-ani-end');
|
||||
const posterP2Ele = useTemplateRef('gui-ani-end-post-p2');
|
||||
|
||||
const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||
const emit = defineEmits(['cloudUp', 'cloudDown', 'restart']);
|
||||
|
||||
// Intersection Observer for p2 animation
|
||||
const hasP2AnimationPlayed = ref(false);
|
||||
|
||||
async function shoot() {
|
||||
//sunEle.value?.jumpTo('天上飞')
|
||||
sunEle.value?.jumpTo('蓄力飞')
|
||||
@@ -52,7 +56,7 @@ async function shoot() {
|
||||
emit('cloudUp');
|
||||
document.querySelector('.bed')?.animate([
|
||||
{ transform: 'translateY(0)' },
|
||||
{ transform: 'translateY(150%)' },
|
||||
{ transform: 'translateY(170%)' },
|
||||
], {
|
||||
duration: 500,
|
||||
delay: 200,
|
||||
@@ -547,7 +551,7 @@ async function gameEnd() {
|
||||
})
|
||||
|
||||
document.querySelector('.bed')?.animate([
|
||||
{ transform: 'translateY(150%)' },
|
||||
{ transform: 'translateY(170%)' },
|
||||
{ transform: 'translateY(0)' },
|
||||
], {
|
||||
duration: 600,
|
||||
@@ -592,7 +596,7 @@ async function gameEnd() {
|
||||
|
||||
document.querySelector('.bed')?.animate([
|
||||
{ transform: 'translateY(0)' },
|
||||
{ transform: 'translateY(150%)' },
|
||||
{ transform: 'translateY(170%)' },
|
||||
], {
|
||||
duration: 600,
|
||||
easing: 'cubic-bezier(0.4, 0, 1, 0.5)',
|
||||
@@ -713,9 +717,48 @@ async function finishCollect() {
|
||||
|
||||
showLastPage.value = true;
|
||||
|
||||
// 在最后一页显示后设置 Intersection Observer 监听 p2 元素
|
||||
await wait(100); // 等待 DOM 更新
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting && !hasP2AnimationPlayed.value) {
|
||||
// p2 进入视口且动画未播放过
|
||||
hasP2AnimationPlayed.value = true;
|
||||
posterP2Ele.value?.jumpTo('p2');
|
||||
console.log('Poster P2 animation triggered');
|
||||
|
||||
// 停止观察,因为只需要触发一次
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, {
|
||||
threshold: 0.5, // 当 50% 的元素进入视口时触发
|
||||
rootMargin: '0px'
|
||||
});
|
||||
|
||||
// 观察 p2 元素
|
||||
const p2Element = posterP2Ele.value?.$el;
|
||||
if (p2Element) {
|
||||
observer.observe(p2Element);
|
||||
console.log('Started observing P2 element');
|
||||
} else {
|
||||
console.warn('P2 element not found');
|
||||
}
|
||||
|
||||
// 8秒后如果用户没有看过p2,自动滚动到p2
|
||||
setTimeout(() => {
|
||||
if (!posterHasChangedToPage2.value) posterHasChangedToPage2.value = true;
|
||||
}, 8000);
|
||||
if (!hasP2AnimationPlayed.value) {
|
||||
console.log('Auto scrolling to P2 after 8 seconds');
|
||||
const posterContainer = document.querySelector('.poster-container');
|
||||
if (posterContainer) {
|
||||
// 滚动到p2位置(第二个元素,占总宽度的50%)
|
||||
posterContainer.scrollTo({
|
||||
left: posterContainer.scrollWidth * 0.5,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
}
|
||||
}, 8000); // 8秒 = 8000毫秒
|
||||
|
||||
}
|
||||
|
||||
@@ -883,17 +926,17 @@ function posterSwap(e: PointerEvent) {
|
||||
:rules="[{ name: 'main', frame: 41, loop: 1, pauseAfter: true, duration: 33, reverse: false }]"
|
||||
style="position: absolute;top: 13%;width: 80%;left: 11%; pointer-events:none;"
|
||||
ref="main-logo" />
|
||||
<div class="poster-container" @pointermove="posterSwap"
|
||||
style="position: absolute;top: 29.3%;left: 37.2%;width: 57.3%; height: 38%; overflow: hidden;pointer-events: all;">
|
||||
<div class="poster-container"
|
||||
style="position: absolute;top: 29.3%;left: 37.2%;width: 57.3%; height: 38%; overflow-x: auto; overflow-y: hidden; pointer-events: all; scroll-snap-type: x mandatory;">
|
||||
<div class="poster-wrapper"
|
||||
style="width: 200%; height: 100%; position: relative; overflow-x: scroll; display: flex; ">
|
||||
<AniEle :url="assets.ani.海报p1" ref="gui-ani-end-post-p1"
|
||||
style="width: 100%;" class="gui-ani-end-post"
|
||||
style="display: flex; width: 200%; height: 100%; flex-direction: row;" dir="ltr" >
|
||||
<AniEle :url="assets.ani.海报p1" ref="gui-ani-end-post-p1 "
|
||||
style="width: 50%; flex-shrink: 0; scroll-snap-align: start;" class="gui-ani-end-post"
|
||||
:height="940" :width="671" :rules="[
|
||||
{ name: 'p1', frame: 32, loop: 1, pauseAfter: true, duration: 33 },
|
||||
]" />
|
||||
<AniEle :url="assets.ani.海报p2" ref="gui-ani-end-post-p2"
|
||||
style="width: 100%;" class="gui-ani-end-post"
|
||||
style="width: 50%; flex-shrink: 0; scroll-snap-align: start;" class="gui-ani-end-post"
|
||||
:height="940" :width="671" :rules="[
|
||||
{ name: 'p2', frame: 32, loop: 1, pauseAfter: true, duration: 33 },
|
||||
]" />
|
||||
@@ -959,6 +1002,11 @@ function posterSwap(e: PointerEvent) {
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.gui-ani-end-post {
|
||||
/* 确保每个海报都能正确对齐 */
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
@keyframes last-btn-in {
|
||||
0% {
|
||||
bottom: -19%;
|
||||
@@ -1297,4 +1345,24 @@ function posterSwap(e: PointerEvent) {
|
||||
animation: scale-in 0.4s ease-in-out forwards;
|
||||
}
|
||||
}
|
||||
|
||||
.poster-container {
|
||||
/* 隐藏滚动条但保持滚动功能 */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari, Opera */
|
||||
}
|
||||
}
|
||||
|
||||
.poster-wrapper {
|
||||
/* 确保滚动流畅 */
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
.gui-ani-end-post {
|
||||
/* 确保每个海报都能正确对齐 */
|
||||
object-fit: contain;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user