forked from zhongyidian/super_video
统一引导提示的持久化控制,补充学习进度入口与模块资源,避免用户返回页面时重复触发提示。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
514 lines
12 KiB
Vue
514 lines
12 KiB
Vue
<script lang="tsx" setup>
|
|
import { getBackgroundImage, getStaticImage, IMAGE_PATHS } from '@/utils'
|
|
import { GuideSteps, GuideStepsItem } from '@/components/Guide'
|
|
import { computed, ref } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { ImgButton } from '@/components/Button'
|
|
|
|
const router = useRouter()
|
|
|
|
const back = () => {
|
|
// 跳转设备准备
|
|
router.back()
|
|
}
|
|
const steps = [
|
|
{
|
|
id: 'step1',
|
|
content: '先认识 Vlog:点击右侧「1.vlog初识」继续',
|
|
highlightSelector: '.img-switch-item--vlog'
|
|
},
|
|
{
|
|
id: 'step2',
|
|
content: '这是主要内容区域的边框',
|
|
highlightSelector: '.work-border'
|
|
}
|
|
]
|
|
const hiddenbar = ref(false)
|
|
const currentIndex = ref(0)
|
|
const selectedMenuIndex = ref(0)
|
|
|
|
const equipmentItems = [
|
|
{
|
|
id: 'camera',
|
|
name: '相机 / 摄像机 / 微单',
|
|
productImages: [
|
|
getStaticImage('equipment/相机产品.png'),
|
|
getStaticImage('equipment/摄像机产品.png'),
|
|
getStaticImage('equipment/微单产品.png')
|
|
],
|
|
title: getStaticImage('equipment/相机标题.png'),
|
|
text: getStaticImage('equipment/相机内容.png')
|
|
},
|
|
{
|
|
id: 'tripod',
|
|
name: '三脚架',
|
|
productImages: [getStaticImage('equipment/三角架产品.png')],
|
|
title: getStaticImage('equipment/三脚架标题.png'),
|
|
text: getStaticImage('equipment/三脚架内容.png')
|
|
},
|
|
{
|
|
id: 'light',
|
|
name: '灯光',
|
|
productImages: [
|
|
getStaticImage('equipment/led补光灯.png'),
|
|
getStaticImage('equipment/环形灯产品.png')
|
|
],
|
|
title: getStaticImage('equipment/灯标题.png'),
|
|
text: getStaticImage('equipment/灯内容.png')
|
|
}
|
|
]
|
|
|
|
const menuItems = ref(
|
|
equipmentItems.map(item => ({ id: item.id, name: item.name, disabled: false }))
|
|
)
|
|
|
|
const currentEquipment = computed(() => equipmentItems[selectedMenuIndex.value])
|
|
const currentProductImages = computed(() => currentEquipment.value.productImages)
|
|
|
|
const hiddenbarclick = () => {
|
|
hiddenbar.value = !hiddenbar.value
|
|
}
|
|
|
|
// 选择菜单项
|
|
const selectMenuItem = (index: number, item: { id: string; name: string; disabled: boolean }) => {
|
|
if (item.disabled) {
|
|
console.log(`菜单项 "${item.name}" 已被禁用`)
|
|
return
|
|
}
|
|
selectedMenuIndex.value = index
|
|
currentIndex.value = 0
|
|
}
|
|
|
|
// 下一张图片
|
|
const nextPhone = () => {
|
|
if (currentIndex.value < currentProductImages.value.length - 1) {
|
|
currentIndex.value++
|
|
}
|
|
}
|
|
|
|
// 上一张图片
|
|
const prevPhone = () => {
|
|
if (currentIndex.value > 0) {
|
|
currentIndex.value--
|
|
}
|
|
}
|
|
</script>
|
|
<template>
|
|
<div class="equipment-index">
|
|
<!-- 背景图片 -->
|
|
<div
|
|
class="absolute inset-0 bg-cover bg-center bg-no-repeat equipment-bg"
|
|
:style="{ backgroundImage: getBackgroundImage(IMAGE_PATHS.EQUIPMENT.BG) }"
|
|
></div>
|
|
|
|
<div class="equipment-bar">
|
|
<img src="@/assets/images/equipment/侧边导航栏.png" alt="" :hidden="hiddenbar" />
|
|
<!-- 内容列表 -->
|
|
<div class="equipment-item" :hidden="hiddenbar">
|
|
<div class="menu-list">
|
|
<div
|
|
v-for="(item, index) in menuItems"
|
|
:key="item.id"
|
|
class="menu-item"
|
|
:class="{
|
|
'menu-item--active': selectedMenuIndex === index,
|
|
'menu-item--disabled': item.disabled
|
|
}"
|
|
@click="selectMenuItem(index, item)"
|
|
>
|
|
<div
|
|
class="menu-item__indicator"
|
|
v-if="selectedMenuIndex === index && !item.disabled"
|
|
></div>
|
|
<span class="menu-item__text">{{ item.name }}</span>
|
|
<div class="menu-item__status" v-if="item.disabled">
|
|
<!-- <span class="status-text">未解锁</span> -->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 设备准备按钮 -->
|
|
<div class="equipment-bt">
|
|
<img src="@/assets/images/equipment/按钮选中-设备准备.png" alt="" />
|
|
</div>
|
|
<div :class="hiddenbar ? 'equipment-unfold1' : 'equipment-unfold2'" @click="hiddenbarclick()">
|
|
<img
|
|
:src="
|
|
hiddenbar
|
|
? getStaticImage('equipment/按钮-展开.png')
|
|
: getStaticImage('equipment/按钮-收缩.png')
|
|
"
|
|
alt=""
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="equipment-layout">
|
|
<div class="equipment-home">
|
|
<div
|
|
class="equipment-leftbutton"
|
|
@click="prevPhone"
|
|
:style="{ visibility: currentIndex > 0 ? 'visible' : 'hidden' }"
|
|
>
|
|
<img src="@/assets/images/equipment/按钮-左滑.png" alt="" />
|
|
</div>
|
|
<div class="equipment-phoneImg">
|
|
<img :src="currentProductImages[currentIndex]" alt="" />
|
|
</div>
|
|
<div
|
|
class="equipment-rightbutton"
|
|
@click="nextPhone"
|
|
:style="{
|
|
visibility: currentIndex < currentProductImages.length - 1 ? 'visible' : 'hidden'
|
|
}"
|
|
>
|
|
<img src="@/assets/images/equipment/按钮-右滑.png" alt="" />
|
|
</div>
|
|
</div>
|
|
<div class="equipment-purpose">
|
|
<div class="plate">
|
|
<img src="@/assets/images/equipment/浮空屏.png" alt="" />
|
|
</div>
|
|
|
|
<div class="title">
|
|
<img :src="currentEquipment.title" alt="" />
|
|
</div>
|
|
<div class="plate-content">
|
|
<div class="text">
|
|
<img :src="currentEquipment.text" alt="" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<ImgButton class="absolute right-0 top-0" :image="IMAGE_PATHS.COMPONENTS.BACK" @click="back" />
|
|
<!-- 调试按钮组 -->
|
|
<!-- <div class="debug-controls">
|
|
<button @click="enableAllMenuItems" class="debug-btn">启用全部</button>
|
|
<button @click="disableAllMenuItems" class="debug-btn">禁用全部</button>
|
|
<button @click="toggleMenuItem('bluetooth-remote')" class="debug-btn">切换蓝牙遥控器</button>
|
|
</div> -->
|
|
</div>
|
|
</template>
|
|
<style lang="less" scoped>
|
|
.equipment-index {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.equipment-layout {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.equipment-bar {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
z-index: 10;
|
|
|
|
.equipment-bt {
|
|
position: absolute;
|
|
top: 0;
|
|
left: -135px;
|
|
width: 577px;
|
|
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
.equipment-unfold1 {
|
|
position: absolute;
|
|
top: 490px;
|
|
left: -41px;
|
|
width: 150px;
|
|
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
}
|
|
}
|
|
|
|
.equipment-unfold2 {
|
|
position: absolute;
|
|
top: 490px;
|
|
left: 268px;
|
|
width: 150px;
|
|
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
}
|
|
}
|
|
|
|
.equipment-item {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
padding-top: 220px;
|
|
padding-left: 20px;
|
|
|
|
.menu-list {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
//background: linear-gradient(135deg, #1a2a4a 0%, #0f1a2e 100%);
|
|
border-radius: 12px;
|
|
padding: 16px 12px;
|
|
// box-shadow:
|
|
// 0 0 20px rgba(64, 150, 255, 0.3),
|
|
// inset 0 0 20px rgba(64, 150, 255, 0.1);
|
|
// backdrop-filter: blur(10px);
|
|
}
|
|
|
|
.menu-item {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 24px 32px;
|
|
border-radius: 8px;
|
|
cursor: pointer;
|
|
transition: all 0.3s ease;
|
|
min-height: 44px;
|
|
|
|
&:hover {
|
|
// background: rgba(64, 150, 255, 0.1);
|
|
transform: translateX(4px);
|
|
}
|
|
|
|
&--active {
|
|
// background: rgba(64, 150, 255, 0.2);
|
|
// box-shadow: 0 0 15px rgba(64, 150, 255, 0.4);
|
|
|
|
.menu-item__text {
|
|
color: #ffffff;
|
|
text-shadow:
|
|
0 0 10px rgba(64, 150, 255, 0.8),
|
|
0 0 20px rgba(64, 150, 255, 0.6),
|
|
0 0 30px rgba(64, 150, 255, 0.4);
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
&__indicator {
|
|
position: absolute;
|
|
left: 0px;
|
|
top: 45%;
|
|
transform: translateY(-50%);
|
|
width: 6px;
|
|
height: 38px;
|
|
background: #ffffff;
|
|
border-radius: 2px;
|
|
box-shadow: 0 0 16px rgba(255, 255, 255, 0.8);
|
|
}
|
|
|
|
&__text {
|
|
color: #64a5ff;
|
|
font-size: 30px;
|
|
font-weight: 800;
|
|
text-shadow: 0 0 8px rgba(64, 150, 255, 0.6);
|
|
transition: all 0.3s ease;
|
|
user-select: none;
|
|
}
|
|
|
|
&__status {
|
|
position: absolute;
|
|
right: 16px;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
|
|
.status-text {
|
|
font-size: 12px;
|
|
color: #999;
|
|
background: rgba(0, 0, 0, 0.6);
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
border: 1px solid #333;
|
|
}
|
|
}
|
|
|
|
// 禁用状态样式
|
|
&--disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
pointer-events: auto; // 保持可点击以显示禁用提示
|
|
|
|
&:hover {
|
|
transform: none;
|
|
// background: rgba(255, 0, 0, 0.1);
|
|
}
|
|
|
|
.menu-item__text {
|
|
color: #666;
|
|
text-shadow: none;
|
|
}
|
|
|
|
.menu-item__indicator {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.guide-ui {
|
|
top: 80% !important;
|
|
}
|
|
|
|
.dragon-character {
|
|
top: 80% !important;
|
|
}
|
|
}
|
|
|
|
.equipment-home {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
.equipment-leftbutton {
|
|
position: absolute;
|
|
top: 511px;
|
|
left: 350px;
|
|
width: 200px;
|
|
height: 200px;
|
|
cursor: pointer;
|
|
z-index: 10;
|
|
}
|
|
|
|
.equipment-phoneImg {
|
|
position: absolute;
|
|
top: 313px;
|
|
left: 500px;
|
|
width: 446px;
|
|
height: 484px;
|
|
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: contain;
|
|
}
|
|
}
|
|
|
|
.equipment-rightbutton {
|
|
position: absolute;
|
|
top: 511px;
|
|
right: 770px;
|
|
width: 200px;
|
|
height: 200px;
|
|
cursor: pointer;
|
|
z-index: 10;
|
|
}
|
|
}
|
|
|
|
.equipment-purpose {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
|
|
.plate {
|
|
position: absolute;
|
|
top: 30px;
|
|
left: 1200px;
|
|
width: 600px;
|
|
/* 调整为你需要的宽度 */
|
|
height: 1000px;
|
|
/* 调整为你需要的高度 */
|
|
|
|
img {
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
}
|
|
|
|
.plate-content {
|
|
position: absolute;
|
|
top: 144px;
|
|
right: 100px;
|
|
width: 600px;
|
|
height: 797px;
|
|
overflow: hidden;
|
|
/* 隐藏超出部分 */
|
|
object-fit: contain;
|
|
|
|
// display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
overflow-y: auto;
|
|
/* 允许垂直滚动 */
|
|
scrollbar-width: none;
|
|
/* Firefox隐藏滚动条 */
|
|
-ms-overflow-style: none;
|
|
/* IE和Edge隐藏滚动条 */
|
|
perspective: 1000px;
|
|
|
|
&::-webkit-scrollbar {
|
|
display: none;
|
|
/* Chrome, Safari隐藏滚动条 */
|
|
}
|
|
}
|
|
|
|
.title {
|
|
// margin-top: 47px;
|
|
width: 400px;
|
|
z-index: 2;
|
|
position: absolute;
|
|
top: 36px;
|
|
left: 1304px;
|
|
}
|
|
|
|
.text {
|
|
position: absolute;
|
|
top: -9px;
|
|
left: 8px;
|
|
z-index: 2;
|
|
transform: rotate3d(0, 1, 0, -20deg);
|
|
|
|
img {
|
|
width: 100%;
|
|
height: auto;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 调试控制按钮样式
|
|
.debug-controls {
|
|
position: absolute;
|
|
top: 20px;
|
|
left: 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
z-index: 1000;
|
|
|
|
.debug-btn {
|
|
background: rgba(0, 0, 0, 0.8);
|
|
color: white;
|
|
border: 1px solid #333;
|
|
padding: 6px 12px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
font-size: 12px;
|
|
transition: background 0.3s ease;
|
|
|
|
&:hover {
|
|
background: rgba(0, 0, 0, 0.9);
|
|
}
|
|
}
|
|
}
|
|
</style>
|