Files
super_video/src/views/basic-elements/light/index.vue
T

231 lines
6.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script lang="ts" setup>
import { computed, nextTick, ref } from 'vue'
import { useRouter } from 'vue-router'
import ImgButton from '@/components/Button/ImgButton.vue'
import { StepNavigation } from '@/components/Guide'
import { Video, QuestionQuiz, type Question } from '@/components'
import { getStaticImage, IMAGE_PATHS } from '@/utils'
import { GuideSteps } from '@/components/Guide'
// 光初识 - 暂时用光的基础认知代替
import video1 from '/video/new/xinshou_guangdejichurenzhi.mp4'
import video2 from '/video/new/xinshou_guangdesidashuxing.mp4'
import video3 from '/video/new/xsdh_psdhjsj_batch.mp4'
import GuideStepsItem from '@/components/Guide/GuideStepsItem.vue'
const router = useRouter()
// 受控播放开关(用于切换到下一个视频时自动播放)
const playing = ref(false)
const status = ref(false)
const showQuiz = ref(false) // 控制是否显示答题窗口
const isGuide = ref(true)
const currentGuideStep = ref(0)
const handleSkip = (index: number) => {
currentGuideStep.value = index
}
const handleComplete = () => {
isGuide.value = false
}
// 步骤导航数据
const navigationSteps = ref([
{
id: 'step2',
label: '视觉素养',
content: '光的基础认知',
type: 'planning' as const
},
{
id: 'step3',
label: '视觉素养',
content: '光的四大属性',
type: 'planning' as const
},
{
id: 'step4',
label: '视觉素养',
content: '拍摄的黄金时间',
type: 'planning' as const
}
])
// 步骤导航相关状态
const showStepNavigation = ref(false)
const currentNavigationStep = ref(0) // 对应视频索引,从0开始
// 视频列表
const videoList = [video1, video2, video3]
const currentVideoIndex = ref(0)
// 题目数据:拍摄的黄金时间(index 2)
const questions = ref<Question[]>([])
// 根据当前视频索引获取对应的题目
const getQuestionsForVideo = (index: number): Question[] => {
// 拍摄的黄金时间(index 2)
if (index === 2) {
return [
{
id: 1,
title: '',
description: '(单选)同一条街道,在不同时间拍摄,哪一张画面更适合表现"温暖、舒服的日常感"?',
options: [
{
id: 'a',
label: '正午直射光,阴影很硬,路面反光明显'
},
{
id: 'b',
label: '傍晚低角度阳光,墙面被染成金色'
},
{
id: 'c',
label: '夜晚路灯照明,光源复杂、色温混杂'
}
],
correctOptionId: 'b',
explanation: '光线角度越低,画面柔和,情绪放大'
}
]
}
return []
}
//按顺序播放
const currentVideo = computed(() => videoList[currentVideoIndex.value])
const handleVideoChange = () => {
if (currentVideoIndex.value < videoList.length - 1) {
currentVideoIndex.value++
currentNavigationStep.value = currentVideoIndex.value
} else {
status.value = true
return
}
nextTick(() => {
// 使用受控播放来触发下一个视频自动播放
playing.value = true
})
}
const handleClose = () => {
router.back()
}
const handlePlay = () => {
isGuide.value = false
}
const onEnded = () => {
// 检查是否是"拍摄的黄金时间"(index 2)
if (currentVideoIndex.value === 2) {
// 暂停播放并显示答题窗口
playing.value = false
questions.value = getQuestionsForVideo(currentVideoIndex.value)
showQuiz.value = true
} else {
// 其他视频正常切换
handleVideoChange()
}
}
// 步骤导航事件处理
const handleStepClick = (index: number) => {
// 关闭答题窗口(如果打开)
showQuiz.value = false
currentVideoIndex.value = index
currentNavigationStep.value = index
nextTick(() => {
playing.value = true
})
}
const handleStepNavigationClose = () => {
showStepNavigation.value = false
}
// 答题完成后的处理
const handleQuestionsComplete = () => {
showQuiz.value = false
// 答题完成后继续播放下一个视频
handleVideoChange()
}
</script>
<template>
<div class="w-full h-full relative bg-white/10">
<ImgButton
class="absolute right-0 top-0 z-10"
:image="IMAGE_PATHS.COMPONENTS.BACK"
@click="handleClose"
/>
<!-- 步骤导航按钮 -->
<button
class="absolute right-4 top-1/2 z-10 -translate-y-1/2 w-12 h-12 bg-blue-500/80 hover:bg-blue-500 rounded-full flex items-center justify-center text-white transition-all duration-200"
@click="showStepNavigation = true"
title="步骤导航"
>
<svg width="20" height="20" viewBox="0 0 20 20" fill="none">
<path
d="M3 4H17M3 8H17M3 12H17M3 16H17"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
/>
</svg>
</button>
<Video
:src="currentVideo"
v-model="playing"
:muted="false"
:volume="1"
:controls="true"
:hideNativeControls="true"
:anchors="[]"
@play="handlePlay"
@ended="onEnded"
>
<template v-slot:overlay>
<ImgButton
class="absolute right-0 top-0 z-10 pointer-events-auto"
:image="IMAGE_PATHS.COMPONENTS.BACK"
@click="handleClose"
/>
<QuestionQuiz
v-if="showQuiz"
:show-question-number="false"
:questions="questions"
@complete="handleQuestionsComplete"
/>
</template>
</Video>
<!-- 步骤导航抽屉 -->
<StepNavigation
:visible="showStepNavigation"
:background-image="getStaticImage('work/vlog背景全屏待定')"
:steps="navigationSteps"
:current-step-index="currentNavigationStep"
@step-click="handleStepClick"
@close="handleStepNavigationClose"
/>
<!-- 引导与高亮 -->
<GuideSteps v-if="isGuide" position-offset-y="85%" @complete="handleComplete">
<GuideStepsItem>光是摄影的灵魂,摄影高手一定是用光的高手</GuideStepsItem>
</GuideSteps>
</div>
</template>
<style scoped>
video {
width: 100%;
height: 100%;
/* 核心:保持视频比例,多余部分被裁剪 */
object-fit: cover;
}
</style>