From fa4df28c220d95adcbcee9e0c5fff37121793429 Mon Sep 17 00:00:00 2001 From: Soulter <905617992@qq.com> Date: Sun, 18 Jan 2026 17:07:19 +0800 Subject: [PATCH] feat: nervous --- dashboard/src/components/chat/LiveMode.vue | 11 ++- dashboard/src/components/chat/LiveOrb.vue | 80 ++++++++++++++++++++-- 2 files changed, 84 insertions(+), 7 deletions(-) diff --git a/dashboard/src/components/chat/LiveMode.vue b/dashboard/src/components/chat/LiveMode.vue index b7ee8b94f..dc2e65473 100644 --- a/dashboard/src/components/chat/LiveMode.vue +++ b/dashboard/src/components/chat/LiveMode.vue @@ -4,6 +4,8 @@ +
@@ -11,8 +13,8 @@
- +
{{ statusText }} @@ -68,6 +70,7 @@ const vadRecording = useVADRecording(); const isActive = ref(false); // Live Mode 是否激活 const isExploding = ref(false); // 是否正在展示爆炸动画 const isCodeMode = ref(false); // 是否开启代码模式 +const isNervousMode = ref(false); // 是否开启紧张模式 // 使用 VAD 提供的 isSpeaking 状态 const isSpeaking = computed(() => vadRecording.isSpeaking.value); const isListening = ref(false); // 是否在监听 @@ -523,6 +526,10 @@ function toggleCodeMode() { isCodeMode.value = !isCodeMode.value; } +function toggleNervousMode() { + isNervousMode.value = !isNervousMode.value; +} + // 监听用户打断 watch(isSpeaking, (newVal) => { if (newVal && isPlaying.value) { diff --git a/dashboard/src/components/chat/LiveOrb.vue b/dashboard/src/components/chat/LiveOrb.vue index 1425edfa2..175f18c29 100644 --- a/dashboard/src/components/chat/LiveOrb.vue +++ b/dashboard/src/components/chat/LiveOrb.vue @@ -3,20 +3,34 @@
-
+
+ +
+ + + +
+ -
+
{{ col.content }}
-
+
+ +
+ + + +
+ -
+
{{ col.content }}
@@ -24,6 +38,15 @@
+ + +
+ + + +
@@ -35,6 +58,7 @@ const props = defineProps<{ mode: 'idle' | 'listening' | 'speaking' | 'processing'; isDark?: boolean; codeMode?: boolean; + nervousMode?: boolean; }>(); // 内部状态 @@ -197,6 +221,7 @@ const scheduleBlink = () => { }; const triggerBlink = () => { + if (props.nervousMode) return; isBlinking.value = true; setTimeout(() => { isBlinking.value = false; @@ -353,7 +378,7 @@ const styleVars = computed(() => { .eyes-container { position: absolute; display: flex; - gap: 55px; + gap: 60px; z-index: 5; /* Center it */ top: 42%; @@ -378,6 +403,22 @@ const styleVars = computed(() => { transform: scaleY(0.1); } +.eye.nervous { + background-color: transparent; + display: flex; + align-items: center; + justify-content: center; + box-shadow: none; +} + +.nervous-eye-content { + width: 100%; + height: 100%; + display: flex; + align-items: center; + justify-content: center; +} + .code-rain-container { position: absolute; top: 0; @@ -421,4 +462,33 @@ const styleVars = computed(() => { .fade-leave-to { opacity: 0; } + +.accessory-star { + position: absolute; + width: 15px; + height: 15px; + top: 20%; + right: 20%; + transform: rotate(5deg); + z-index: -100; + opacity: 0.8; + filter: drop-shadow(0 0 5px rgba(180, 182, 255, 0.4)); + animation: starFloat 4s ease-in-out infinite; + pointer-events: none; + mix-blend-mode: screen; +} + +@keyframes starFloat { + + 0%, + 100% { + transform: rotate(5deg) translateY(0) scale(1); + opacity: 0.3; + } + + 50% { + transform: rotate(10deg) translateY(-3px) scale(1.05); + opacity: 0.5; + } +}