|
@@ -61,6 +61,13 @@
|
|
|
<div class="dialogue-content" v-html="parseMarkdown(currentDialogue.content)"></div>
|
|
<div class="dialogue-content" v-html="parseMarkdown(currentDialogue.content)"></div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
|
|
+ <!-- 诗词显示区域 -->
|
|
|
|
|
+ <div v-if="showPoem" class="poem-display">
|
|
|
|
|
+ <div class="poem-content">
|
|
|
|
|
+ <div class="poem-text" v-html="parseMarkdown(currentPoemContent)"></div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
<!-- 用户输入卡片 -->
|
|
<!-- 用户输入卡片 -->
|
|
|
<div
|
|
<div
|
|
|
v-if="currentDialogue.type === 'user'"
|
|
v-if="currentDialogue.type === 'user'"
|
|
@@ -160,6 +167,10 @@ const voiceRecognizedText = ref("")
|
|
|
const recordingStartCursorPos = ref(0)
|
|
const recordingStartCursorPos = ref(0)
|
|
|
// 录音开始时的原始文本
|
|
// 录音开始时的原始文本
|
|
|
const recordingStartText = ref("")
|
|
const recordingStartText = ref("")
|
|
|
|
|
+// 诗词显示状态
|
|
|
|
|
+const showPoem = ref(false)
|
|
|
|
|
+// 当前诗词内容
|
|
|
|
|
+const currentPoemContent = ref('')
|
|
|
|
|
|
|
|
// 音频对象
|
|
// 音频对象
|
|
|
// 背景音频
|
|
// 背景音频
|
|
@@ -321,6 +332,11 @@ const playDialogueAudio = (isAutoPlay = false) => {
|
|
|
dialogueAudio.value.currentTime = 0
|
|
dialogueAudio.value.currentTime = 0
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 如果是诗词类型,不播放音频
|
|
|
|
|
+ if (currentDialogue.value?.type === 'poem') {
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 播放当前对话的语音
|
|
// 播放当前对话的语音
|
|
|
if (currentDialogue.value?.voiceoverUrl) {
|
|
if (currentDialogue.value?.voiceoverUrl) {
|
|
|
const audio = new Audio(currentDialogue.value.voiceoverUrl)
|
|
const audio = new Audio(currentDialogue.value.voiceoverUrl)
|
|
@@ -343,16 +359,16 @@ const playDialogueAudio = (isAutoPlay = false) => {
|
|
|
// 播放音频
|
|
// 播放音频
|
|
|
audio.play().catch(e => {
|
|
audio.play().catch(e => {
|
|
|
console.error('对话语音播放失败:', e)
|
|
console.error('对话语音播放失败:', e)
|
|
|
- // 播放失败时,2秒后跳转(暂时注销,因为会导致user类型数字人回复播报跳转后语音播报报错,直接2秒跳转)
|
|
|
|
|
- // if (isAutoPlay && isPlaying.value) {
|
|
|
|
|
- // setTimeout(() => {
|
|
|
|
|
- // if (!playNext(true)) {
|
|
|
|
|
- // // 播放完毕
|
|
|
|
|
- // isPlaying.value = false
|
|
|
|
|
- // stopAllAudio()
|
|
|
|
|
- // }
|
|
|
|
|
- // }, 2000)
|
|
|
|
|
- // }
|
|
|
|
|
|
|
+ // 播放失败时,2秒后跳转
|
|
|
|
|
+ if (isAutoPlay && isPlaying.value) {
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ if (!playNext(true)) {
|
|
|
|
|
+ // 播放完毕
|
|
|
|
|
+ isPlaying.value = false
|
|
|
|
|
+ stopAllAudio()
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 2000)
|
|
|
|
|
+ }
|
|
|
})
|
|
})
|
|
|
} else {
|
|
} else {
|
|
|
// 如果没有语音文件,2秒后跳转
|
|
// 如果没有语音文件,2秒后跳转
|
|
@@ -388,8 +404,23 @@ const playSequence = () => {
|
|
|
// 如果当前是用户输入卡片,暂停播放等待用户输入
|
|
// 如果当前是用户输入卡片,暂停播放等待用户输入
|
|
|
if (currentDialogue.value?.type === 'user') return
|
|
if (currentDialogue.value?.type === 'user') return
|
|
|
|
|
|
|
|
- // 播放当前对话语音,传递isAutoPlay参数
|
|
|
|
|
- playDialogueAudio(true)
|
|
|
|
|
|
|
+ // 检查当前对话是否为诗词类型
|
|
|
|
|
+ if (currentDialogue.value?.type === 'poem') {
|
|
|
|
|
+ // 显示诗词并替换内容为最新的诗词
|
|
|
|
|
+ showPoem.value = true
|
|
|
|
|
+ currentPoemContent.value = currentDialogue.value.content
|
|
|
|
|
+ // 自动切换到下一条对话
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ if (!playNext(true)) {
|
|
|
|
|
+ // 播放完毕
|
|
|
|
|
+ isPlaying.value = false
|
|
|
|
|
+ stopAllAudio()
|
|
|
|
|
+ }
|
|
|
|
|
+ }, 500)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 播放当前对话语音,传递isAutoPlay参数
|
|
|
|
|
+ playDialogueAudio(true)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const playPrevious = () => {
|
|
const playPrevious = () => {
|
|
@@ -409,15 +440,28 @@ const playPrevious = () => {
|
|
|
currentSectionIndex.value--
|
|
currentSectionIndex.value--
|
|
|
const section = props.scriptData.sections[currentSectionIndex.value]
|
|
const section = props.scriptData.sections[currentSectionIndex.value]
|
|
|
currentDialogueIndex.value = section.dialogues.length - 1
|
|
currentDialogueIndex.value = section.dialogues.length - 1
|
|
|
|
|
+ // 切换环节时隐藏诗词
|
|
|
|
|
+ showPoem.value = false
|
|
|
|
|
+ currentPoemContent.value = ''
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 检查当前对话是否为诗词类型
|
|
|
|
|
+ if (currentDialogue.value?.type === 'poem') {
|
|
|
|
|
+ // 显示诗词并替换内容为最新的诗词
|
|
|
|
|
+ showPoem.value = true
|
|
|
|
|
+ currentPoemContent.value = currentDialogue.value.content
|
|
|
|
|
+ }
|
|
|
|
|
+ // 如果不是诗词类型,保持诗词显示(不做任何操作)
|
|
|
|
|
+
|
|
|
// 播放背景音
|
|
// 播放背景音
|
|
|
playBackgroundAudio()
|
|
playBackgroundAudio()
|
|
|
- // 播放当前对话语音
|
|
|
|
|
- if (isPlaying.value) {
|
|
|
|
|
- playDialogueAudio(true)
|
|
|
|
|
- } else {
|
|
|
|
|
- playDialogueAudio()
|
|
|
|
|
|
|
+ // 播放当前对话语音(非诗词类型)
|
|
|
|
|
+ if (currentDialogue.value?.type !== 'poem') {
|
|
|
|
|
+ if (isPlaying.value) {
|
|
|
|
|
+ playDialogueAudio(true)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ playDialogueAudio()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -437,6 +481,19 @@ const playNext = (isAutoPlay = false) => {
|
|
|
|
|
|
|
|
if (currentSection.value && currentDialogueIndex.value < currentSection.value.dialogues.length - 1) {
|
|
if (currentSection.value && currentDialogueIndex.value < currentSection.value.dialogues.length - 1) {
|
|
|
currentDialogueIndex.value++
|
|
currentDialogueIndex.value++
|
|
|
|
|
+
|
|
|
|
|
+ // 检查当前对话是否为诗词类型
|
|
|
|
|
+ if (currentDialogue.value?.type === 'poem') {
|
|
|
|
|
+ // 显示诗词并替换内容为最新的诗词
|
|
|
|
|
+ showPoem.value = true
|
|
|
|
|
+ currentPoemContent.value = currentDialogue.value.content
|
|
|
|
|
+ // 自动切换到下一条对话,不需要播放音频
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ playNext(isAutoPlay)
|
|
|
|
|
+ }, 500)
|
|
|
|
|
+ return true
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 根据是否为自动播放状态决定如何播放语音
|
|
// 根据是否为自动播放状态决定如何播放语音
|
|
|
if (isPlaying.value) {
|
|
if (isPlaying.value) {
|
|
|
playDialogueAudio(true)
|
|
playDialogueAudio(true)
|
|
@@ -447,13 +504,27 @@ const playNext = (isAutoPlay = false) => {
|
|
|
} else if (currentSectionIndex.value < props.scriptData.sections.length - 1) {
|
|
} else if (currentSectionIndex.value < props.scriptData.sections.length - 1) {
|
|
|
currentSectionIndex.value++
|
|
currentSectionIndex.value++
|
|
|
currentDialogueIndex.value = 0
|
|
currentDialogueIndex.value = 0
|
|
|
|
|
+ // 切换环节时隐藏诗词
|
|
|
|
|
+ showPoem.value = false
|
|
|
|
|
+ currentPoemContent.value = ''
|
|
|
// 播放背景音
|
|
// 播放背景音
|
|
|
playBackgroundAudio()
|
|
playBackgroundAudio()
|
|
|
- // 根据是否为自动播放状态决定如何播放语音
|
|
|
|
|
- if (isPlaying.value) {
|
|
|
|
|
- playDialogueAudio(true)
|
|
|
|
|
|
|
+ // 检查新环节的第一个对话是否为诗词类型
|
|
|
|
|
+ if (currentDialogue.value?.type === 'poem') {
|
|
|
|
|
+ // 显示诗词
|
|
|
|
|
+ showPoem.value = true
|
|
|
|
|
+ currentPoemContent.value = currentDialogue.value.content
|
|
|
|
|
+ // 自动切换到下一条对话,不需要播放音频
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ playNext(isAutoPlay)
|
|
|
|
|
+ }, 500)
|
|
|
} else {
|
|
} else {
|
|
|
- playDialogueAudio()
|
|
|
|
|
|
|
+ // 根据是否为自动播放状态决定如何播放语音
|
|
|
|
|
+ if (isPlaying.value) {
|
|
|
|
|
+ playDialogueAudio(true)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ playDialogueAudio()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
return true
|
|
return true
|
|
|
}
|
|
}
|
|
@@ -479,8 +550,20 @@ const startPlayback = () => {
|
|
|
showMask.value = false
|
|
showMask.value = false
|
|
|
}, 500)
|
|
}, 500)
|
|
|
}
|
|
}
|
|
|
- // 播放当前对话语音
|
|
|
|
|
- playDialogueAudio()
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 检查当前对话是否为诗词类型
|
|
|
|
|
+ if (currentDialogue.value?.type === 'poem') {
|
|
|
|
|
+ // 显示诗词
|
|
|
|
|
+ showPoem.value = true
|
|
|
|
|
+ currentPoemContent.value = currentDialogue.value.content
|
|
|
|
|
+ // 自动切换到下一条对话
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ playNext()
|
|
|
|
|
+ }, 500)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 播放当前对话语音
|
|
|
|
|
+ playDialogueAudio()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 键盘事件处理,键盘左右箭头控制对话
|
|
// 键盘事件处理,键盘左右箭头控制对话
|
|
@@ -538,6 +621,9 @@ watch(() => props.scriptData, (newVal, oldVal) => {
|
|
|
userInput.value = ''
|
|
userInput.value = ''
|
|
|
// 清空对话缓存
|
|
// 清空对话缓存
|
|
|
currentDialogueCache.value = null
|
|
currentDialogueCache.value = null
|
|
|
|
|
+ // 隐藏诗词
|
|
|
|
|
+ showPoem.value = false
|
|
|
|
|
+ currentPoemContent.value = ''
|
|
|
}
|
|
}
|
|
|
}, { deep: true })
|
|
}, { deep: true })
|
|
|
|
|
|
|
@@ -1524,8 +1610,114 @@ onUnmounted(() => {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
.keyboard-icon {
|
|
.keyboard-icon {
|
|
|
- font-size: rpx(14);
|
|
|
|
|
- color: #0064BE;
|
|
|
|
|
|
|
+ font-size: rpx(14);
|
|
|
|
|
+ color: #0064BE;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+/* 诗词显示样式 */
|
|
|
|
|
+.poem-display {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 25%;
|
|
|
|
|
+ left: 50%;
|
|
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ max-width: rpx(600);
|
|
|
|
|
+ padding: rpx(20);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ z-index: 5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.poem-content {
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ animation: poemFadeIn 1s ease-in-out;
|
|
|
|
|
+ transition: all 0.5s ease-in-out;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.poem-text {
|
|
|
|
|
+ font-family: 'STKaiti', 'KaiTi', '楷体', 'Ma Shan Zheng', cursive;
|
|
|
|
|
+ font-size: rpx(30);
|
|
|
|
|
+ line-height: 1.5;
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
|
|
|
|
|
+ padding: rpx(20);
|
|
|
|
|
+ background-color: #ffffff1a;
|
|
|
|
|
+ border-radius: rpx(10);
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ overflow: hidden;
|
|
|
|
|
+ transition: all 0.5s ease-in-out;
|
|
|
|
|
+ white-space: nowrap;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.poem-text::before {
|
|
|
|
|
+ content: '';
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ right: 0;
|
|
|
|
|
+ bottom: 0;
|
|
|
|
|
+ background: linear-gradient(45deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 255, 255, 0) 100%);
|
|
|
|
|
+ animation: poemShine 3s ease-in-out infinite;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@keyframes poemFadeIn {
|
|
|
|
|
+ from {
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ transform: scale(0.8) translateY(20px);
|
|
|
|
|
+ }
|
|
|
|
|
+ to {
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+ transform: scale(1) translateY(0);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@keyframes poemShine {
|
|
|
|
|
+ 0% {
|
|
|
|
|
+ transform: translateX(-100%) rotate(45deg);
|
|
|
|
|
+ }
|
|
|
|
|
+ 100% {
|
|
|
|
|
+ transform: translateX(100%) rotate(45deg);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.poem-text p {
|
|
|
|
|
+ margin: rpx(10) 0;
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ animation: poemSlideIn 0.5s ease forwards;
|
|
|
|
|
+ font-weight: 500;
|
|
|
|
|
+ letter-spacing: rpx(2);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.poem-text p:nth-child(1) {
|
|
|
|
|
+ animation-delay: 0.2s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.poem-text p:nth-child(2) {
|
|
|
|
|
+ animation-delay: 0.4s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.poem-text p:nth-child(3) {
|
|
|
|
|
+ animation-delay: 0.6s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.poem-text p:nth-child(4) {
|
|
|
|
|
+ animation-delay: 0.8s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.poem-text p:nth-child(5) {
|
|
|
|
|
+ animation-delay: 1s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+@keyframes poemSlideIn {
|
|
|
|
|
+ from {
|
|
|
|
|
+ opacity: 0;
|
|
|
|
|
+ transform: translateY(10px);
|
|
|
|
|
+ }
|
|
|
|
|
+ to {
|
|
|
|
|
+ opacity: 1;
|
|
|
|
|
+ transform: translateY(0);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
</style>
|
|
</style>
|