feat(stage-web): offset for model, use blur for bg
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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'"
|
||||
|
||||
Reference in New Issue
Block a user