feat(stage-web): offset for model, use blur for bg

This commit is contained in:
Neko Ayaka
2025-07-07 00:41:24 +08:00
parent e77608f9aa
commit 7478b5ac65
5 changed files with 46 additions and 9 deletions
@@ -162,12 +162,12 @@ onAfterSend(async () => {
</div>
</label>
</fieldset>
<div h-full max-h="[85vh]" w-full px="12 <md:0" py="4">
<div h-full max-h="[85vh]" w-full py="4">
<div
flex="~ col"
border="solid 4 primary-50 dark:primary-400/20"
border="solid 4 primary-200/20 dark:primary-400/20"
h-full w-full overflow-scroll rounded-xl
bg="white dark:primary-950"
bg="primary-50/50 dark:primary-950/70" backdrop-blur-md
>
<ChatHistory h-full flex-1 p-4 w="full" max-h="<md:[60%]" />
<div h="<md:full" flex gap-2>
@@ -175,7 +175,7 @@ onAfterSend(async () => {
v-model="messageInput"
:placeholder="t('stage.message')"
text="primary-500 hover:primary-600 dark:primary-300/50 dark:hover:primary-500 placeholder:primary-400 placeholder:hover:primary-500 placeholder:dark:primary-300/50 placeholder:dark:hover:primary-500"
bg="primary-50 dark:primary-400/20"
bg="primary-200/20 dark:primary-400/20"
min-h="[100px]" max-h="[300px]" w-full
rounded-t-xl p-4 font-medium
outline-none transition="all duration-250 ease-in-out placeholder:all placeholder:duration-250 placeholder:ease-in-out"
+2 -1
View File
@@ -40,8 +40,9 @@ const positionCursor = useMouse()
x: positionCursor.x.value,
y: positionCursor.y.value,
}"
x-offset="-10%"
/>
<InteractiveArea class="flex <md:hidden" flex-1 max-w="500px" min-w="30%" />
<InteractiveArea class="flex <md:hidden" absolute h="85dvh" right-4 flex-1 max-w="500px" min-w="30%" />
<MobileInteractiveArea class="hidden <md:block" mx2 mb2 @settings-open="handleSettingsOpen" />
</div>
</div>
@@ -16,6 +16,8 @@ withDefaults(defineProps<{
paused: boolean
mouthOpenSize?: number
focusAt: { x: number, y: number }
xOffset?: number | string
yOffset?: number | string
}>(), {
mouthOpenSize: 0,
})
@@ -41,6 +43,8 @@ const { live2dCurrentMotion } = storeToRefs(useSettings())
:height="height"
:paused="paused"
:focus-at="focusAt"
:x-offset="xOffset"
:y-offset="yOffset"
/>
</Live2DCanvas>
<div absolute bottom="3" right="3">
@@ -26,6 +26,8 @@ const props = withDefaults(defineProps<{
paused?: boolean
focusAt?: { x: number, y: number }
disableFocusAt?: boolean
xOffset?: number | string
yOffset?: number | string
}>(), {
mouthOpenSize: 0,
paused: false,
@@ -88,6 +90,27 @@ const {
} = storeToRefs(useSettings())
const currentMotion = ref<{ group: string, index: number }>({ group: 'Idle', index: 0 })
function parsePropsOffset() {
let xOffset = Number.parseFloat(String(props.xOffset)) || 0
let yOffset = Number.parseFloat(String(props.yOffset)) || 0
if (String(props.xOffset).endsWith('%')) {
xOffset = (Number.parseFloat(String(props.xOffset).replace('%', '')) / 100) * props.width
}
if (String(props.yOffset).endsWith('%')) {
yOffset = (Number.parseFloat(String(props.yOffset).replace('%', '')) / 100) * props.height
}
if (Number.isNaN(xOffset))
xOffset = 0
if (Number.isNaN(yOffset))
yOffset = 0
return {
xOffset,
yOffset,
}
}
async function loadModel() {
if (!pixiApp.value)
return
@@ -112,8 +135,10 @@ async function loadModel() {
initialModelWidth.value = model.value.width
initialModelHeight.value = model.value.height
model.value.x = props.width / 2
model.value.y = props.height
const { xOffset, yOffset } = parsePropsOffset()
model.value.x = (props.width / 2) + (xOffset || 0)
model.value.y = props.height + (yOffset || 0)
model.value.anchor.set(0.5, 0.5)
setScale(model)
@@ -210,8 +235,11 @@ async function setMotion(motionName: string, index?: number) {
const handleResize = useDebounceFn(() => {
if (model.value) {
model.value.x = props.width / 2
model.value.y = props.height
const { xOffset, yOffset } = parsePropsOffset()
model.value.x = props.width / 2 + xOffset
model.value.y = props.height + yOffset
setScale(model)
}
}, 100)
@@ -30,6 +30,8 @@ import { useSettings } from '../../stores/settings'
withDefaults(defineProps<{
paused?: boolean
focusAt: { x: number, y: number }
xOffset?: number | string
yOffset?: number | string
}>(), { paused: false })
const db = ref<DuckDBWasmDrizzleDatabase>()
@@ -230,6 +232,8 @@ onMounted(async () => {
:mouth-open-size="mouthOpenSize"
min-w="50% <lg:full" min-h="100 sm:100" h-full w-full flex-1
:paused="paused"
:x-offset="xOffset"
:y-offset="yOffset"
/>
<VRMScene
v-else-if="stageView === '3d'"