perf(stage-web): pause render when settings open (#34)

This commit is contained in:
LemonNeko
2025-02-25 18:19:12 +08:00
committed by GitHub
parent 0a28e0cdb3
commit 856c78f706
7 changed files with 41 additions and 4 deletions
@@ -10,6 +10,10 @@ import { useI18n } from 'vue-i18n'
import MobileChatHistory from '../Widgets/MobileChatHistory.vue'
import MobileSettings from '../Widgets/MobileSettings.vue'
const emit = defineEmits<{
(e: 'settingsOpen', open: boolean): void
}>()
const messageInput = ref('')
const listening = ref(false)
@@ -69,6 +73,10 @@ function handleTranscription(_buffer: Float32Array<ArrayBufferLike>) {
// selectedAudioDevice.value = found
// }
function handleSettingsOpen(open: boolean) {
emit('settingsOpen', open)
}
watch(isAudioInputOn, async (value) => {
if (value === 'false') {
destroy()
@@ -100,7 +108,7 @@ onMounted(() => {
@submit="handleSend"
/>
</div>
<DrawerRoot should-scale-background>
<DrawerRoot should-scale-background @update:open="handleSettingsOpen">
<DrawerTrigger
class="px-4 py-2.5"
border="solid 2 pink-100 dark:pink-400/20"
+8 -2
View File
@@ -1,6 +1,7 @@
<script setup lang="ts">
import { WidgetStage } from '@proj-airi/stage-ui/components'
import { useDark } from '@vueuse/core'
import { ref } from 'vue'
import Cross from '../components/Backgrounds/Cross.vue'
import AnimatedBackground from '../components/Layouts/AnimatedBackground.vue'
@@ -10,6 +11,11 @@ import MobileHeader from '../components/Layouts/MobileHeader.vue'
import MobileInteractiveArea from '../components/Layouts/MobileInteractiveArea.vue'
const dark = useDark()
const paused = ref(false)
function handleSettingsOpen(open: boolean) {
paused.value = open
}
</script>
<template>
@@ -23,9 +29,9 @@ const dark = useDark()
</div>
<!-- page -->
<div relative flex="~ 1 row gap-y-0 gap-x-2 <md:col">
<WidgetStage flex-1 min-w="1/2" />
<WidgetStage flex-1 min-w="1/2" :paused="paused" />
<InteractiveArea class="flex <md:hidden" flex-1 max-w="500px" min-w="30%" />
<MobileInteractiveArea class="hidden <md:block" mx2 mb2 />
<MobileInteractiveArea class="hidden <md:block" mx2 mb2 @settings-open="handleSettingsOpen" />
</div>
</div>
</AnimatedBackground>
@@ -20,11 +20,13 @@ const props = withDefaults(defineProps<{
width: number
height: number
motion?: string
paused: boolean
}>(), {
mouthOpenSize: 0,
})
const pixiApp = toRef(() => props.app)
const paused = toRef(() => props.paused)
const model = ref<Live2DModel>()
const initialModelWidth = ref<number>(0)
const initialModelHeight = ref<number>(0)
@@ -141,6 +143,9 @@ watch(model, updateDropShadowFilter)
watch(mouthOpenSize, value => getCoreModel().setParameterValueById('ParamMouthOpenY', value))
watch(pixiApp, initLive2DPixiStage)
watch(() => props.motion, () => props.motion && setMotion(props.motion))
watch(paused, (value) => {
value ? pixiApp.value?.stop() : pixiApp.value?.start()
})
onMounted(updateDropShadowFilter)
onUnmounted(() => model.value && pixiApp.value?.stage.removeChild(model.value))
@@ -17,6 +17,7 @@ import TransitionVertical from '../TransitionVertical.vue'
withDefaults(defineProps<{
model: string
paused: boolean
mouthOpenSize?: number
}>(), {
mouthOpenSize: 0,
@@ -29,7 +30,7 @@ const show = ref(false)
<template>
<Screen v-slot="{ width, height }" relative>
<Live2DCanvas v-slot="{ app }" :width="width" :height="height">
<Live2DModel :app="app" :model="model" :mouth-open-size="mouthOpenSize" :width="width" :height="height" :motion="motion" />
<Live2DModel :app="app" :model="model" :mouth-open-size="mouthOpenSize" :width="width" :height="height" :motion="motion" :paused="paused" />
</Live2DCanvas>
<div absolute bottom="3" right="3">
<div flex="~ row" cursor-pointer>
@@ -12,6 +12,7 @@ import VRMModel from '../VRM/Model.vue'
const props = defineProps<{
model: string
idleAnimation: string
paused: boolean
}>()
const emit = defineEmits<{
@@ -51,6 +52,7 @@ defineExpose({
:model="props.model"
:idle-animation="props.idleAnimation"
:position="[vrmModelPositionX, vrmModelPositionY, vrmModelPositionZ]"
:paused="props.paused"
@load-model-progress="(val) => emit('loadModelProgress', val)"
@error="(val) => emit('error', val)"
/>
@@ -15,6 +15,7 @@ const props = defineProps<{
idleAnimation: string
loadAnimations?: string[]
position: [number, number, number]
paused: boolean
}>()
const emit = defineEmits<{
@@ -96,6 +97,12 @@ defineExpose({
vrmEmote.value?.setEmotionWithResetAfter(expression, 1000)
},
})
const { pause, resume } = useLoop()
watch(() => props.paused, (value) => {
value ? pause() : resume()
})
</script>
<template>
@@ -22,6 +22,12 @@ import VRMScene from '../Scenes/VRM.vue'
import '../../utils/live2d-zip-loader'
withDefaults(defineProps<{
paused?: boolean
}>(), {
paused: false,
})
const vrmViewerRef = ref<{ setExpression: (expression: string) => void }>()
const motion = ref('')
@@ -212,6 +218,7 @@ onMounted(() => {
:mouth-open-size="mouthOpenSize"
model="./assets/live2d/models/hiyori_pro_zh.zip"
min-w="50% <lg:full" min-h="100 sm:100" h-full w-full flex-1
:paused="paused"
/>
<VRMScene
v-else-if="stageView === '3d'"
@@ -219,6 +226,7 @@ onMounted(() => {
model="/assets/vrm/models/AvatarSample-B/AvatarSample_B.vrm"
idle-animation="/assets/vrm/animations/idle_loop.vrma"
min-w="50% <lg:full" min-h="100 sm:100" h-full w-full flex-1
:paused="paused"
@error="console.error"
/>
</div>