mirror of
https://github.com/moeru-ai/airi.git
synced 2026-07-10 00:08:33 +00:00
feat: add live2d rendering resolution scaling slider
This commit is contained in:
parent
4c9564f4b9
commit
27dad69041
8 changed files with 49 additions and 2 deletions
|
|
@ -127,6 +127,9 @@ live2d:
|
|||
description: Limit rendering frame rate
|
||||
options:
|
||||
unlimited: ∞
|
||||
resolution-scaling:
|
||||
title: Rendering Resolution Scale
|
||||
description: Adjust Live2D render resolution scaling (base 2x)
|
||||
microphone: Microphone
|
||||
models: Model
|
||||
pages:
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ live2d:
|
|||
description: 限制渲染帧率
|
||||
options:
|
||||
unlimited: '∞'
|
||||
resolution-scaling:
|
||||
title: 渲染分辨率缩放
|
||||
description: 调整 Live2D 渲染分辨率缩放(基础为 2x)
|
||||
microphone: 麦克风
|
||||
models: 模型
|
||||
pages:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { Screen } from '@proj-airi/ui'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ref, watch } from 'vue'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import Live2DCanvas from './live2d/Canvas.vue'
|
||||
import Live2DModel from './live2d/Model.vue'
|
||||
|
|
@ -28,6 +28,7 @@ withDefaults(defineProps<{
|
|||
live2dExpressionEnabled?: boolean
|
||||
live2dShadowEnabled?: boolean
|
||||
live2dMaxFps?: number
|
||||
live2dResolutionScaling?: number
|
||||
}>(), {
|
||||
paused: false,
|
||||
focusAt: () => ({ x: 0, y: 0 }),
|
||||
|
|
@ -41,6 +42,7 @@ withDefaults(defineProps<{
|
|||
live2dExpressionEnabled: true,
|
||||
live2dShadowEnabled: true,
|
||||
live2dMaxFps: 0,
|
||||
live2dResolutionScaling: 1,
|
||||
})
|
||||
|
||||
const componentState = defineModel<'pending' | 'loading' | 'mounted'>('state', { default: 'pending' })
|
||||
|
|
@ -51,6 +53,7 @@ const live2dCanvasRef = ref<InstanceType<typeof Live2DCanvas>>()
|
|||
|
||||
const live2d = useLive2d()
|
||||
const { position } = storeToRefs(live2d)
|
||||
const live2dCanvasResolution = computed(() => Math.max(0.5, props.live2dResolutionScaling) * 2)
|
||||
|
||||
watch([componentStateModel, componentStateCanvas], () => {
|
||||
componentState.value = (componentStateModel.value === 'mounted' && componentStateCanvas.value === 'mounted')
|
||||
|
|
@ -73,7 +76,7 @@ defineExpose({
|
|||
v-model:state="componentStateCanvas"
|
||||
:width="width"
|
||||
:height="height"
|
||||
:resolution="2"
|
||||
:resolution="live2dCanvasResolution"
|
||||
:max-fps="live2dMaxFps"
|
||||
max-h="100dvh"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ const {
|
|||
live2dExpressionEnabled,
|
||||
live2dShadowEnabled,
|
||||
live2dMaxFps,
|
||||
live2dResolutionScaling,
|
||||
} = storeToRefs(settings)
|
||||
|
||||
const live2d = useLive2d()
|
||||
|
|
@ -338,6 +339,35 @@ function handleMotionSelect(selectedMotionPath: string | number | undefined) {
|
|||
</div>
|
||||
</label>
|
||||
|
||||
<FieldRange
|
||||
v-model="live2dResolutionScaling"
|
||||
as="div"
|
||||
:min="0.5"
|
||||
:max="2"
|
||||
:step="0.05"
|
||||
:label="t('settings.live2d.resolution-scaling.title')"
|
||||
>
|
||||
<template #label>
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex-1">
|
||||
<div class="text-sm font-medium">
|
||||
{{ t('settings.live2d.resolution-scaling.title') }}
|
||||
</div>
|
||||
<div class="text-xs text-neutral-500 dark:text-neutral-400">
|
||||
{{ t('settings.live2d.resolution-scaling.description') }}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
class="px-2 text-xs outline-none"
|
||||
title="Reset value to default"
|
||||
@click="() => live2dResolutionScaling = 1"
|
||||
>
|
||||
<div class="i-solar:forward-linear transform-scale-x--100 text-neutral-500 dark:text-neutral-400" />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</FieldRange>
|
||||
|
||||
<div mt-4 flex items-center justify-between>
|
||||
<span text-sm text-neutral-600 dark:text-neutral-400>Auto Blink</span>
|
||||
<Checkbox v-model="live2dAutoBlinkEnabled" />
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ const {
|
|||
live2dForceAutoBlinkEnabled,
|
||||
live2dShadowEnabled,
|
||||
live2dMaxFps,
|
||||
live2dResolutionScaling,
|
||||
} = storeToRefs(settingsStore)
|
||||
const { scale: live2dScale } = storeToRefs(live2dStore)
|
||||
const { sceneMutationLocked, scenePhase } = storeToRefs(modelStore)
|
||||
|
|
@ -136,6 +137,7 @@ defineExpose({
|
|||
:live2d-force-auto-blink-enabled="live2dForceAutoBlinkEnabled"
|
||||
:live2d-shadow-enabled="live2dShadowEnabled"
|
||||
:live2d-max-fps="live2dMaxFps"
|
||||
:live2d-resolution-scaling="live2dResolutionScaling"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ const {
|
|||
live2dExpressionEnabled,
|
||||
live2dShadowEnabled,
|
||||
live2dMaxFps,
|
||||
live2dResolutionScaling,
|
||||
} = storeToRefs(settingsStore)
|
||||
const { mouthOpenSize } = storeToRefs(useSpeakingStore())
|
||||
const { audioContext } = useAudioContext()
|
||||
|
|
@ -588,6 +589,7 @@ defineExpose({
|
|||
:live2d-expression-enabled="live2dExpressionEnabled"
|
||||
:live2d-shadow-enabled="live2dShadowEnabled"
|
||||
:live2d-max-fps="live2dMaxFps"
|
||||
:live2d-resolution-scaling="live2dResolutionScaling"
|
||||
/>
|
||||
<ThreeScene
|
||||
v-if="stageModelRenderer === 'vrm' && showStage"
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ export const useSettings = defineStore('settings', () => {
|
|||
live2dExpressionEnabled: live2dRefs.live2dExpressionEnabled,
|
||||
live2dShadowEnabled: live2dRefs.live2dShadowEnabled,
|
||||
live2dMaxFps: live2dRefs.live2dMaxFps,
|
||||
live2dResolutionScaling: live2dRefs.live2dResolutionScaling,
|
||||
|
||||
// Theme settings
|
||||
themeColorsHue: themeRefs.themeColorsHue,
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ export const useSettingsLive2d = defineStore('settings-live2d', () => {
|
|||
const live2dExpressionEnabled = useLocalStorageManualReset<boolean>('settings/live2d/expression-enabled', false)
|
||||
const live2dShadowEnabled = useLocalStorageManualReset<boolean>('settings/live2d/shadow-enabled', true)
|
||||
const live2dMaxFps = useLocalStorageManualReset<number>('settings/live2d/max-fps', 0)
|
||||
const live2dResolutionScaling = useLocalStorageManualReset<number>('settings/live2d/resolution-scaling', 1)
|
||||
|
||||
function resetState() {
|
||||
live2dDisableFocus.reset()
|
||||
|
|
@ -36,6 +37,7 @@ export const useSettingsLive2d = defineStore('settings-live2d', () => {
|
|||
live2dExpressionEnabled.reset()
|
||||
live2dShadowEnabled.reset()
|
||||
live2dMaxFps.reset()
|
||||
live2dResolutionScaling.reset()
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
@ -46,6 +48,7 @@ export const useSettingsLive2d = defineStore('settings-live2d', () => {
|
|||
live2dExpressionEnabled,
|
||||
live2dShadowEnabled,
|
||||
live2dMaxFps,
|
||||
live2dResolutionScaling,
|
||||
resetState,
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue