forked from zhongyidian/super_video
feat: 完善课程引导与实战评价体验
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
6f8252472f
commit
1f8723aabd
122 files changed
+2595
-1325
No files matched your search
@@ -36,14 +36,23 @@ const handleModalClose = () => {
|
||||
}
|
||||
|
||||
// 自由取景框模式
|
||||
const { viewfinderContainer, viewfinderBox, viewfinder, startDrag, startResize } = useViewfinderB()
|
||||
const {
|
||||
viewfinderContainer,
|
||||
viewfinderBox,
|
||||
viewfinder,
|
||||
startDrag,
|
||||
startResize,
|
||||
} = useViewfinderB()
|
||||
|
||||
const handleStartDrag = (event: MouseEvent | TouchEvent): void => {
|
||||
hideInstruction()
|
||||
startDrag(event)
|
||||
}
|
||||
|
||||
const handleStartResize = (direction: ResizeDirection, event: MouseEvent | TouchEvent): void => {
|
||||
const handleStartResize = (
|
||||
direction: ResizeDirection,
|
||||
event: MouseEvent | TouchEvent,
|
||||
): void => {
|
||||
hideInstruction()
|
||||
startResize(direction, event)
|
||||
}
|
||||
@@ -74,7 +83,7 @@ const captureScene = async (): Promise<void> => {
|
||||
height: viewfinder.value.height,
|
||||
scale: CANVAS_SCALE,
|
||||
delay: UI_UPDATE_DELAY,
|
||||
onDraw: ctx => {
|
||||
onDraw: (ctx) => {
|
||||
if (!backgroundImage.value) {
|
||||
throw new Error('Background image not found')
|
||||
}
|
||||
@@ -96,7 +105,7 @@ const captureScene = async (): Promise<void> => {
|
||||
0, // 目标 x
|
||||
0, // 目标 y
|
||||
viewfinder.value.width, // 目标 width
|
||||
viewfinder.value.height // 目标 height
|
||||
viewfinder.value.height, // 目标 height
|
||||
)
|
||||
},
|
||||
onComplete: () => {
|
||||
@@ -104,7 +113,7 @@ const captureScene = async (): Promise<void> => {
|
||||
setTimeout(() => {
|
||||
showGuide.value = true
|
||||
}, GUIDE_SHOW_DELAY)
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -114,7 +123,7 @@ const captureScene = async (): Promise<void> => {
|
||||
const handleComplete = (): void => {
|
||||
showGuide.value = false
|
||||
router.push({
|
||||
name: 'Vlog'
|
||||
name: 'Vlog',
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -126,11 +135,14 @@ const handleComplete = (): void => {
|
||||
:style="{
|
||||
backgroundImage: start
|
||||
? getBackgroundImage('vlog/shooting/沉水栈道-清晰.png')
|
||||
: getBackgroundImage('vlog/shooting/沉水栈道-模糊.png')
|
||||
: getBackgroundImage('vlog/shooting/沉水栈道-模糊.png'),
|
||||
}"
|
||||
>
|
||||
<!-- 标题 -->
|
||||
<ImgButton image="vlog/shooting/沉水栈道侧边.png" class="title-button absolute left-0" />
|
||||
<ImgButton
|
||||
image="vlog/shooting/沉水栈道侧边.png"
|
||||
class="title-button absolute left-0"
|
||||
/>
|
||||
|
||||
<!-- 返回按钮 -->
|
||||
<ImgButton
|
||||
@@ -146,10 +158,17 @@ const handleComplete = (): void => {
|
||||
操作说明:拖动取景框四角调整裁剪范围,点击“取景”键就完成啦!
|
||||
</p>
|
||||
|
||||
<StartOverlay v-if="!start" @start="handleStart" />
|
||||
<StartOverlay
|
||||
scene="b"
|
||||
v-if="!start"
|
||||
@start="handleStart"
|
||||
/>
|
||||
|
||||
<!-- 取景 -->
|
||||
<div class="absolute bottom-0 w-full h-full" v-else>
|
||||
<div
|
||||
class="absolute bottom-0 w-full h-full"
|
||||
v-else
|
||||
>
|
||||
<!-- 隐藏的背景图片,用于 Canvas 绘制 -->
|
||||
<img
|
||||
ref="backgroundImage"
|
||||
@@ -160,14 +179,17 @@ const handleComplete = (): void => {
|
||||
/>
|
||||
|
||||
<!-- 取景框容器 -->
|
||||
<div ref="viewfinderContainer" class="relative w-full h-full">
|
||||
<div
|
||||
ref="viewfinderContainer"
|
||||
class="relative w-full h-full"
|
||||
>
|
||||
<!-- 四个方向的遮罩层 -->
|
||||
<!-- 上遮罩 -->
|
||||
<div
|
||||
class="mask-layer absolute left-0 right-0 bg-black/60 pointer-events-none z-10"
|
||||
:style="{
|
||||
top: 0,
|
||||
height: viewfinder.y + 'px'
|
||||
height: viewfinder.y + 'px',
|
||||
}"
|
||||
></div>
|
||||
<!-- 下遮罩 -->
|
||||
@@ -175,7 +197,7 @@ const handleComplete = (): void => {
|
||||
class="mask-layer absolute left-0 right-0 bg-black/60 pointer-events-none z-10"
|
||||
:style="{
|
||||
top: viewfinder.y + viewfinder.height + 'px',
|
||||
bottom: 0
|
||||
bottom: 0,
|
||||
}"
|
||||
></div>
|
||||
<!-- 左遮罩 -->
|
||||
@@ -184,7 +206,7 @@ const handleComplete = (): void => {
|
||||
:style="{
|
||||
top: viewfinder.y + 'px',
|
||||
width: viewfinder.x + 'px',
|
||||
height: viewfinder.height + 'px'
|
||||
height: viewfinder.height + 'px',
|
||||
}"
|
||||
></div>
|
||||
<!-- 右遮罩 -->
|
||||
@@ -193,7 +215,7 @@ const handleComplete = (): void => {
|
||||
:style="{
|
||||
top: viewfinder.y + 'px',
|
||||
left: viewfinder.x + viewfinder.width + 'px',
|
||||
height: viewfinder.height + 'px'
|
||||
height: viewfinder.height + 'px',
|
||||
}"
|
||||
></div>
|
||||
|
||||
@@ -205,13 +227,15 @@ const handleComplete = (): void => {
|
||||
left: viewfinder.x + 'px',
|
||||
top: viewfinder.y + 'px',
|
||||
width: viewfinder.width + 'px',
|
||||
height: viewfinder.height + 'px'
|
||||
height: viewfinder.height + 'px',
|
||||
}"
|
||||
@mousedown="handleStartDrag"
|
||||
@touchstart="handleStartDrag"
|
||||
>
|
||||
<!-- 九宫格辅助线 -->
|
||||
<div class="grid-lines absolute inset-0 grid grid-cols-3 grid-rows-3">
|
||||
<div
|
||||
class="grid-lines absolute inset-0 grid grid-cols-3 grid-rows-3"
|
||||
>
|
||||
<div
|
||||
v-for="i in 9"
|
||||
:key="i"
|
||||
@@ -220,7 +244,7 @@ const handleComplete = (): void => {
|
||||
'border-t-0': i <= 3,
|
||||
'border-b-0': i >= 7,
|
||||
'border-l-0': (i - 1) % 3 === 0,
|
||||
'border-r-0': i % 3 === 0
|
||||
'border-r-0': i % 3 === 0,
|
||||
}"
|
||||
></div>
|
||||
</div>
|
||||
@@ -254,19 +278,34 @@ const handleComplete = (): void => {
|
||||
class="capture-button-container absolute z-20 -translate-x-1/2 -translate-y-1/2"
|
||||
:style="{
|
||||
left: viewfinder.x + viewfinder.width / 2 + 'px',
|
||||
top: viewfinder.y + viewfinder.height + 'px'
|
||||
top: viewfinder.y + viewfinder.height + 'px',
|
||||
}"
|
||||
>
|
||||
<ImgButton class="w-36" image="shooting/按钮-取景" @click="captureScene" />
|
||||
<ImgButton
|
||||
class="w-36"
|
||||
image="shooting/按钮-取景"
|
||||
@click="captureScene"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 结果弹窗 -->
|
||||
<Overlay :visible="showModal" @close="handleModalClose">
|
||||
<div class="relative w-[1000px] h-[600px] flex items-center justify-center">
|
||||
<Overlay
|
||||
:visible="showModal"
|
||||
@close="handleModalClose"
|
||||
>
|
||||
<div
|
||||
class="relative w-[1000px] h-[600px] flex items-center justify-center"
|
||||
>
|
||||
<!-- 截图内容 -->
|
||||
<div v-if="capturedImageUrl" class="bg-white p-2 rounded-md -rotate-6">
|
||||
<img :src="capturedImageUrl" alt="拍摄结果" />
|
||||
<div
|
||||
v-if="capturedImageUrl"
|
||||
class="bg-white p-2 rounded-md -rotate-6"
|
||||
>
|
||||
<img
|
||||
:src="capturedImageUrl"
|
||||
alt="拍摄结果"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
@@ -277,11 +316,20 @@ const handleComplete = (): void => {
|
||||
</Overlay>
|
||||
</div>
|
||||
|
||||
<LoadingOverlay :visible="isLoading" text="正在出片中..." />
|
||||
<LoadingOverlay
|
||||
:visible="isLoading"
|
||||
text="正在出片中..."
|
||||
/>
|
||||
|
||||
<!-- 引导步骤 -->
|
||||
<GuideSteps v-if="showGuide" positionOffsetY="80%" @complete="handleComplete">
|
||||
<GuideStepsItem>实地取景已全部完成,现在跟着我走进现场开始正式的拍摄吧~</GuideStepsItem>
|
||||
<GuideSteps
|
||||
v-if="showGuide"
|
||||
positionOffsetY="80%"
|
||||
@complete="handleComplete"
|
||||
>
|
||||
<GuideStepsItem>
|
||||
实地取景已全部完成,现在跟着我走进现场开始正式的拍摄吧~
|
||||
</GuideStepsItem>
|
||||
</GuideSteps>
|
||||
</div>
|
||||
</template>
|
||||
Reference in new issue
Block a user