feat: 完善课程引导与实战评价体验

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
zhongyidianandClaude Opus 4.7 committed 2026-05-09 09:53:06 +08:00
1 parent 6f8252472f
commit 1f8723aabd
122 files changed
+2595 -1325

No files matched your search

@@ -24,7 +24,13 @@ const handleModalClose = () => {
}
// 自由取景框模式
const { viewfinderContainer, viewfinderBox, viewfinder, startDrag, startResize } = useViewfinderB()
const {
viewfinderContainer,
viewfinderBox,
viewfinder,
startDrag,
startResize,
} = useViewfinderB()
const showGuide = ref(false)
const backgroundImage = ref<HTMLImageElement | null>(null)
@@ -50,7 +56,7 @@ const captureScene = async () => {
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')
}
@@ -72,7 +78,7 @@ const captureScene = async () => {
0, // 目标 x
0, // 目标 y
viewfinder.value.width, // 目标 width
viewfinder.value.height // 目标 height
viewfinder.value.height, // 目标 height
)
},
onComplete: () => {
@@ -80,7 +86,7 @@ const captureScene = async () => {
setTimeout(() => {
showGuide.value = true
}, GUIDE_SHOW_DELAY)
}
},
})
}
@@ -90,7 +96,7 @@ const captureScene = async () => {
const handleComplete = () => {
showGuide.value = false
router.push({
name: 'Interview'
name: 'Interview',
})
}
</script>
@@ -102,7 +108,7 @@ const handleComplete = () => {
:style="{
backgroundImage: start
? getBackgroundImage('interview/shooting/教学楼-清晰.png')
: getBackgroundImage('interview/shooting/教学楼-模糊.png')
: getBackgroundImage('interview/shooting/教学楼-模糊.png'),
}"
>
<!-- 标题 -->
@@ -118,10 +124,17 @@ const handleComplete = () => {
@click="back"
/>
<StartOverlay v-if="!start" @start="start = true" />
<StartOverlay
scene="b"
v-if="!start"
@start="start = true"
/>
<!-- 取景 -->
<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"
@@ -132,14 +145,17 @@ const handleComplete = () => {
/>
<!-- 取景框容器 -->
<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>
<!-- 下遮罩 -->
@@ -147,7 +163,7 @@ const handleComplete = () => {
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>
<!-- 左遮罩 -->
@@ -156,7 +172,7 @@ const handleComplete = () => {
:style="{
top: viewfinder.y + 'px',
width: viewfinder.x + 'px',
height: viewfinder.height + 'px'
height: viewfinder.height + 'px',
}"
></div>
<!-- 右遮罩 -->
@@ -165,7 +181,7 @@ const handleComplete = () => {
:style="{
top: viewfinder.y + 'px',
left: viewfinder.x + viewfinder.width + 'px',
height: viewfinder.height + 'px'
height: viewfinder.height + 'px',
}"
></div>
@@ -177,13 +193,15 @@ const handleComplete = () => {
left: viewfinder.x + 'px',
top: viewfinder.y + 'px',
width: viewfinder.width + 'px',
height: viewfinder.height + 'px'
height: viewfinder.height + 'px',
}"
@mousedown="startDrag"
@touchstart="startDrag"
>
<!-- 九宫格辅助线 -->
<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"
@@ -192,7 +210,7 @@ const handleComplete = () => {
'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>
@@ -226,19 +244,34 @@ const handleComplete = () => {
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>
<!-- 操作按钮 -->
@@ -249,11 +282,20 @@ const handleComplete = () => {
</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>