chore: new ui

This commit is contained in:
Neko Ayaka
2024-12-17 00:10:16 +08:00
parent b66eb6a235
commit eb59e7b5aa
7 changed files with 351 additions and 145 deletions
@@ -0,0 +1,26 @@
<template>
<div class="cross-background-container">
<slot />
</div>
</template>
<style lang="css" scoped>
/*
CSS Background Patterns by MagicPattern
https://www.magicpattern.design/tools/css-backgrounds
*/
.cross-background-container {
background-color: #ffffff;
opacity: 0.8;
background:
radial-gradient(circle, transparent 20%, #ffffff 20%, #ffffff 80%, transparent 80%, transparent),
radial-gradient(circle, transparent 20%, #ffffff 20%, #ffffff 80%, transparent 80%, transparent) 25px 25px,
linear-gradient(var(--airi-theme-primary-500) 2px, transparent 2px) 0 -1px,
linear-gradient(90deg, var(--airi-theme-primary-500) 2px, #ffffff 2px) -1px 0;
background-size:
50px 50px,
50px 50px,
25px 25px,
25px 25px;
}
</style>
@@ -0,0 +1,46 @@
<template>
<div class="cross-blocks-background-container">
<slot />
</div>
</template>
<style scoped>
/*
CSS pattern backgrounds by Super designer
https://superdesigner.co/tools/css-backgrounds
*/
.cross-blocks-background-container {
background: linear-gradient(
45deg,
var(--airi-theme-primary-200) 10%,
transparent 11%,
transparent 89%,
var(--airi-theme-primary-200) 90%
),
linear-gradient(
135deg,
var(--airi-theme-primary-200) 10%,
transparent 11%,
transparent 89%,
var(--airi-theme-primary-200) 90%
),
radial-gradient(circle, transparent 25%, #ffffff 26%),
linear-gradient(
45deg,
transparent 46%,
var(--airi-theme-primary-200) 47%,
var(--airi-theme-primary-200) 52%,
transparent 53%
),
linear-gradient(
135deg,
transparent 46%,
var(--airi-theme-primary-200) 47%,
var(--airi-theme-primary-200) 52%,
transparent 53%
);
background-size: 3em 3em;
background-color: #ffffff;
opacity: 1;
}
</style>
@@ -0,0 +1,16 @@
<template>
<div class="line-1-background-container">
<slot />
</div>
</template>
<style lang="css" scoped>
/*
Pattern Monster - SVG Pattern Generator
https://pattern.monster/
*/
.line-1-background-container {
background-image: url("data:image/svg+xml,<svg id='patternId' width='100%' height='100%' xmlns='http://www.w3.org/2000/svg'><defs><pattern id='a' patternUnits='userSpaceOnUse' width='40' height='40' patternTransform='scale(8) rotate(45)'><rect x='0' y='0' width='100%' height='100%' fill='%23ffffffff'/><path d='M20-5V5m0 30v10m20-30v10M0 15v10' stroke-linejoin='round' stroke-linecap='round' stroke-width='2' stroke='%23eee7e9ff' fill='none'/><path d='M-5 40H5M-5 0H5m30 0h10M35 40h10M15 20h10' stroke-linejoin='round' stroke-linecap='round' stroke-width='2' stroke='%23efbcceff' fill='none'/></pattern></defs><rect width='800%' height='800%' transform='translate(-488,-456)' fill='url(%23a)'/></svg>");
}
</style>
@@ -0,0 +1,36 @@
<template>
<div class="tic-tac-toe-background-container">
<slot />
</div>
</template>
<style scoped>
/*
Hero Patterns | Free repeatable SVG background patterns for your web projects
https://heropatterns.com/
*/
.tic-tac-toe-background-container {
background-color: #ffffff;
background-image: url("data:image/svg+xml,%3Csvg width='64' height='64' viewBox='0 0 64 64' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 16c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm0-2c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6zm33.414-6l5.95-5.95L45.95.636 40 6.586 34.05.636 32.636 2.05 38.586 8l-5.95 5.95 1.414 1.414L40 9.414l5.95 5.95 1.414-1.414L41.414 8zM40 48c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm0-2c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6zM9.414 40l5.95-5.95-1.414-1.414L8 38.586l-5.95-5.95L.636 34.05 6.586 40l-5.95 5.95 1.414 1.414L8 41.414l5.95 5.95 1.414-1.414L9.414 40z' fill='%23ffcfe1' fill-opacity='0.4' fill-rule='evenodd'/%3E%3C/svg%3E");
background-position: 0 0;
position: relative;
overflow: hidden;
cursor: pointer;
transform: scale(1);
transition: transform 0.3s ease;
}
.tic-tac-toe-background-container:hover {
transform: scale(1.02);
animation: slideBackground 2s linear infinite;
}
@keyframes slideBackground {
0% {
background-position: 0 0;
}
100% {
background-position: 64px -64px; /* Match the SVG size for smooth looping */
}
}
</style>
+79 -43
View File
@@ -1,4 +1,5 @@
<script setup lang="ts">
import { ref } from 'vue'
import {
EmotionAngryMotionName,
EmotionAwkwardMotionName,
@@ -22,6 +23,7 @@ withDefaults(defineProps<{
const modelRef = ref<{
setMotion: (motionName: string) => Promise<void>
}>()
const show = ref(false)
defineExpose({
setMotion: async (motionName: string): Promise<void> => {
@@ -33,51 +35,85 @@ defineExpose({
<template>
<Screen v-slot="{ width, height }" relative>
<Live2DViewer ref="modelRef" :canvas-width="width" :canvas-height="height" :model="model" :mouth-open-size="mouthOpenSize" />
<div z="10" bottom="2" absolute w-full flex="~ col" gap-2>
<div flex="~ row" w-full flex-wrap gap-2>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionSurpriseMotionName)"
<div absolute top="2">
<div
flex="~ row"
bg="zinc-100 dark:zinc-700"
text="sm zinc-400 dark:zinc-500"
h-fit w-fit appearance-none gap-1 rounded-lg rounded-md border-none
>
<label
h-fit cursor-pointer
:class="[show ? 'bg-zinc-300 text-zinc-900 dark:bg-zinc-200 dark:text-zinc-800' : '']"
transition="all ease-in-out duration-500"
rounded-md px-2 py-2
>
🤯 Surprised
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionSadMotionName)"
>
😫 Sad
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionAngryMotionName)"
>
😠 Angry
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionHappyMotionName)"
>
😄 Happy
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionAwkwardMotionName)"
>
😳 Awkward
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionQuestionMotionName)"
>
🤔 Question
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionThinkMotionName)"
>
🤨 Think
</button>
<input
v-model="show"
:checked="show"
:aria-checked="show"
name="showLive2DViewerInspector"
type="checkbox"
hidden appearance-none outline-none
>
<div select-none>
<div i-solar:bug-bold-duotone text="text-zinc-900 dark:text-zinc-800" />
</div>
</label>
</div>
<TransitionVertical>
<div v-if="show" absolute w-full top="10" min-w="50vw">
<div bg="zinc-200/20 dark:black/20" rounded-lg p-2 backdrop-blur-sm>
<div font-mono>
<span>Emotions</span>
</div>
<div flex="~ row" flex-wrap gap-2>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionSurpriseMotionName)"
>
🤯 Surprised
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionSadMotionName)"
>
😫 Sad
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionAngryMotionName)"
>
😠 Angry
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionHappyMotionName)"
>
😄 Happy
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionAwkwardMotionName)"
>
😳 Awkward
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionQuestionMotionName)"
>
🤔 Question
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setMotion(EmotionThinkMotionName)"
>
🤨 Think
</button>
</div>
</div>
</div>
</TransitionVertical>
</div>
</Screen>
</template>
+139 -102
View File
@@ -16,6 +16,8 @@ const emit = defineEmits<{
(e: 'error', value: unknown): void
}>()
const show = ref(false)
const cameraPositionX = ref(-0.17)
const cameraPositionY = ref(0)
const cameraPositionZ = ref(-1)
@@ -50,114 +52,149 @@ defineExpose({
@error="(val) => emit('error', val)"
/>
</TresCanvas>
<div z="10" bottom="2" absolute w-full flex="~ col" gap-2>
<div w-full flex="~ col md:row" gap-2>
<Collapsable h-fit w-full>
<template #label>
<span font-mono>Camera</span>
</template>
<div grid="~ cols-[20px_1fr_60px]" w-full gap-1 p-2 text-sm font-mono>
<div text="zinc-400 dark:zinc-500">
<span>X</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="cameraPositionX" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ cameraPositionX }}</span>
<div absolute top="2">
<div
flex="~ row"
bg="zinc-100 dark:zinc-700"
text="sm zinc-400 dark:zinc-500"
h-fit w-fit appearance-none gap-1 rounded-lg rounded-md border-none
>
<label
h-fit cursor-pointer
:class="[show ? 'bg-zinc-300 text-zinc-900 dark:bg-zinc-200 dark:text-zinc-800' : '']"
transition="all ease-in-out duration-500"
rounded-md px-2 py-2
>
<input
v-model="show"
:checked="show"
:aria-checked="show"
name="showLive2DViewerInspector"
type="checkbox"
hidden appearance-none outline-none
>
<div select-none>
<div i-solar:bug-bold-duotone text="text-zinc-900 dark:text-zinc-800" />
</div>
</label>
</div>
<TransitionVertical>
<div v-if="show" absolute w-full top="10" min-w="50vw">
<div bg="zinc-200/20 dark:black/20" flex="~ col" gap-2 rounded-lg p-2 backdrop-blur-sm>
<div font-mono>
<span>Model</span>
</div>
<Collapsable h-fit w-full>
<template #label>
<span font-mono>Camera</span>
</template>
<div grid="~ cols-[20px_1fr_60px]" w-full gap-1 p-2 text-sm font-mono>
<div text="zinc-400 dark:zinc-500">
<span>X</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="cameraPositionX" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ cameraPositionX }}</span>
</div>
<div text="zinc-400 dark:zinc-500">
<span>Y</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="cameraPositionY" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ cameraPositionY }}</span>
</div>
<div text="zinc-400 dark:zinc-500">
<span>Y</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="cameraPositionY" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ cameraPositionY }}</span>
</div>
<div text="zinc-400 dark:zinc-500">
<span>Z</span>
<div text="zinc-400 dark:zinc-500">
<span>Z</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="cameraPositionZ" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ cameraPositionZ }}</span>
</div>
</div>
</Collapsable>
<Collapsable h-fit w-full>
<template #label>
<span font-mono>Model</span>
</template>
<div grid="~ cols-[20px_1fr_60px]" w-full gap-1 p-2 text-sm font-mono>
<div text="zinc-400 dark:zinc-500">
<span>X</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="vrmModelPositionX" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ vrmModelPositionX }}</span>
</div>
<div text="zinc-400 dark:zinc-500">
<span>Y</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="vrmModelPositionY" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ vrmModelPositionY }}</span>
</div>
<div text="zinc-400 dark:zinc-500">
<span>Z</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="vrmModelPositionZ" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ vrmModelPositionZ }}</span>
</div>
</div>
</Collapsable>
<div font-mono>
<span>Emotions</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="cameraPositionZ" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ cameraPositionZ }}</span>
<div flex="~ row" w-full flex-wrap gap-2>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('neutral')"
>
🙂 Neutral
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('surprised')"
>
🤯 Surprised
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('sad')"
>
😫 Sad
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('angry')"
>
😠 Angry
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('happy')"
>
😄 Happy
</button>
</div>
</div>
</Collapsable>
<Collapsable h-fit w-full>
<template #label>
<span font-mono>Model</span>
</template>
<div grid="~ cols-[20px_1fr_60px]" w-full gap-1 p-2 text-sm font-mono>
<div text="zinc-400 dark:zinc-500">
<span>X</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="vrmModelPositionX" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ vrmModelPositionX }}</span>
</div>
<div text="zinc-400 dark:zinc-500">
<span>Y</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="vrmModelPositionY" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ vrmModelPositionY }}</span>
</div>
<div text="zinc-400 dark:zinc-500">
<span>Z</span>
</div>
<label w-full flex items-center gap-2>
<DataGuiRange v-model="vrmModelPositionZ" :min="-10" :max="10" :step="0.01" />
</label>
<div text-right>
<span>{{ vrmModelPositionZ }}</span>
</div>
</div>
</Collapsable>
</div>
<div flex="~ row" w-full flex-wrap gap-2>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('neutral')"
>
🙂 Neutral
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('surprised')"
>
🤯 Surprised
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('sad')"
>
😫 Sad
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('angry')"
>
😠 Angry
</button>
<button
rounded-lg bg="zinc-100/70 dark:zinc-800/50" px-2 py-1 backdrop-blur-sm
@click="modelRef?.setExpression('happy')"
>
😄 Happy
</button>
</div>
</div>
</TransitionVertical>
</div>
</Screen>
</template>
+9
View File
@@ -1,4 +1,8 @@
<script setup lang="ts">
// import BackgroundCross from '../components/Backgrounds/Cross.vue'
// import BackgroundCrossBlocks from '../components/Backgrounds/CrossBlocks.vue'
import BackgroundTicTacToe from '../components/Backgrounds/TicTacToe.vue'
// import BackgroundLine1 from '../components/Backgrounds/Line1.vue'
import Header from '../components/Layouts/Header.vue'
import ChatHistory from '../components/Widgets/ChatHistory.vue'
import Stage from '../components/Widgets/Stage.vue'
@@ -9,6 +13,11 @@ import Stage from '../components/Widgets/Stage.vue'
<Header />
<div flex="~ row 1" max-h="" relative h-full w-full items-end gap-2>
<Stage />
<BackgroundTicTacToe border="solid 2 pink-500" overflow-hidden rounded-full px-5 py-2>
<div>
ABCD
</div>
</BackgroundTicTacToe>
<ChatHistory />
</div>
</div>