forked from zhongyidian/super_video
完善课程资源、学习进度与技能树解锁体验,统一视频播放与引导相关交互。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
175 lines
5.7 KiB
Vue
175 lines
5.7 KiB
Vue
<script lang="ts" setup>
|
|
import { ref } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { GuideSteps, type GuideStep } from '@/components/Guide'
|
|
import { ImgButton } from '@/components/Button'
|
|
import { getBackgroundImage, getPublicPath, getStaticImage } from '@/utils'
|
|
import shootingtitle from '@/assets/images/shooting/标题-实地取景.png'
|
|
import videoSrc from '/video/new/composition/xsdh_jzgtf_batch.mp4'
|
|
import KnowledgeCard from '@/components/KnowledgeCard/FilmKnowledgeCard.vue'
|
|
import CompositionGuide from '@/components/CompositionGuide.vue'
|
|
import { useFilmStore } from '@/stores/modules/film'
|
|
|
|
const router = useRouter()
|
|
const filmStore = useFilmStore()
|
|
const introGuideKey = 'film-shooting-intro'
|
|
const compositionGuideKey = 'film-shooting-composition'
|
|
const showIntroGuide = ref(!filmStore.guideShown[introGuideKey])
|
|
const showCompositionGuide = ref(!filmStore.guideShown[compositionGuideKey])
|
|
|
|
if (showIntroGuide.value) {
|
|
filmStore.markGuideShown(introGuideKey)
|
|
}
|
|
|
|
const steps = ref<GuideStep[]>([
|
|
{
|
|
id: '1',
|
|
audioSrc: getPublicPath('audio/py_4_015.MP3'),
|
|
content: '哇,徐汇滨江真的超适合取景,一起看看可以运用哪些构图方法吧!',
|
|
highlightSelector: '.btn-1',
|
|
},
|
|
])
|
|
|
|
const guideSteps = ref<GuideStep[]>([
|
|
{
|
|
id: '1',
|
|
content: '点击框架构图,查看构图方法',
|
|
highlightSelector: '.btn-item-1',
|
|
},
|
|
{
|
|
id: '2',
|
|
content: '点击对称构图,查看构图方法',
|
|
highlightSelector: '.btn-item-2',
|
|
},
|
|
{
|
|
id: '3',
|
|
content: '点击引导线构图,查看构图方法',
|
|
highlightSelector: '.btn-item-3',
|
|
},
|
|
])
|
|
const showModal = ref(false)
|
|
|
|
const btnList = ref([
|
|
{
|
|
key: '1',
|
|
name: '框架构图',
|
|
btnImage: 'film/shooting/框架构图',
|
|
desc: '框架构图是拍摄时用“框架”把主体框起来,可以让画面更加有空间感及层次感,并且使用也并不复杂,比如镜子、门窗、山洞等,也可以说是光影框等。',
|
|
images: ['film/shooting/01框架构图_底图', 'film/shooting/02框架构图_底图'],
|
|
},
|
|
{
|
|
key: '2',
|
|
name: '对称构图',
|
|
btnImage: 'film/shooting/对称构图',
|
|
desc: '对称构图是通过画面中轴线(水平 / 垂直)两侧元素镜像分布的构图方式,属于平衡类构图。它借对称的视觉均衡感,让画面显规整、稳定,同时强化主体秩序与美感。拍摄可找天然对称景物(如建筑、倒影),或调整角度让元素对称;略有不对称可后期微调,适合展现建筑、对称静物等规整场景。',
|
|
images: ['film/shooting/03对称构图_底图', 'film/shooting/04对称构图_底图'],
|
|
},
|
|
{
|
|
key: '3',
|
|
name: '引导线构图',
|
|
btnImage: 'film/shooting/引导线构图',
|
|
desc: '引导线构图的关键在于引导线,借助环境中的引导线,把观者注意力集中到引导线上,营造画面纵深效果,我们日常拍摄中常见的引导线有:马路及其延伸(马路线、栏杆、走廊)。',
|
|
images: [
|
|
'film/shooting/05引导线构图_底图',
|
|
'film/shooting/06引导线构图_底图',
|
|
],
|
|
},
|
|
])
|
|
|
|
const openCompositionGuide = () => {
|
|
showModal.value = true
|
|
if (showCompositionGuide.value) {
|
|
filmStore.markGuideShown(compositionGuideKey)
|
|
}
|
|
}
|
|
|
|
const handleClickA = () => {
|
|
router.push({ name: 'FilmFilmingLocationA' })
|
|
}
|
|
const handleClickB = () => {
|
|
router.push({ name: 'FilmFilmingLocationB' })
|
|
}
|
|
const back = () => {
|
|
router.back()
|
|
}
|
|
</script>
|
|
<template>
|
|
<div class="relative w-full h-full">
|
|
<!-- 背景图片 -->
|
|
<div
|
|
class="absolute inset-0 bg-cover bg-center bg-no-repeat shooting-bg"
|
|
:style="{ backgroundImage: getBackgroundImage('film/shooting/底图') }"
|
|
></div>
|
|
|
|
<div class="absolute top-0 left-0">
|
|
<img
|
|
:src="shootingtitle"
|
|
alt=""
|
|
/>
|
|
</div>
|
|
<div class="absolute top-0 right-0">
|
|
<ImgButton
|
|
image="shooting/返回.png"
|
|
@click="back"
|
|
/>
|
|
</div>
|
|
<div class="absolute left-[12%] top-1/2 -translate-y-[calc(50%-70px)]">
|
|
<div class="relative inline-block">
|
|
<ImgButton
|
|
class="btn-2"
|
|
image="film/shooting/龙美术馆入口.png"
|
|
@click="handleClickA"
|
|
/>
|
|
<img
|
|
v-if="filmStore.isRouteViewed('FilmFilmingLocationA')"
|
|
:src="getStaticImage('midterm/完成.png')"
|
|
class="absolute -top-8 right-6 w-24 pointer-events-none"
|
|
alt="已完成"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="absolute right-[12%] top-1/2 -translate-y-[calc(50%-70px)]">
|
|
<div class="relative inline-block">
|
|
<ImgButton
|
|
class="btn-3"
|
|
image="film/shooting/油罐艺术公园入口.png"
|
|
@click="handleClickB"
|
|
/>
|
|
<img
|
|
v-if="filmStore.isRouteViewed('FilmFilmingLocationB')"
|
|
:src="getStaticImage('midterm/完成.png')"
|
|
class="absolute -top-8 right-14 w-24 pointer-events-none"
|
|
alt="已完成"
|
|
/>
|
|
</div>
|
|
</div>
|
|
<div class="absolute bottom-4 left-4 btn-1">
|
|
<ImgButton
|
|
image="shooting/构图指南.png"
|
|
@click="openCompositionGuide"
|
|
/>
|
|
</div>
|
|
|
|
<!-- 引导步骤 -->
|
|
<GuideSteps
|
|
:visible="showIntroGuide"
|
|
:steps="steps"
|
|
:highlight-padding="12"
|
|
:highlight-radius="20"
|
|
position-offset-y="20%"
|
|
/>
|
|
|
|
<!-- 构图指南弹窗 -->
|
|
<CompositionGuide
|
|
:visible="showModal"
|
|
bg-image="film/shooting/构图指南底图"
|
|
:btn-list="btnList"
|
|
:knowledge-card-component="KnowledgeCard"
|
|
:video-src="videoSrc"
|
|
:guide-steps="guideSteps"
|
|
:show-internal-guide="showCompositionGuide"
|
|
@close="showModal = false"
|
|
/>
|
|
</div>
|
|
</template>
|