Merge branch 'main' of https://gitee.com/zzyyymm/super_video
This commit is contained in:
commit
273bed54ff
27 files changed
+503
-37
No files matched your search
@@ -1,5 +1,5 @@
|
||||
<script lang="ts" setup>
|
||||
import { getBackgroundImage, IMAGE_PATHS } from '@/utils'
|
||||
import { getBackgroundImage, getStaticImage, IMAGE_PATHS } from '@/utils'
|
||||
import { ImgButton } from '@/components/Button'
|
||||
import { ModuleSwitcher } from './components/ModuleSwitcher'
|
||||
import { computed, ref, onMounted } from 'vue'
|
||||
@@ -121,6 +121,11 @@ onMounted(() => {
|
||||
class="absolute top-60 right-1/2 translate-x-1/2"
|
||||
@click="handleCloseGuide"
|
||||
/>
|
||||
<img
|
||||
class="absolute bottom-0 left-1/2 -translate-x-1/2"
|
||||
:src="getStaticImage('home/新手导航')"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- <GuideSteps @complete="handleComplete" @skip="handleSkip">
|
||||
|
||||
@@ -25,6 +25,11 @@ const handleWorkClick = () => {
|
||||
// 处理任务取景按钮点击逻辑
|
||||
router.push({ name: 'Work' })
|
||||
}
|
||||
|
||||
const handleClick = () => {
|
||||
// 处理任务取景按钮点击逻辑
|
||||
router.push({ name: 'equipment' })
|
||||
}
|
||||
const highlightShow = ref(true)
|
||||
</script>
|
||||
|
||||
@@ -59,7 +64,10 @@ const highlightShow = ref(true)
|
||||
<ImgButton :image="IMAGE_PATHS.VLOG.Midterm" />
|
||||
</div>
|
||||
<!-- 进度百分比 -->
|
||||
<div v-if="highlightShow" class="absolute left-1/2 top-[12%] -translate-x-1/2">
|
||||
<div
|
||||
v-if="highlightShow"
|
||||
class="absolute left-1/2 top-[12%] -translate-x-1/2 pointer-events-none"
|
||||
>
|
||||
<div class="flex">
|
||||
<ImgButton :image="IMAGE_PATHS.VLOG.Progress" />
|
||||
<ImgButton :image="IMAGE_PATHS.VLOG.Four" />
|
||||
@@ -73,7 +81,11 @@ const highlightShow = ref(true)
|
||||
class="absolute left-[21%] top-[9%] -translate-x-1/2"
|
||||
style="z-index: 998"
|
||||
>
|
||||
<ImgButton :image="IMAGE_PATHS.VLOG.MidtermEquipment" class="ml-[60px]" />
|
||||
<ImgButton
|
||||
:image="IMAGE_PATHS.VLOG.MidtermEquipment"
|
||||
@click="handleClick"
|
||||
class="ml-[60px]"
|
||||
/>
|
||||
<ImgButton :image="IMAGE_PATHS.VLOG.MidtermFraming" class="ml-[40px]" />
|
||||
<ImgButton :image="IMAGE_PATHS.VLOG.MidtermShoot" class="ml-[20px]" />
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,6 @@ import { ProgressBar } from '@/components'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { GuideSteps } from '@/components/Guide'
|
||||
type WorkTab = 'vlog' | 'case' | 'profession' | 'idea'
|
||||
const steps = [
|
||||
{
|
||||
id: 'step1',
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
import { getBackgroundImage, IMAGE_PATHS } from '@/utils'
|
||||
import { ImgButton } from '@/components/Button'
|
||||
|
||||
import { ref } from 'vue'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { ProgressBar } from '@/components'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
const currentStep = ref(0)
|
||||
|
||||
@@ -25,6 +26,12 @@ const handleWorkClick = () => {
|
||||
// 处理任务取景按钮点击逻辑
|
||||
router.push({ name: 'Work' })
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (route.query.key === 'video') {
|
||||
currentStep.value = 1
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -51,7 +58,10 @@ const handleWorkClick = () => {
|
||||
class="absolute left-24 top-24"
|
||||
:style="{ backgroundImage: getBackgroundImage(IMAGE_PATHS.VLOG.TASK_CAMERA) }"
|
||||
>
|
||||
<ImgButton :image="IMAGE_PATHS.VLOG.TASK_BTN" @click="handleWorkClick" />
|
||||
<ImgButton
|
||||
:image="currentStep === 1 ? IMAGE_PATHS.VLOG.TASK_BTN_OK : IMAGE_PATHS.VLOG.TASK_BTN"
|
||||
@click="handleWorkClick"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 引导任务 -->
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, nextTick, onMounted, ref } from 'vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
import ImgButton from '@/components/Button/ImgButton.vue'
|
||||
import { GuideSteps } from '@/components/Guide'
|
||||
import { getStaticImage, IMAGE_PATHS } from '@/utils'
|
||||
import second from '/video/Vlog模块_任务取景框_专业剖析_基础景别运用.mp4'
|
||||
import third from '/video/Vlog模块_任务取景框_专业剖析_画面构图.mp4'
|
||||
import fourth from '/video/Vlog模块_任务取景框_专业剖析_脚本策划.mp4'
|
||||
import five from '/video/Vlog模块_任务取景框_专业剖析_动态事件跟拍与抓拍.mp4'
|
||||
import six from '/video/Vlog模块_任务取景框_专业剖析_素材导入、剪辑拼接.mp4'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
const videoRef = ref()
|
||||
const status = ref(false)
|
||||
|
||||
//引导步骤
|
||||
const steps = ref([
|
||||
{
|
||||
id: 'step1',
|
||||
content: '试着用这些方法记录身边的小事,你会发现,原来平凡的日子里有这么多值得捕捉的瞬间。'
|
||||
}
|
||||
])
|
||||
|
||||
// 视频列表
|
||||
const videoList = [second, third, fourth, five, six]
|
||||
const currentVideoIndex = ref(0)
|
||||
|
||||
//按顺序播放
|
||||
const currentVideo = computed(() => videoList[currentVideoIndex.value])
|
||||
const handleVideoChange = () => {
|
||||
if (currentVideoIndex.value < videoList.length - 1) {
|
||||
currentVideoIndex.value++
|
||||
} else {
|
||||
status.value = true
|
||||
steps.value = [
|
||||
{
|
||||
id: 'step1',
|
||||
content: '已完成专业剖析,即可查看脚本'
|
||||
}
|
||||
]
|
||||
return
|
||||
}
|
||||
nextTick(() => {
|
||||
if (!videoRef.value) return
|
||||
videoRef.value.muted = false
|
||||
videoRef.value.volume = 1
|
||||
videoRef.value.play()
|
||||
})
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
router.back()
|
||||
}
|
||||
|
||||
const image = computed(() => route.query.image as string)
|
||||
const key = computed(() => route.query.key as string)
|
||||
|
||||
const handleClick = () => {
|
||||
if (!videoRef.value) return
|
||||
videoRef.value.muted = false
|
||||
videoRef.value.volume = 1
|
||||
}
|
||||
|
||||
const handlePlay = () => {
|
||||
if (!videoRef.value) return
|
||||
videoRef.value.muted = false
|
||||
videoRef.value.volume = 1
|
||||
}
|
||||
|
||||
const handleComplete = () => {
|
||||
if (key.value === 'profession') {
|
||||
router.push({
|
||||
name: 'Work',
|
||||
query: {
|
||||
key: 'work'
|
||||
}
|
||||
})
|
||||
} else {
|
||||
router.push({
|
||||
name: 'midterm',
|
||||
query: {
|
||||
key: 'midterm'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (key.value === 'idea') {
|
||||
status.value = true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full h-full relative bg-white/10" @click="handleClick">
|
||||
<ImgButton class="absolute left-4 top-4 z-10" :image="image"></ImgButton>
|
||||
<ImgButton
|
||||
class="absolute right-0 top-0 z-10"
|
||||
:image="IMAGE_PATHS.COMPONENTS.BACK"
|
||||
@click="handleClose"
|
||||
/>
|
||||
<div v-if="key === 'vlog'" :src="image">
|
||||
<img :src="getStaticImage('work/vlog背景全屏待定')" alt="" />
|
||||
</div>
|
||||
<video
|
||||
ref="videoRef"
|
||||
v-else-if="key === 'case'"
|
||||
src="/video/案例赏析-美食小确幸:桂花酒酿小圆子.mp4"
|
||||
controls
|
||||
@play="handlePlay"
|
||||
></video>
|
||||
<!-- 专业剖析 -->
|
||||
<video
|
||||
ref="videoRef"
|
||||
v-else-if="key === 'profession'"
|
||||
:src="currentVideo"
|
||||
controls
|
||||
@play="handlePlay"
|
||||
@ended="handleVideoChange"
|
||||
></video>
|
||||
<div v-else-if="key === 'idea'" :src="image">
|
||||
<img :src="getStaticImage('work/思路提点全屏')" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 引导与高亮 -->
|
||||
<GuideSteps v-if="status" :steps="steps" position-offset-y="85%" @complete="handleComplete" />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/* 核心:保持视频比例,多余部分被裁剪 */
|
||||
object-fit: cover;
|
||||
}
|
||||
</style>
|
||||
@@ -44,4 +44,8 @@ const items = [
|
||||
]
|
||||
|
||||
const onChange = (val: string) => emit('change', val as WorkTab)
|
||||
|
||||
defineExpose({
|
||||
items
|
||||
})
|
||||
</script>
|
||||
@@ -1,20 +1,61 @@
|
||||
<script lang="tsx" setup>
|
||||
import { ref, computed } from 'vue'
|
||||
import { getBackgroundImage, IMAGE_PATHS } from '@/utils'
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { getBackgroundImage, IMAGE_PATHS, getStaticImage } from '@/utils'
|
||||
import { ImgButton } from '@/components/Button'
|
||||
import WorkSideSwitcher from './components/WorkSideSwitcher.vue'
|
||||
import { GuideSteps } from '@/components/Guide'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
type WorkTab = 'vlog' | 'case' | 'profession' | 'idea'
|
||||
|
||||
const selected = ref<WorkTab>('vlog')
|
||||
const stepIndex = ref(0)
|
||||
const workSideSwitcherRef = ref<InstanceType<typeof WorkSideSwitcher>>()
|
||||
|
||||
const status = ref(false)
|
||||
|
||||
//引导步骤
|
||||
const steps = [
|
||||
{ id: 'step1', content: '先认识 Vlog:点击右侧「1.vlog初识」继续' },
|
||||
{ id: 'step2', content: '这是主要内容区域的边框' }
|
||||
{
|
||||
id: 'step1',
|
||||
content:
|
||||
'现在我们要一起走进 Vlog 的世界。简单说,Vlog 就是用视频记录生活的一种方式 —— 它像一本会动的日记,能把我们身边的小事、瞬间的心情,通过镜头变得生动又具体。'
|
||||
},
|
||||
{ id: 'step2', content: '接下来,我们就通过一个具体的案例,看看 Vlog 是怎么“捕捉美好” 的吧。' }
|
||||
]
|
||||
|
||||
//切换图片
|
||||
const sideSwitcherItems = ref([
|
||||
{
|
||||
key: 'vlog',
|
||||
description: '记录身边的美好',
|
||||
image: 'work/vlog初识框'
|
||||
},
|
||||
{
|
||||
key: 'case',
|
||||
description: '美食小确幸:桂花酒酿小圆子',
|
||||
image: 'work/案例背景待定'
|
||||
},
|
||||
{
|
||||
key: 'profession',
|
||||
description: '美食小确幸:桂花酒酿小圆子',
|
||||
image: 'work/案例背景待定'
|
||||
},
|
||||
{
|
||||
key: 'idea',
|
||||
description: '美食小确幸:桂花酒酿小圆子',
|
||||
image: 'work/思路提点小屏'
|
||||
}
|
||||
])
|
||||
|
||||
//当前选中的item
|
||||
const currentItem = computed(() => {
|
||||
return sideSwitcherItems.value.find(item => item.key === selected.value)
|
||||
})
|
||||
|
||||
const currentHighlight = computed(() =>
|
||||
stepIndex.value === 0 ? '.img-switch-item--vlog' : '.work-border'
|
||||
)
|
||||
@@ -26,6 +67,38 @@ interface SimpleStep {
|
||||
const handleStepChange = (_step: SimpleStep | null, index: number) => {
|
||||
stepIndex.value = index
|
||||
}
|
||||
|
||||
const handleSideSwitcherChange = (value: WorkTab) => {
|
||||
if (selected.value === value) return
|
||||
}
|
||||
|
||||
const handleImageClick = () => {
|
||||
router.push({
|
||||
name: 'Video',
|
||||
query: {
|
||||
image:
|
||||
workSideSwitcherRef.value?.items.find(item => item.key === selected.value)?.activeImage ||
|
||||
'',
|
||||
key: selected.value
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
router.back()
|
||||
}
|
||||
|
||||
//状态是否完成前置
|
||||
const isComplete = ref(false)
|
||||
|
||||
onMounted(() => {
|
||||
if (route.query.key === 'work') {
|
||||
selected.value = 'profession'
|
||||
isComplete.value = true
|
||||
} else {
|
||||
status.value = true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -36,6 +109,13 @@ const handleStepChange = (_step: SimpleStep | null, index: number) => {
|
||||
:style="{ backgroundImage: getBackgroundImage(IMAGE_PATHS.WORK.BG) }"
|
||||
></div>
|
||||
|
||||
<!-- 关闭 -->
|
||||
<ImgButton
|
||||
class="absolute right-0 top-0"
|
||||
:image="IMAGE_PATHS.COMPONENTS.CLOSE"
|
||||
@click="handleClose"
|
||||
/>
|
||||
|
||||
<!-- border图片 -->
|
||||
<div
|
||||
class="work-border absolute top-[140px] left-24 inset-0 bg-cover bg-center bg-no-repeat z-10 w-[1360px] h-[800px] p-10"
|
||||
@@ -48,31 +128,42 @@ const handleStepChange = (_step: SimpleStep | null, index: number) => {
|
||||
<span
|
||||
class="mt-24 text-white font-bold text-6xl [text-shadow:0_2px_4px_rgba(0,0,0,0.2),0_0_6px_rgba(0,207,255,0.9),0_0_14px_rgba(0,207,255,0.7)]"
|
||||
>
|
||||
记录身边的美好</span
|
||||
{{ currentItem?.description }}</span
|
||||
>
|
||||
</div>
|
||||
<img class="rounded-[62px]" src="@/assets/images/work/image1.png" alt="" />
|
||||
<img
|
||||
@click="handleImageClick"
|
||||
class="rounded-[62px] cursor-pointer"
|
||||
:src="getStaticImage(currentItem?.image || '')"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 左侧选项切换 -->
|
||||
<div class="absolute right-4 top-32 z-20">
|
||||
<WorkSideSwitcher
|
||||
ref="workSideSwitcherRef"
|
||||
v-model="selected"
|
||||
@change="() => {}"
|
||||
@change="handleSideSwitcherChange"
|
||||
:item-class="'w-[462px] h-[142px] '"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 任务取景按钮 -->
|
||||
<ImgButton class="absolute right-14 bottom-10" :image="IMAGE_PATHS.WORK.TASK_BTN" />
|
||||
<ImgButton
|
||||
class="absolute right-14 bottom-10"
|
||||
:image="isComplete ? IMAGE_PATHS.WORK.TASK_BTN_OK : IMAGE_PATHS.WORK.TASK_BTN"
|
||||
/>
|
||||
|
||||
<!-- 引导与高亮 -->
|
||||
<GuideSteps
|
||||
v-if="status"
|
||||
:steps="steps"
|
||||
:highlight-selector="currentHighlight"
|
||||
:highlight-padding="12"
|
||||
:highlight-radius="20"
|
||||
@step-change="handleStepChange"
|
||||
position-offset-y="85%"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
Reference in new issue
Block a user