1
This commit is contained in:
@@ -7,14 +7,8 @@
|
||||
<div class="digital-avatar" :class="{ speaking: isAISpeaking, thinking: isAIThinking }">
|
||||
<div class="avatar-face">
|
||||
<div class="avatar-eyes">
|
||||
<div class="eye left-eye" :class="{ blink: isBlinking }"
|
||||
:style="{ transform: `translate(${eyeOffsetX}px, ${eyeOffsetY}px)` }">
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye right-eye" :class="{ blink: isBlinking }"
|
||||
:style="{ transform: `translate(${eyeOffsetX}px, ${eyeOffsetY}px)` }">
|
||||
<div class="pupil"></div>
|
||||
</div>
|
||||
<div class="eye left-eye" :class="{ blink: isBlinking }"></div>
|
||||
<div class="eye right-eye" :class="{ blink: isBlinking }"></div>
|
||||
</div>
|
||||
<div class="avatar-mouth" :class="{ talking: isAISpeaking }"></div>
|
||||
</div>
|
||||
@@ -211,13 +205,6 @@ export default {
|
||||
isBlinking: false, // 是否在眨眼
|
||||
blinkTimer: null, // 眨眼定时器
|
||||
speakingTimer: null, // 说话动画定时器
|
||||
|
||||
// 眼睛跟踪鼠标
|
||||
mouseX: 0, // 鼠标X坐标
|
||||
mouseY: 0, // 鼠标Y坐标
|
||||
eyeOffsetX: 0, // 眼睛X偏移
|
||||
eyeOffsetY: 0, // 眼睛Y偏移
|
||||
isMouseTracking: true, // 是否启用鼠标跟踪
|
||||
requestMonitorInterval: null,
|
||||
maxRequestDuration: 60000, // 最大请求持续时间60秒
|
||||
|
||||
@@ -296,9 +283,6 @@ export default {
|
||||
// 启动数字人自动眨眼
|
||||
this.startAutoBlinking()
|
||||
|
||||
// 启动鼠标跟踪
|
||||
this.enableMouseTracking()
|
||||
|
||||
// 确保DOM完全渲染后再初始化聊天
|
||||
this.$nextTick(() => {
|
||||
setTimeout(async () => {
|
||||
@@ -338,10 +322,9 @@ export default {
|
||||
this.contentUpdateTimer = null
|
||||
}
|
||||
|
||||
// 清理数字人相关定时器和事件监听器
|
||||
// 清理数字人相关定时器
|
||||
this.stopAutoBlinking()
|
||||
this.stopAIAnimation()
|
||||
this.disableMouseTracking()
|
||||
|
||||
// 取消正在进行的请求
|
||||
if (this.currentCancel) {
|
||||
@@ -1159,8 +1142,6 @@ export default {
|
||||
startAIThinking() {
|
||||
this.isAIThinking = true
|
||||
this.isAISpeaking = false
|
||||
// 思考时启用鼠标跟踪
|
||||
this.enableMouseTracking()
|
||||
},
|
||||
|
||||
// 开始AI说话动画
|
||||
@@ -1168,9 +1149,6 @@ export default {
|
||||
this.isAIThinking = false
|
||||
this.isAISpeaking = true
|
||||
|
||||
// 说话时禁用鼠标跟踪,眼睛面向前方
|
||||
this.disableMouseTracking()
|
||||
|
||||
// 清除之前的说话定时器
|
||||
if (this.speakingTimer) {
|
||||
clearTimeout(this.speakingTimer)
|
||||
@@ -1182,9 +1160,6 @@ export default {
|
||||
this.isAIThinking = false
|
||||
this.isAISpeaking = false
|
||||
|
||||
// 停止动画后恢复鼠标跟踪
|
||||
this.enableMouseTracking()
|
||||
|
||||
if (this.speakingTimer) {
|
||||
clearTimeout(this.speakingTimer)
|
||||
this.speakingTimer = null
|
||||
@@ -1222,69 +1197,6 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
// 鼠标移动事件处理
|
||||
handleMouseMove(event) {
|
||||
if (!this.isMouseTracking || this.isDestroyed) return
|
||||
|
||||
this.mouseX = event.clientX
|
||||
this.mouseY = event.clientY
|
||||
this.updateEyePosition()
|
||||
},
|
||||
|
||||
// 更新眼睛位置
|
||||
updateEyePosition() {
|
||||
if (!this.isMouseTracking) return
|
||||
|
||||
// 获取数字人头像的位置
|
||||
const avatarElement = this.$el.querySelector('.digital-avatar')
|
||||
if (!avatarElement) return
|
||||
|
||||
const rect = avatarElement.getBoundingClientRect()
|
||||
const avatarCenterX = rect.left + rect.width / 2
|
||||
const avatarCenterY = rect.top + rect.height / 2
|
||||
|
||||
// 计算鼠标相对于头像中心的位置
|
||||
const deltaX = this.mouseX - avatarCenterX
|
||||
const deltaY = this.mouseY - avatarCenterY
|
||||
|
||||
// 计算距离和角度
|
||||
const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY)
|
||||
const maxDistance = 100 // 最大跟踪距离
|
||||
const maxOffset = 1.5 // 眼睛最大偏移量
|
||||
|
||||
// 限制跟踪范围
|
||||
const trackingFactor = Math.min(distance / maxDistance, 1)
|
||||
|
||||
// 计算眼睛偏移
|
||||
this.eyeOffsetX = (deltaX / distance) * maxOffset * trackingFactor
|
||||
this.eyeOffsetY = (deltaY / distance) * maxOffset * trackingFactor
|
||||
|
||||
// 如果距离太近,眼睛回到中心
|
||||
if (distance < 50) {
|
||||
this.eyeOffsetX = 0
|
||||
this.eyeOffsetY = 0
|
||||
}
|
||||
},
|
||||
|
||||
// 眼睛回到中心位置(说话时使用)
|
||||
resetEyePosition() {
|
||||
this.eyeOffsetX = 0
|
||||
this.eyeOffsetY = 0
|
||||
},
|
||||
|
||||
// 启用鼠标跟踪
|
||||
enableMouseTracking() {
|
||||
this.isMouseTracking = true
|
||||
document.addEventListener('mousemove', this.handleMouseMove)
|
||||
},
|
||||
|
||||
// 禁用鼠标跟踪
|
||||
disableMouseTracking() {
|
||||
this.isMouseTracking = false
|
||||
document.removeEventListener('mousemove', this.handleMouseMove)
|
||||
this.resetEyePosition()
|
||||
},
|
||||
|
||||
/**
|
||||
* 处理点赞
|
||||
*/
|
||||
@@ -1808,35 +1720,16 @@ export default {
|
||||
|
||||
/* 眼睛 */
|
||||
.eye {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #fff;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 50%;
|
||||
transition: all 0.15s ease;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.eye.blink {
|
||||
height: 2px;
|
||||
background: #666;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.eye.blink .pupil {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* 瞳孔 */
|
||||
.pupil {
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
background: #333;
|
||||
border-radius: 50%;
|
||||
transition: transform 0.1s ease;
|
||||
transition: all 0.15s ease;
|
||||
}
|
||||
|
||||
.eye.blink {
|
||||
height: 1px;
|
||||
background: #666;
|
||||
}
|
||||
|
||||
/* 嘴巴 */
|
||||
|
Reference in New Issue
Block a user