1351 lines
34 KiB
Vue
1351 lines
34 KiB
Vue
<template>
|
||
<view class="welcome-mask" @click="onBgClick">
|
||
<text class="header-text">SKIP</text>
|
||
|
||
<!-- 背景层 -->
|
||
<view class="background-layer">
|
||
<!-- 场景1: 视频图.mp4 -->
|
||
<view v-if="currentScene === 0" class="scene1-wrapper">
|
||
<video class="bg-media" src="/static/animation/animation1.mp4" loop autoplay muted object-fit="fill"
|
||
:show-center-play-btn="false" :show-play-btn="false" :enable-progress-gesture="false"
|
||
:controls="false"></video>
|
||
<!-- 场景1对话框 - 位置动态配置 -->
|
||
<view class="scene1-dialog" :style="{ left: currentDialogPos.left, top: currentDialogPos.top }"
|
||
:class="{ visible: dialogVisible }">
|
||
<image class="dialog-bg" src="/static/animation/dialog-monster/dialog.png" mode="aspectFit" />
|
||
<view class="dialog-text-wrapper-vertical">
|
||
<text class="dialog-text-vertical">{{ currentText }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 场景2: 视频轮播 图3,图4,图5 (三个独立区域) -->
|
||
<view v-else-if="currentScene === 1" class="scene2-layout">
|
||
<!-- 图3: 底层视频 (始终显示) -->
|
||
<view class="scene2-item scene2-item-1">
|
||
<video class="scene2-video" src="/static/animation/animation3.mp4" loop autoplay muted
|
||
object-fit="fill" :show-center-play-btn="false" :show-play-btn="false"
|
||
:enable-progress-gesture="false" :controls="false"></video>
|
||
</view>
|
||
<!-- 图4: 上层视频 (scene2SubPhase >= 1 时显示) -->
|
||
<view v-if="scene2SubPhase >= 1" class="scene2-item scene2-item-2 visible">
|
||
<video class="scene2-video scene2-video-right" src="/static/animation/animation4.mp4" loop autoplay
|
||
muted object-fit="fill" :show-center-play-btn="false" :show-play-btn="false"
|
||
:enable-progress-gesture="false" :controls="false"></video>
|
||
</view>
|
||
<!-- 图4对话框: 覆盖在图3上面 (scene2SubPhase >= 1 时显示) -->
|
||
<view v-if="scene2SubPhase >= 1" class="scene2-dialog-on-video3"
|
||
:style="{ left: scene1DialogOnVideo3Pos.left, top: scene1DialogOnVideo3Pos.top }"
|
||
:class="{ visible: dialogVisible }">
|
||
<image class="dialog-bg dialog-bg-oval" src="/static/animation/dialog-monster/oval-dialog1.png"
|
||
mode="aspectFit" />
|
||
<view class="dialog-text-wrapper-vertical dialog-text-wrapper-vertical-on-video3">
|
||
<text class="dialog-text-vertical">{{ scene2Video4Text }}</text>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 图5: 视频 (scene2SubPhase >= 2 时显示) -->
|
||
<view v-if="scene2SubPhase >= 2" class="scene2-item scene2-item-3 visible">
|
||
<view class="scene2-video-crop">
|
||
<video class="scene2-video scene2-video-crop-inner" src="/static/animation/animation5.mp4" loop
|
||
autoplay muted object-fit="fill" :show-center-play-btn="false" :show-play-btn="false"
|
||
:enable-progress-gesture="false" :controls="false"></video>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 图5对话框: 覆盖在图4上面 (scene2SubPhase >= 2 时显示) -->
|
||
<view v-if="scene2SubPhase >= 2" class="scene2-dialog-on-video4"
|
||
:style="{ left: scene2DialogOnVideo5Pos.left, top: scene2DialogOnVideo5Pos.top }"
|
||
:class="{ visible: dialogVisible }">
|
||
<image class="dialog-bg dialog-bg-oval1" src="/static/animation/dialog-monster/dialog2.png"
|
||
mode="aspectFit" />
|
||
<view class="dialog-text-wrapper-vertical">
|
||
<text class="dialog-text-vertical">{{ scene2Video5Text }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 场景3: 图2,图6 (上下布局) -->
|
||
<view v-else-if="currentScene === 2" class="scene3-layout">
|
||
<view class="scene3-top">
|
||
<video class="scene3-video" src="/static/animation/animation2.mp4" loop autoplay muted
|
||
object-fit="fill" :show-center-play-btn="false" :show-play-btn="false"
|
||
:enable-progress-gesture="false" :controls="false"></video>
|
||
<!-- 上部分对话框 -->
|
||
<view class="scene1-dialog" :style="{ left: scene3DialogTopPos.left, top: scene3DialogTopPos.top }"
|
||
:class="{ visible: dialogVisible }">
|
||
<image class="dialog-bg dialog-bg-oval-1" src="/static/animation/dialog-monster/dialog2.png"
|
||
mode="aspectFit" />
|
||
<view class="dialog-text-wrapper-vertical dialog-text-wrapper-vertical-on-video4">
|
||
<text class="dialog-text-vertical">{{ currentText }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="scene3-bottom" v-if="scene3SubPhase >= 1">
|
||
<video class="scene3-video" src="/static/animation/animation6.mp4" loop autoplay muted
|
||
object-fit="fill" :show-center-play-btn="false" :show-play-btn="false"
|
||
:enable-progress-gesture="false" :controls="false"></video>
|
||
<!-- 下部分对话框 -->
|
||
<view class="scene1-dialog"
|
||
:style="{ left: scene3DialogBottomPos.left, top: scene3DialogBottomPos.top }"
|
||
:class="{ visible: dialogVisible }">
|
||
<image class="dialog-bg dialog-bg-oval-2"
|
||
src="/static/animation/dialog-monster/rounded-corner-dialog1.png" mode="aspectFit" />
|
||
<view class="dialog-text-wrapper-vertical dialog-text-wrapper-vertical-on-video5">
|
||
<text class="dialog-text-vertical">{{ scene3Video6Text }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 场景4: 视频轮播 图7,图8 (两个独立区域) -->
|
||
<view v-else-if="currentScene === 3" class="scene4-layout">
|
||
<!-- 图7: 有对话框 -->
|
||
<view class="scene4-item scene4-item-1">
|
||
<video class="scene4-video" src="/static/animation/animation7.mp4" loop autoplay muted
|
||
:show-center-play-btn="false" :show-play-btn="false" :enable-progress-gesture="false"
|
||
:controls="false"></video>
|
||
<view class="scene1-dialog" :style="{ left: scene4Dialog7Pos.left, top: scene4Dialog7Pos.top }"
|
||
:class="{ visible: dialogVisible }">
|
||
<image class="dialog-bg dialog-bg-oval-3"
|
||
src="/static/animation/dialog-monster/rounded-corner-dialog1.png" mode="aspectFit" />
|
||
<view class="dialog-text-wrapper-vertical dialog-text-wrapper-vertical-on-video6">
|
||
<text class="dialog-text-vertical dialog-text-vertical-on-video5">{{ scene4Video7Text
|
||
}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 图8: 有对话框 -->
|
||
<view class="scene4-item scene4-item-2" v-if="scene4SubPhase >= 1">
|
||
<video class="scene4-video" src="/static/animation/animation8.mp4" loop autoplay muted
|
||
object-fit="fill" :show-center-play-btn="false" :show-play-btn="false"
|
||
:enable-progress-gesture="false" :controls="false"></video>
|
||
<view class="scene1-dialog" :style="{ left: scene4Dialog8Pos.left, top: scene4Dialog8Pos.top }"
|
||
:class="{ visible: dialogVisible }">
|
||
<image class="dialog-bg dialog-bg-oval-4" src="/static/animation/dialog-monster/dialog3.png"
|
||
mode="aspectFit" />
|
||
<view class="dialog-text-wrapper-vertical dialog-text-wrapper-vertical-on-video7">
|
||
<text class="dialog-text-vertical">{{ scene4Video8Text }}</text>
|
||
</view>
|
||
</view>
|
||
<!-- 小怪兽图片 -->
|
||
<image class="scene4-monster" :style="{ left: scene4MonsterPos.left, top: scene4MonsterPos.top }"
|
||
src="/static/animation/dialog-monster/monster.png" mode="aspectFit" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 场景5: 选择明星页面 -->
|
||
<view v-else-if="currentScene === 4" class="scene-role">
|
||
<SelectRole :is-welcome="true" @confirm="onSelectRoleConfirm" />
|
||
</view>
|
||
|
||
<!-- 场景6: 视频图9.mp4 -->
|
||
<view v-else-if="currentScene === 5" class="scene6-wrapper">
|
||
<view class="scene6-bg">
|
||
<video class="bg-media" src="/static/animation/animation9.mp4" loop autoplay muted object-fit="fill"
|
||
:show-center-play-btn="false" :show-play-btn="false" :enable-progress-gesture="false"
|
||
:controls="false"></video>
|
||
<view class="scene1-dialog" :style="{ left: scene6DialogPos.left, top: scene6DialogPos.top }"
|
||
:class="{ visible: dialogVisible }">
|
||
<image class="dialog-bg dialog-bg-oval-5" src="/static/animation/dialog-monster/dialog3.png"
|
||
mode="aspectFit" />
|
||
<view class="dialog-text-wrapper-vertical dialog-text-wrapper-vertical-on-video8">
|
||
<text class="dialog-text-vertical dialog-text-vertical-on-video5">{{ scene6Video9Text }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- Topfans文字 + 箭头 (仅场景1-4) -->
|
||
<view v-if="currentScene <= 3" class="topfans-arrow-wrapper" :class="{ visible: contentVisible }"
|
||
@click.stop="nextScene">
|
||
<text class="topfans-text">TOPFANS</text>
|
||
<text class="arrow-icon"></text>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onMounted, onUnmounted } from "vue";
|
||
import { useStore } from "vuex";
|
||
import SelectRole from "../profile/selectRole.vue";
|
||
|
||
const store = useStore();
|
||
|
||
const emit = defineEmits(["complete", "skip"]);
|
||
|
||
// 固定资源
|
||
const monsterSrc = "/static/animation/dialog-monster/monster.png";
|
||
|
||
// 每场景的文案
|
||
const sceneTexts = [
|
||
"这些限量款徽章都没舍得用过……", // 场景1
|
||
"还可以铸造专属藏品哦~", // 场景3
|
||
"这些都是我的宝贝,难道都会悄悄褪色吗?!", // 场景4
|
||
"选择你喜欢的明星吧!", // 场景5
|
||
];
|
||
|
||
// 图4和图5对话框的独立文字
|
||
const scene2Video4Text = ref("啊啊啊,这张小卡怎么褪色了555");
|
||
const scene2Video5Text = ref("当时可是排好久才买到的。");
|
||
|
||
// 场景3图6的对话框文字
|
||
const scene3Video6Text = ref("当然不会!角角我能让这些铸造成永久的藏品。");
|
||
|
||
// 场景4图7的对话框文字
|
||
const scene4Video7Text = ref("是真的吗,我要怎么做?");
|
||
// 场景4图8的对话框文字
|
||
const scene4Video8Text = ref("只需要告诉我Ta的名字,我就能带你去Ta的TopFans。");
|
||
|
||
// 场景6图9的对话框文字
|
||
const scene6Video9Text = ref("好,传送门打开了,我们出发吧");
|
||
|
||
// 对话框位置配置 (每个场景可配置)
|
||
const dialogPosConfig = ref({
|
||
scene0: { leftRatio: 0.35, topRatio: 0.2 },
|
||
// 场景3: 图2对话框 (上部分)
|
||
scene3_top: { leftRatio: 0.35, topRatio: 0.135 },
|
||
// 场景3: 图6对话框 (下部分)
|
||
scene3_bottom: { leftRatio: -0.08, topRatio: 0.06 },
|
||
// 场景4: 图7对话框 (上部分)
|
||
scene4_top: { leftRatio: 0.4, topRatio: -0.06 },
|
||
// 场景4: 图8对话框 (下部分)
|
||
scene4_bottom: { leftRatio: 0.035, topRatio: 0.2 },
|
||
// 场景4: 小怪兽
|
||
scene4Monster: { leftRatio: 0, topRatio: 0.15 },
|
||
// 图4对话框覆盖在图3上面
|
||
scene1DialogOnVideo3: { leftRatio: 0.11, topRatio: 0.30 },
|
||
// 图5对话框
|
||
scene2DialogOnVideo5: { leftRatio: 0.4, topRatio: 0.7 },
|
||
// 场景6: 图9对话框
|
||
scene6: { leftRatio: 0.15, topRatio: 0.15 },
|
||
});
|
||
|
||
// 当前对话框位置
|
||
const currentDialogPos = ref({
|
||
left: "0",
|
||
top: "0"
|
||
});
|
||
|
||
// 图4对话框位置
|
||
const scene1DialogOnVideo3Pos = ref({
|
||
left: "0",
|
||
top: "0"
|
||
});
|
||
|
||
// 图5对话框位置
|
||
const scene2DialogOnVideo5Pos = ref({
|
||
left: "0",
|
||
top: "0"
|
||
});
|
||
|
||
// 场景3(图2/图6)对话框位置
|
||
const scene3DialogTopPos = ref({
|
||
left: "0",
|
||
top: "0"
|
||
});
|
||
|
||
const scene3DialogBottomPos = ref({
|
||
left: "0",
|
||
top: "0"
|
||
});
|
||
|
||
// 场景4对话框位置
|
||
const scene4Dialog7Pos = ref({
|
||
left: "0",
|
||
top: "0"
|
||
});
|
||
|
||
const scene4Dialog8Pos = ref({
|
||
left: "0",
|
||
top: "0"
|
||
});
|
||
|
||
// 场景4小怪兽位置
|
||
const scene4MonsterPos = ref({
|
||
left: "0",
|
||
top: "0"
|
||
});
|
||
|
||
// 场景6对话框位置
|
||
const scene6DialogPos = ref({
|
||
left: "0",
|
||
top: "0"
|
||
});
|
||
|
||
// 通用:动态计算对话框位置
|
||
const calculateDialogPos = (sceneIndex) => {
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
const screenWidth = systemInfo.windowWidth;
|
||
const screenHeight = systemInfo.windowHeight;
|
||
|
||
// 计算屏幕宽高比
|
||
const ratio = screenWidth / screenHeight;
|
||
|
||
// 获取当前场景的配置
|
||
const configKey = `scene${sceneIndex}`;
|
||
const config = dialogPosConfig.value[configKey] || dialogPosConfig.value.scene0;
|
||
|
||
// 根据屏幕比例动态调整
|
||
const leftBase = config.leftRatio;
|
||
const leftAdjust = ratio > 0.5 ? (ratio - 0.5) * 0.3 : 0;
|
||
|
||
currentDialogPos.value = {
|
||
left: Math.round(screenWidth * (leftBase + leftAdjust)) + "px",
|
||
top: Math.round(screenHeight * config.topRatio) + "px"
|
||
};
|
||
};
|
||
|
||
// 计算图4对话框位置(覆盖在图3上面)
|
||
const calculateScene1DialogOnVideo3Pos = () => {
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
const screenWidth = systemInfo.windowWidth;
|
||
const screenHeight = systemInfo.windowHeight;
|
||
|
||
const config = dialogPosConfig.value.scene1DialogOnVideo3;
|
||
const ratio = screenWidth / screenHeight;
|
||
const leftAdjust = ratio > 0.5 ? (ratio - 0.5) * 0.3 : 0;
|
||
|
||
scene1DialogOnVideo3Pos.value = {
|
||
left: Math.round(screenWidth * (config.leftRatio + leftAdjust)) + "px",
|
||
top: Math.round(screenHeight * config.topRatio) + "px"
|
||
};
|
||
};
|
||
|
||
// 计算图5对话框位置
|
||
const calculateScene2DialogOnVideo5Pos = () => {
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
const screenWidth = systemInfo.windowWidth;
|
||
const screenHeight = systemInfo.windowHeight;
|
||
|
||
const config = dialogPosConfig.value.scene2DialogOnVideo5;
|
||
const ratio = screenWidth / screenHeight;
|
||
const leftAdjust = ratio > 0.5 ? (ratio - 0.5) * 0.3 : 0;
|
||
|
||
scene2DialogOnVideo5Pos.value = {
|
||
left: Math.round(screenWidth * (config.leftRatio + leftAdjust)) + "px",
|
||
top: Math.round(screenHeight * config.topRatio) + "px"
|
||
};
|
||
};
|
||
|
||
// 计算场景3(图2/图6)对话框位置
|
||
const calculateScene3DialogPos = () => {
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
const screenWidth = systemInfo.windowWidth;
|
||
const screenHeight = systemInfo.windowHeight;
|
||
|
||
// 上部分对话框
|
||
const configTop = dialogPosConfig.value.scene3_top;
|
||
const ratio = screenWidth / screenHeight;
|
||
const leftAdjust = ratio > 0.5 ? (ratio - 0.5) * 0.3 : 0;
|
||
|
||
scene3DialogTopPos.value = {
|
||
left: Math.round(screenWidth * (configTop.leftRatio + leftAdjust)) + "px",
|
||
top: Math.round(screenHeight * configTop.topRatio) + "px"
|
||
};
|
||
|
||
// 下部分对话框
|
||
const configBottom = dialogPosConfig.value.scene3_bottom;
|
||
scene3DialogBottomPos.value = {
|
||
left: Math.round(screenWidth * (configBottom.leftRatio + leftAdjust)) + "px",
|
||
top: Math.round(screenHeight * configBottom.topRatio) + "px"
|
||
};
|
||
};
|
||
|
||
// 计算场景4(图7/图8)对话框位置
|
||
const calculateScene4DialogPos = () => {
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
const screenWidth = systemInfo.windowWidth;
|
||
const screenHeight = systemInfo.windowHeight;
|
||
|
||
const ratio = screenWidth / screenHeight;
|
||
const leftAdjust = ratio > 0.5 ? (ratio - 0.5) * 0.3 : 0;
|
||
|
||
// 上部分对话框
|
||
const configTop = dialogPosConfig.value.scene4_top;
|
||
scene4Dialog7Pos.value = {
|
||
left: Math.round(screenWidth * (configTop.leftRatio + leftAdjust)) + "px",
|
||
top: Math.round(screenHeight * configTop.topRatio) + "px"
|
||
};
|
||
|
||
// 下部分对话框
|
||
const configBottom = dialogPosConfig.value.scene4_bottom;
|
||
scene4Dialog8Pos.value = {
|
||
left: Math.round(screenWidth * (configBottom.leftRatio + leftAdjust)) + "px",
|
||
top: Math.round(screenHeight * configBottom.topRatio) + "px"
|
||
};
|
||
|
||
// 小怪兽位置 - 在图8对话框右边
|
||
const configMonster = dialogPosConfig.value.scene4Monster;
|
||
scene4MonsterPos.value = {
|
||
left: 0 + "px",
|
||
top: Math.round(screenHeight * configMonster.topRatio) + "px"
|
||
};
|
||
};
|
||
|
||
// 计算场景6(图9)对话框位置
|
||
const calculateScene6DialogPos = () => {
|
||
const systemInfo = uni.getSystemInfoSync();
|
||
const screenWidth = systemInfo.windowWidth;
|
||
const screenHeight = systemInfo.windowHeight;
|
||
|
||
const config = dialogPosConfig.value.scene6;
|
||
scene6DialogPos.value = {
|
||
left: Math.round(screenWidth * config.leftRatio) + "px",
|
||
top: Math.round(screenHeight * config.topRatio) + "px"
|
||
};
|
||
};
|
||
|
||
// 响应式状态
|
||
const currentScene = ref(0);
|
||
const contentVisible = ref(false);
|
||
const dialogVisible = ref(false);
|
||
const monsterVisible = ref(false);
|
||
|
||
// 场景2的子阶段:0=只显示图3, 1=显示图3+图4, 2=显示图3+图4+图5
|
||
const scene2SubPhase = ref(0);
|
||
|
||
// 场景3的子阶段:0=只显示图2, 1=显示图2+图6
|
||
const scene3SubPhase = ref(0);
|
||
|
||
// 场景4的子阶段:0=只显示图7, 1=显示图7+图8
|
||
const scene4SubPhase = ref(0);
|
||
|
||
const currentText = computed(() => sceneTexts[currentScene.value]);
|
||
|
||
// 选择明星确认后调用注册接口
|
||
const onSelectRoleConfirm = async (star) => {
|
||
console.log("[WelcomeAnimation] onSelectRoleConfirm called, star:", star);
|
||
|
||
try {
|
||
// 获取临时存储的注册信息
|
||
const mobile = uni.getStorageSync("temp_register_mobile");
|
||
const password = uni.getStorageSync("temp_register_password");
|
||
const nickname = uni.getStorageSync("temp_register_nickname");
|
||
const star_id = star.star_id;
|
||
|
||
console.log("[WelcomeAnimation] register info:", {
|
||
mobile,
|
||
password,
|
||
nickname,
|
||
star_id,
|
||
});
|
||
|
||
if (!mobile || !password || !nickname || !star_id) {
|
||
console.log("[WelcomeAnimation] 注册信息不完整");
|
||
uni.showToast({
|
||
title: "注册信息不完整",
|
||
icon: "none",
|
||
});
|
||
// 清除已选择的注册信息,重新注册
|
||
uni.removeStorageSync("temp_register_mobile");
|
||
uni.removeStorageSync("temp_register_password");
|
||
uni.removeStorageSync("temp_register_nickname");
|
||
// 返回注册页面重新注册
|
||
uni.navigateTo({
|
||
url: '/pages/register/register'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 显示加载提示
|
||
uni.showLoading({
|
||
title: "注册中...",
|
||
mask: true,
|
||
});
|
||
|
||
// 调用注册 API
|
||
console.log("[WelcomeAnimation] 开始调用注册API");
|
||
await store.dispatch("user/register", {
|
||
mobile,
|
||
password,
|
||
star_id,
|
||
nickname,
|
||
});
|
||
console.log("[WelcomeAnimation] 注册API调用成功");
|
||
|
||
uni.hideLoading();
|
||
|
||
// 清除临时数据
|
||
uni.removeStorageSync("temp_register_mobile");
|
||
uni.removeStorageSync("temp_register_password");
|
||
uni.removeStorageSync("temp_register_nickname");
|
||
|
||
// 跳转到场景6
|
||
console.log("[WelcomeAnimation] 跳转到场景6");
|
||
currentScene.value = 5;
|
||
// 2秒后自动结束
|
||
setTimeout(() => {
|
||
handleFinish();
|
||
}, 2000);
|
||
} catch (error) {
|
||
console.log("[WelcomeAnimation] 注册失败:", error);
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: error.message || "注册失败,请重试",
|
||
icon: "none",
|
||
});
|
||
// 清除已选择的注册信息,重新注册
|
||
uni.removeStorageSync("temp_register_mobile");
|
||
uni.removeStorageSync("temp_register_password");
|
||
uni.removeStorageSync("temp_register_nickname");
|
||
// 返回注册页面重新注册
|
||
uni.navigateTo({
|
||
url: '/pages/register/register'
|
||
});
|
||
}
|
||
};
|
||
|
||
// 点击背景显示文字和箭头,处理场景2的子阶段切换
|
||
const onBgClick = (e) => {
|
||
// 阻止事件冒泡,避免触发背景点击
|
||
e && e.stopPropagation && e.stopPropagation();
|
||
|
||
// 场景2:处理子阶段切换
|
||
if (currentScene.value === 1) {
|
||
if (scene2SubPhase.value === 0) {
|
||
// 图3显示时,点击立即进入下一阶段显示图4
|
||
scene2SubPhase.value = 1;
|
||
} else if (scene2SubPhase.value === 1) {
|
||
// 图4显示时,点击立即进入下一阶段显示图5
|
||
scene2SubPhase.value = 2;
|
||
} else if (scene2SubPhase.value === 2) {
|
||
// 图5显示时,点击显示Topfans文字+箭头
|
||
if (!contentVisible.value) {
|
||
contentVisible.value = true;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 场景3:处理子阶段切换
|
||
if (currentScene.value === 2) {
|
||
if (scene3SubPhase.value === 0) {
|
||
// 图2显示时,点击立即进入下一阶段显示图6
|
||
scene3SubPhase.value = 1;
|
||
} else if (scene3SubPhase.value === 1) {
|
||
// 图6显示时,点击显示Topfans文字+箭头
|
||
if (!contentVisible.value) {
|
||
contentVisible.value = true;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 场景4:处理子阶段切换
|
||
if (currentScene.value === 3) {
|
||
if (scene4SubPhase.value === 0) {
|
||
// 图7显示时,点击立即进入下一阶段显示图8
|
||
scene4SubPhase.value = 1;
|
||
} else if (scene4SubPhase.value === 1) {
|
||
// 图8显示时,点击显示Topfans文字+箭头
|
||
if (!contentVisible.value) {
|
||
contentVisible.value = true;
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 其他场景:点击显示文字和箭头
|
||
if (currentScene.value <= 3 && !contentVisible.value) {
|
||
contentVisible.value = true;
|
||
}
|
||
};
|
||
|
||
let carouselTimer = null;
|
||
let autoShowTimer = null;
|
||
|
||
// 切换到下一个场景
|
||
const nextScene = () => {
|
||
if (currentScene.value === 0) {
|
||
// 场景1: 切换到场景2 (图3、图4、图5 上中下)
|
||
currentScene.value = 1;
|
||
resetSceneAnimation();
|
||
} else if (currentScene.value === 1) {
|
||
// 场景2: 切换到场景3 (图2、图6 上下)
|
||
currentScene.value = 2;
|
||
resetSceneAnimation();
|
||
} else if (currentScene.value === 2) {
|
||
// 场景3: 切换到场景4 (图7、图8 上下)
|
||
currentScene.value = 3;
|
||
resetSceneAnimation();
|
||
} else if (currentScene.value === 3) {
|
||
// 场景4: 切换到场景5(选择明星)
|
||
currentScene.value = 4;
|
||
resetSceneAnimation();
|
||
} else if (currentScene.value === 4) {
|
||
// 场景5: 选择明星页面,由组件触发确认事件
|
||
// 不做任何操作,等待用户选择明星后触发 onSelectRoleConfirm
|
||
} else {
|
||
handleFinish();
|
||
}
|
||
};
|
||
|
||
// 跳过
|
||
const handleSkip = () => {
|
||
cleanup();
|
||
emit("skip");
|
||
};
|
||
|
||
// 完成
|
||
const handleFinish = () => {
|
||
cleanup();
|
||
uni.setStorageSync("has_seen_welcome", true);
|
||
emit("complete");
|
||
};
|
||
|
||
// 重置场景动画
|
||
const resetSceneAnimation = () => {
|
||
// 清除之前的自动显示定时器
|
||
if (autoShowTimer) {
|
||
clearTimeout(autoShowTimer);
|
||
autoShowTimer = null;
|
||
}
|
||
|
||
contentVisible.value = false;
|
||
dialogVisible.value = false;
|
||
monsterVisible.value = false;
|
||
|
||
// 场景2子阶段重置
|
||
scene2SubPhase.value = 0;
|
||
|
||
// 切换场景时只自动显示对话框和小怪兽,文字和箭头需要点击显示
|
||
setTimeout(() => {
|
||
dialogVisible.value = true;
|
||
}, 300);
|
||
|
||
setTimeout(() => {
|
||
monsterVisible.value = true;
|
||
}, 800);
|
||
|
||
// 切换场景时重新计算对话框位置
|
||
calculateDialogPos(currentScene.value);
|
||
|
||
// 场景1: 5秒后自动显示文字和箭头
|
||
if (currentScene.value === 0) {
|
||
autoShowTimer = setTimeout(() => {
|
||
contentVisible.value = true;
|
||
}, 4800);
|
||
}
|
||
|
||
// 场景2: 自动逐步显示(只在用户没有手动点击时触发)
|
||
if (currentScene.value === 1) {
|
||
// 图3显示后4秒,自动进入下一阶段显示图4
|
||
autoShowTimer = setTimeout(() => {
|
||
if (scene2SubPhase.value === 0) {
|
||
scene2SubPhase.value = 1;
|
||
}
|
||
// 图4显示后4秒,自动进入下一阶段显示图5
|
||
autoShowTimer = setTimeout(() => {
|
||
if (scene2SubPhase.value === 1) {
|
||
scene2SubPhase.value = 2;
|
||
}
|
||
// 图5显示后10秒,自动显示Topfans文字+箭头
|
||
autoShowTimer = setTimeout(() => {
|
||
if (!contentVisible.value) {
|
||
contentVisible.value = true;
|
||
}
|
||
}, 9800);
|
||
}, 3800);
|
||
}, 3800);
|
||
}
|
||
|
||
// 场景3: 自动逐步显示
|
||
if (currentScene.value === 2) {
|
||
// 图2显示后4秒,自动进入下一阶段显示图6
|
||
autoShowTimer = setTimeout(() => {
|
||
if (scene3SubPhase.value === 0) {
|
||
scene3SubPhase.value = 1;
|
||
}
|
||
// 图6显示后10秒,自动显示Topfans文字+箭头
|
||
autoShowTimer = setTimeout(() => {
|
||
if (!contentVisible.value) {
|
||
contentVisible.value = true;
|
||
}
|
||
}, 2800);
|
||
}, 8800);
|
||
}
|
||
|
||
// 场景4: 自动逐步显示
|
||
if (currentScene.value === 3) {
|
||
// 图7显示后4秒,自动进入下一阶段显示图8
|
||
autoShowTimer = setTimeout(() => {
|
||
if (scene4SubPhase.value === 0) {
|
||
scene4SubPhase.value = 1;
|
||
}
|
||
// 图8显示后10秒,自动显示Topfans文字+箭头
|
||
autoShowTimer = setTimeout(() => {
|
||
if (!contentVisible.value) {
|
||
contentVisible.value = true;
|
||
}
|
||
}, 7800);
|
||
}, 3800);
|
||
}
|
||
};
|
||
|
||
// 清理定时器
|
||
const cleanup = () => {
|
||
if (carouselTimer) {
|
||
clearInterval(carouselTimer);
|
||
carouselTimer = null;
|
||
}
|
||
if (autoShowTimer) {
|
||
clearTimeout(autoShowTimer);
|
||
autoShowTimer = null;
|
||
}
|
||
};
|
||
|
||
// 启动视频轮播(仅场景1、5、6需要自动切换)
|
||
const startCarousel = () => {
|
||
// 场景2-4不需要轮播,每个场景只显示一次
|
||
carouselTimer = setInterval(() => {
|
||
// 这里可以留作未来扩展,目前场景2-4不需要自动切换
|
||
}, 3000);
|
||
};
|
||
|
||
onMounted(() => {
|
||
// 动态计算当前场景对话框位置
|
||
calculateDialogPos(currentScene.value);
|
||
|
||
// 计算图4对话框位置
|
||
calculateScene1DialogOnVideo3Pos();
|
||
calculateScene2DialogOnVideo5Pos();
|
||
calculateScene3DialogPos();
|
||
calculateScene4DialogPos();
|
||
calculateScene6DialogPos();
|
||
|
||
// 初始动画 - 对话框和小怪兽自动显示,文字和箭头需要点击显示
|
||
setTimeout(() => {
|
||
dialogVisible.value = true;
|
||
}, 500);
|
||
|
||
setTimeout(() => {
|
||
monsterVisible.value = true;
|
||
}, 1500);
|
||
|
||
// 场景1: 5秒后自动显示 Topfans文字+箭头
|
||
if (currentScene.value === 0) {
|
||
autoShowTimer = setTimeout(() => {
|
||
contentVisible.value = true;
|
||
}, 5000);
|
||
}
|
||
|
||
// 启动轮播
|
||
startCarousel();
|
||
});
|
||
|
||
onUnmounted(() => {
|
||
cleanup();
|
||
});
|
||
</script>
|
||
|
||
<style scoped>
|
||
@font-face {
|
||
/* 这里给字体起个名字,随便取,只要好记就行,比如 'MyAnimFont' */
|
||
font-family: "MyAnimFont";
|
||
|
||
/* 这里才是放 url 的地方 */
|
||
src: url("/static/fonts/animation.ttf") format("truetype");
|
||
|
||
/* 可选:定义字重和样式,防止浏览器乱猜 */
|
||
font-weight: normal;
|
||
font-style: normal;
|
||
}
|
||
|
||
.welcome-mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 9999;
|
||
background: white;
|
||
}
|
||
|
||
.header-text {
|
||
width: 176rpx;
|
||
font-size: 64rpx;
|
||
background: linear-gradient(45deg, #b52920 20%, #56c1ff, #86d9e0);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
position: absolute;
|
||
right: 48rpx;
|
||
top: 16rpx;
|
||
z-index: 5;
|
||
font-family: "MyAnimFont", sans-serif;
|
||
}
|
||
|
||
.header-text::first-letter {
|
||
font-size: 96rpx;
|
||
margin-left: 8px;
|
||
line-height: 1;
|
||
}
|
||
|
||
.background-layer {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
}
|
||
|
||
.bg-media {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
.scene-role {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
}
|
||
|
||
/* 场景1独立区域 */
|
||
.scene1-wrapper {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
}
|
||
|
||
/* 场景1对话框样式 */
|
||
.scene1-dialog {
|
||
position: absolute;
|
||
width: 420rpx;
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
transition: all 0.5s ease;
|
||
pointer-events: none;
|
||
z-index: 10;
|
||
}
|
||
|
||
.dialog-bg.dialog-bg-oval-1 {
|
||
transform: scale(1.95);
|
||
}
|
||
|
||
.dialog-bg.dialog-bg-oval-2 {
|
||
transform: scale(5);
|
||
}
|
||
|
||
.dialog-bg.dialog-bg-oval-3 {
|
||
transform: scale(4);
|
||
}
|
||
|
||
.dialog-bg.dialog-bg-oval-4 {
|
||
transform: scale(1.6);
|
||
}
|
||
|
||
.dialog-bg.dialog-bg-oval-5 {
|
||
transform: scale(1.6);
|
||
}
|
||
|
||
.scene1-dialog.visible {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
|
||
/* 场景2三个独立区域 */
|
||
.scene2-layout {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
}
|
||
|
||
/* 场景2三个独立区域 - 使用固定高度 */
|
||
.scene2-item {
|
||
position: absolute;
|
||
left: 16rpx;
|
||
right: 16rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 图3: 上部分 */
|
||
.scene2-item-1 {
|
||
top: 128rpx;
|
||
height: 25%;
|
||
}
|
||
|
||
/* 图4: 中部分 */
|
||
.scene2-item-2 {
|
||
top: calc(128rpx + 25% + 16rpx);
|
||
height: 30%;
|
||
opacity: 0;
|
||
transition: opacity 0.5s ease;
|
||
}
|
||
|
||
.scene2-item-2.visible {
|
||
opacity: 1;
|
||
}
|
||
|
||
/* 图5: 下部分 */
|
||
.scene2-item-3 {
|
||
bottom: 32rpx;
|
||
height: 30%;
|
||
opacity: 0;
|
||
transition: opacity 0.5s ease;
|
||
}
|
||
|
||
.scene2-item-3.visible {
|
||
opacity: 1;
|
||
}
|
||
|
||
.scene2-video {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
/* 图4视频:靠右,宽度4/5 */
|
||
.scene2-video-right {
|
||
left: auto;
|
||
right: 0;
|
||
width: 80%;
|
||
height: 90%;
|
||
}
|
||
|
||
/* 场景2对话框样式 */
|
||
.scene2-dialog,
|
||
.scene2-dialog-bottom {
|
||
position: absolute;
|
||
right: 0;
|
||
width: 80%;
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
transition: all 0.5s ease;
|
||
pointer-events: auto;
|
||
}
|
||
|
||
.scene2-dialog.visible,
|
||
.scene2-dialog-bottom.visible {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
|
||
/* 图4对话框覆盖在图3上面 */
|
||
.scene2-dialog-on-video3 {
|
||
position: absolute;
|
||
width: 420rpx;
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
transition: all 0.5s ease;
|
||
pointer-events: none;
|
||
z-index: 10;
|
||
}
|
||
|
||
/* 图5对话框覆盖在图4上面 */
|
||
.scene2-dialog-on-video4 {
|
||
position: absolute;
|
||
width: 420rpx;
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
transition: all 0.5s ease;
|
||
pointer-events: none;
|
||
z-index: 10;
|
||
}
|
||
|
||
.scene2-dialog-on-video3.visible,
|
||
.scene2-dialog-on-video4.visible {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.scene2-dialog {
|
||
top: 20%;
|
||
}
|
||
|
||
.scene2-dialog-bottom {
|
||
bottom: 20%;
|
||
}
|
||
|
||
.dialog-bg.dialog-bg-oval {
|
||
transform: scale(4.5);
|
||
}
|
||
|
||
.dialog-bg.dialog-bg-oval1 {
|
||
transform: scale(1.5);
|
||
top: 32rpx;
|
||
}
|
||
|
||
/* 场景4两个独立区域 */
|
||
.scene4-layout {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
}
|
||
|
||
.scene4-item {
|
||
position: relative;
|
||
|
||
}
|
||
|
||
.scene4-item-1 {
|
||
margin: 256rpx 16rpx 32rpx 16rpx;
|
||
height: 25%;
|
||
}
|
||
|
||
.scene4-item-2 {
|
||
height: 30%;
|
||
width: 75%;
|
||
margin: 0 0 0 auto;
|
||
}
|
||
|
||
.scene4-monster {
|
||
position: absolute;
|
||
width: 144rpx;
|
||
height: 144rpx;
|
||
z-index: 1;
|
||
transform: scale(4);
|
||
}
|
||
|
||
.scene4-video {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
/* 场景4对话框样式 */
|
||
.scene4-dialog,
|
||
.scene4-dialog-bottom {
|
||
position: absolute;
|
||
left: 40rpx;
|
||
width: 420rpx;
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
transition: all 0.5s ease;
|
||
pointer-events: auto;
|
||
}
|
||
|
||
.scene4-dialog.visible,
|
||
.scene4-dialog-bottom.visible {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.scene4-dialog {
|
||
top: 20%;
|
||
}
|
||
|
||
.scene4-dialog-bottom {
|
||
bottom: 20%;
|
||
}
|
||
|
||
/* 场景3上下布局 (上2/3, 下1/3) */
|
||
.scene3-layout {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.scene3-top {
|
||
height: 60%;
|
||
position: relative;
|
||
margin: 96rpx 16rpx 32rpx 16rpx;
|
||
border-radius: 0.8rpx;
|
||
}
|
||
|
||
.scene3-bottom {
|
||
height: 20%;
|
||
width: 640rpx;
|
||
position: relative;
|
||
margin: 0 16rpx 0 auto;
|
||
}
|
||
|
||
.scene3-video {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
object-fit: cover;
|
||
}
|
||
|
||
/* 场景3对话框样式 */
|
||
.scene3-top,
|
||
.scene3-bottom {
|
||
position: relative;
|
||
}
|
||
|
||
.skip-btn {
|
||
position: absolute;
|
||
top: 80rpx;
|
||
right: 40rpx;
|
||
z-index: 10;
|
||
padding: 16rpx 32rpx;
|
||
background: rgba(0, 0, 0, 0.5);
|
||
border-radius: 30rpx;
|
||
border: 2rpx solid rgba(255, 255, 255, 0.5);
|
||
}
|
||
|
||
.skip-text {
|
||
font-size: 28rpx;
|
||
color: #fff;
|
||
}
|
||
|
||
/* Topfans文字 + 箭头整体 */
|
||
.topfans-arrow-wrapper {
|
||
position: absolute;
|
||
left: 40rpx;
|
||
right: 40rpx;
|
||
bottom: 0;
|
||
transform: translateY(-50%) translateX(-50rpx);
|
||
opacity: 0;
|
||
transition: all 0.5s ease;
|
||
z-index: 5;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.topfans-arrow-wrapper.visible {
|
||
pointer-events: auto;
|
||
}
|
||
|
||
.topfans-arrow-wrapper.visible {
|
||
opacity: 1;
|
||
transform: translateY(-50%) translateX(0);
|
||
}
|
||
|
||
.topfans-text {
|
||
width: 640rpx;
|
||
font-size: 96rpx;
|
||
background: linear-gradient(45deg, #b52920 10%, #56c1ff, #86d9e0);
|
||
-webkit-background-clip: text;
|
||
-webkit-text-fill-color: transparent;
|
||
background-clip: text;
|
||
font-family: "MyAnimFont", sans-serif;
|
||
}
|
||
|
||
.topfans-text::first-letter {
|
||
font-size: 112;
|
||
/* 设置为首行文字大小的3倍 */
|
||
margin-left: 8px;
|
||
/* 可选:与后续文字保持间距 */
|
||
line-height: 1;
|
||
/* 可选:调整行高以防错位 */
|
||
}
|
||
|
||
.arrow-icon {
|
||
display: inline-block;
|
||
width: 0;
|
||
height: 0;
|
||
|
||
/* 1. 画三角形形状 */
|
||
border-top: 15px solid transparent;
|
||
border-bottom: 15px solid transparent;
|
||
border-left: 25px solid #ffcccc;
|
||
/* 这里的颜色会被渐变覆盖,随便写个浅色即可 */
|
||
|
||
/* 2. 设置渐变色 (从左到右:粉色 -> 黄色) */
|
||
/* 注意:为了让渐变填满三角形,我们需要一个伪元素或者特殊技巧,
|
||
但更简单的方法是直接用 background-image 配合 clip-path (现代浏览器)
|
||
或者保持上面的 border 写法,用 filter 上色(兼容性最好但渐变难做)。
|
||
|
||
【修正方案】:为了完美渐变 + 阴影,我们用 clip-path 画法更精准:
|
||
*/
|
||
width: 128rpx;
|
||
/* 箭头总宽 */
|
||
height: 64rpx;
|
||
/* 箭头总高 */
|
||
border: none;
|
||
/* 清除边框画法 */
|
||
|
||
/* 使用背景渐变 */
|
||
background: linear-gradient(35deg, rgba(255, 107, 157, 0.9) 35%, rgba(255, 177, 153, 0.9) 70%);
|
||
|
||
/* 使用 clip-path 切割出“尾巴+三角”的形状 */
|
||
/* 这是一个类似图片中形状的坐标点:左边有个小尾巴,右边是大三角 */
|
||
clip-path: polygon(0% 40%,
|
||
/* 左上尾巴起点 */
|
||
40% 40%,
|
||
/* 尾巴连接处上 */
|
||
40% 0%,
|
||
/* 三角形顶点上 */
|
||
100% 50%,
|
||
/* 最右侧尖端 */
|
||
40% 100%,
|
||
/* 三角形顶点下 */
|
||
40% 60%,
|
||
/* 尾巴连接处下 */
|
||
0% 60%
|
||
/* 左下尾巴终点 */
|
||
);
|
||
|
||
/* 3. 添加立体阴影 (关键步骤) */
|
||
/* drop-shadow 比 box-shadow 更适合不规则形状 */
|
||
filter: drop-shadow(2px 3px 2px rgba(0, 0, 0, 0.3));
|
||
|
||
vertical-align: middle;
|
||
margin: 0 10px;
|
||
}
|
||
|
||
/* 内容层 */
|
||
.content-layer {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
pointer-events: none;
|
||
}
|
||
|
||
.dialog-wrapper {
|
||
position: absolute;
|
||
left: 35%;
|
||
top: 20%;
|
||
width: 420rpx;
|
||
opacity: 0;
|
||
transform: translateY(20rpx);
|
||
transition: all 0.5s ease;
|
||
pointer-events: auto;
|
||
}
|
||
|
||
.dialog-wrapper.visible {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
|
||
.dialog-bg {
|
||
position: absolute;
|
||
top: 8rpx;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 200rpx;
|
||
z-index: 0;
|
||
transform: scale(1.2);
|
||
pointer-events: none;
|
||
|
||
}
|
||
|
||
.dialog-text-wrapper {
|
||
position: relative;
|
||
z-index: 1;
|
||
padding: 40rpx 50rpx 50rpx 50rpx;
|
||
min-height: 120rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
left: 15%;
|
||
}
|
||
|
||
.dialog-text {
|
||
font-size: 30rpx;
|
||
color: #333;
|
||
line-height: 1.5;
|
||
font-weight: 500;
|
||
}
|
||
|
||
/* 场景1文字上下居中样式 */
|
||
.dialog-text-wrapper-vertical {
|
||
position: relative;
|
||
left: 80rpx;
|
||
z-index: 1;
|
||
width: 256rpx;
|
||
height: 200rpx;
|
||
display: flex;
|
||
flex-direction: column;
|
||
justify-content: center;
|
||
align-items: center;
|
||
}
|
||
|
||
.dialog-text-wrapper-vertical.dialog-text-wrapper-vertical-on-video3 {
|
||
left: 48rpx;
|
||
width: 320rpx;
|
||
}
|
||
|
||
.dialog-text-wrapper-vertical.dialog-text-wrapper-vertical-on-video4 {
|
||
left: 56rpx;
|
||
bottom: 32rpx;
|
||
width: 320rpx;
|
||
}
|
||
|
||
.dialog-text-wrapper-vertical.dialog-text-wrapper-vertical-on-video5 {
|
||
left: 24rpx;
|
||
width: 336rpx;
|
||
}
|
||
|
||
.dialog-text-wrapper-vertical.dialog-text-wrapper-vertical-on-video6 {
|
||
width: 224rpx;
|
||
left: 80rpx;
|
||
}
|
||
|
||
.dialog-text-wrapper-vertical.dialog-text-wrapper-vertical-on-video7 {
|
||
width: 352rpx;
|
||
bottom: 16rpx;
|
||
left: 80rpx;
|
||
}
|
||
.dialog-text-wrapper-vertical.dialog-text-wrapper-vertical-on-video8 {
|
||
width: 356rpx;
|
||
left: 80rpx;
|
||
}
|
||
|
||
|
||
.dialog-text-vertical {
|
||
font-size: 24rpx;
|
||
color: #333;
|
||
font-weight: 500;
|
||
text-align: center;
|
||
letter-spacing: 4rpx;
|
||
line-height: 40rpx;
|
||
}
|
||
|
||
.dialog-text-vertical.dialog-text-vertical-on-video5 {
|
||
font-size: 32rpx;
|
||
}
|
||
|
||
.monster {
|
||
position: absolute;
|
||
right: 160rpx;
|
||
bottom: 20%;
|
||
width: 280rpx;
|
||
height: 280rpx;
|
||
opacity: 0;
|
||
transform: translateX(50rpx);
|
||
transition: all 0.6s ease;
|
||
pointer-events: auto;
|
||
}
|
||
|
||
.monster.visible {
|
||
opacity: 1;
|
||
transform: translateX(0);
|
||
}
|
||
|
||
/* 场景6背景 */
|
||
|
||
.scene6-wrapper {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
}
|
||
|
||
.scene6-bg {
|
||
position: relative;
|
||
height: 100%;
|
||
}
|
||
|
||
</style>
|