feat(v2.2): 开场剧场与场景面板去文字化(纯语音范围扩展)
- SceneTheater 移除情境字幕块(拼音逐字/「情境」标签/朗读状态), 内容仍自动朗读;删 pairs computed 与 showPinyin prop - play.vue 场景面板移除情境描述 RubyText 与「读一读情境」按钮, 仅保留场景名/emoji/漂浮装饰;SceneTheater 传参同步移除 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -24,30 +24,11 @@
|
||||
<view v-else class="theater-char-avatar" :style="{ background: charColor }">{{ character.name.slice(0, 1) }}</view>
|
||||
<view class="theater-char-mood">🤔</view>
|
||||
</view>
|
||||
|
||||
<!-- 旁白字幕(逐字淡入 + 拼音) -->
|
||||
<view class="theater-sub card">
|
||||
<view class="theater-sub-head">
|
||||
<text class="theater-sub-label">📖 情境</text>
|
||||
<text class="theater-sub-state">{{ speaking ? '正在朗读…' : '' }}</text>
|
||||
</view>
|
||||
<view class="theater-sub-ruby">
|
||||
<view
|
||||
v-for="(ch, i) in pairs"
|
||||
:key="i"
|
||||
class="theater-unit"
|
||||
:style="{ animationDelay: i * 0.05 + 's' }"
|
||||
>
|
||||
<text v-if="ch.p && showPinyin" class="theater-py">{{ ch.p }}</text>
|
||||
<text class="theater-ch">{{ ch.c }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- v2.2 纯语音开场:无情境字幕/拼音(内容仍自动朗读),仅保留场景名 + 道具 + 角色 + 跳过 -->
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { parsePinyin, zipText } from '../utils/pinyin.js'
|
||||
import { propVisual, personVisual } from '../utils/visual.js'
|
||||
import { speak, stopSpeak } from '../utils/speech.js'
|
||||
|
||||
@@ -62,17 +43,13 @@ export default {
|
||||
contentPinyin: { type: String, default: '' },
|
||||
audio: { type: String, default: '' },
|
||||
character: { type: Object, default: null }, // {name, image, id}
|
||||
props: { type: Array, default: () => [] }, // 道具名数组
|
||||
showPinyin: { type: Boolean, default: true }
|
||||
props: { type: Array, default: () => [] } // 道具名数组
|
||||
},
|
||||
emits: ['done'],
|
||||
data() {
|
||||
return { speaking: false }
|
||||
},
|
||||
computed: {
|
||||
pairs() {
|
||||
return zipText(this.content, parsePinyin(this.contentPinyin))
|
||||
},
|
||||
charColor() {
|
||||
return personVisual(this.character && this.character.id ? this.character.id : 0).color
|
||||
}
|
||||
@@ -136,13 +113,4 @@ export default {
|
||||
.theater-char-avatar { width: 160rpx; height: 160rpx; border-radius: 50%; color: #fff; font-size: 72rpx; font-weight: 800; display: flex; align-items: center; justify-content: center; }
|
||||
.theater-char-mood { position: absolute; right: -16rpx; bottom: -16rpx; font-size: 56rpx; }
|
||||
@keyframes char-in { 0% { opacity: 0; transform: translateX(-220rpx); } 70% { transform: translateX(16rpx); } 100% { opacity: 1; transform: translateX(0); } }
|
||||
.theater-sub { margin-top: auto; padding: 32rpx 36rpx; position: relative; z-index: 2; }
|
||||
.theater-sub-head { display: flex; justify-content: space-between; margin-bottom: 12rpx; }
|
||||
.theater-sub-label { font-size: 26rpx; color: #a08c74; font-weight: 700; }
|
||||
.theater-sub-state { font-size: 24rpx; color: #ff6b35; }
|
||||
.theater-sub-ruby { display: flex; flex-wrap: wrap; line-height: 1.9; }
|
||||
.theater-unit { display: flex; flex-direction: column; align-items: center; margin: 0 2rpx; opacity: 0; animation: t-word 0.4s ease forwards; }
|
||||
@keyframes t-word { 0% { opacity: 0; transform: translateY(12rpx); } 100% { opacity: 1; transform: translateY(0); } }
|
||||
.theater-py { font-size: 20rpx; color: #ff6b35; line-height: 1.3; height: 28rpx; }
|
||||
.theater-ch { font-size: 34rpx; line-height: 1.5; color: #5b4636; }
|
||||
</style>
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
:audio="detail.scene_audio"
|
||||
:character="introCharacter"
|
||||
:props="introProps"
|
||||
:show-pinyin="showPinyin"
|
||||
@done="showIntro = false"
|
||||
/>
|
||||
|
||||
@@ -31,7 +30,7 @@
|
||||
<view v-for="i in 6" :key="i" class="dot" :class="{ on: i <= stepCount }"></view>
|
||||
</view>
|
||||
|
||||
<!-- 场景面板:环境 + 情境描述 + 朗读 + 漂浮装饰 -->
|
||||
<!-- 场景面板:环境 + 漂浮装饰(v2.2 移除情境描述文字与朗读按钮,开场已自动朗读) -->
|
||||
<view class="scene-card card" :class="{ 'fx-shake': sceneFx }" :style="{ background: scene.color + '44' }">
|
||||
<image v-if="sceneImg" class="scene-img" :src="sceneImg" mode="aspectFill" />
|
||||
<view class="scene-float f1">☁️</view>
|
||||
@@ -41,8 +40,6 @@
|
||||
<view class="scene-name">{{ detail.scene ? detail.scene.name : '' }}</view>
|
||||
<view v-if="combo > 1" class="combo-badge">🔥 ×{{ combo }}</view>
|
||||
</view>
|
||||
<RubyText class="scene-text" :text="detail.scene_content" :pinyin="detail.scene_content_pinyin" :show="showPinyin" />
|
||||
<SpeakButton class="scene-speak" :text="detail.scene_content" :file="detail.scene_audio" label="读一读情境" />
|
||||
</view>
|
||||
|
||||
<!-- v2.1 终局演绎:结局台词播完自动跳结算 -->
|
||||
@@ -360,8 +357,6 @@ export default {
|
||||
.scene-name { font-size: 32rpx; font-weight: 800; color: #5b4636; }
|
||||
.combo-badge { margin-left: auto; background: #ff6b35; color: #fff; font-weight: 800; border-radius: 30rpx; padding: 8rpx 24rpx; font-size: 28rpx; animation: combo-pop 0.4s ease; }
|
||||
@keyframes combo-pop { 0% { transform: scale(0.4); } 60% { transform: scale(1.2); } 100% { transform: scale(1); } }
|
||||
.scene-text { margin-bottom: 20rpx; position: relative; z-index: 1; }
|
||||
.scene-speak { margin-top: 8rpx; position: relative; z-index: 1; }
|
||||
.node { padding: 48rpx 40rpx; }
|
||||
.node-title { font-size: 38rpx; font-weight: 800; color: #ff6b35; margin-bottom: 24rpx; }
|
||||
.character { display: flex; align-items: center; margin-bottom: 24rpx; }
|
||||
|
||||
Reference in New Issue
Block a user