This commit is contained in:
yinsx
2025-12-25 09:46:16 +08:00
parent 48d587c1ff
commit e56f47076c
4 changed files with 36 additions and 19 deletions

View File

@ -231,8 +231,13 @@ class BlendShapeAnimator {
this.blinkInterval = setTimeout(() => {
if (this.isBlinkEnabled) {
this._doBlink();
const holdDuration = Math.max(0, this.blinkParams.duration || 0);
this.blinkInterval = setTimeout(() => {
if (this.isBlinkEnabled) {
scheduleNext();
}
}, holdDuration);
}
}, delay);
};
@ -281,9 +286,14 @@ class BlendShapeAnimator {
const delay = this.eyeLookParams.intervalMin + Math.random() * (this.eyeLookParams.intervalMax - this.eyeLookParams.intervalMin);
this.eyeLookInterval = setTimeout(() => {
if (this.isEyeLookEnabled) {
this._doRandomEyeLook();
const holdDuration = this._doRandomEyeLook();
const waitDuration = Math.max(0, holdDuration || 0);
this.eyeLookInterval = setTimeout(() => {
if (this.isEyeLookEnabled) {
scheduleNext();
}
}, waitDuration);
}
}, delay);
};
@ -330,6 +340,8 @@ class BlendShapeAnimator {
});
}
}, holdDuration);
return holdDuration;
}
_resetEyeLook() {

View File

@ -131,6 +131,7 @@ const ExpressionLibrary = {
enabled: false,
timeout: null,
currentExpression: null,
lastExpressionKey: null,
intervalMin: 3000,
intervalMax: 8000,
@ -170,7 +171,10 @@ const ExpressionLibrary = {
return;
}
const randomKey = enabledKeys[Math.floor(Math.random() * enabledKeys.length)];
const availableKeys = enabledKeys.length > 1 && this.lastExpressionKey
? enabledKeys.filter(key => key !== this.lastExpressionKey)
: enabledKeys;
const randomKey = availableKeys[Math.floor(Math.random() * availableKeys.length)];
const expression = ExpressionLibrary.expressions[randomKey];
this.play(expression);
@ -178,6 +182,9 @@ const ExpressionLibrary = {
play: function(expression) {
this.currentExpression = expression;
this.lastExpressionKey = Object.keys(ExpressionLibrary.expressions).find(
key => ExpressionLibrary.expressions[key] === expression
);
// 从主页面获取动画速度参数
const speed = window.expressionParams?.speed || 400;
@ -189,17 +196,13 @@ const ExpressionLibrary = {
}
}
// 获取表情的key
const expressionKey = Object.keys(ExpressionLibrary.expressions).find(
key => ExpressionLibrary.expressions[key] === expression
);
// 使用用户设置的持续时间,如果没有则使用表情默认时间
const duration = (window.expressionDurations && window.expressionDurations[expressionKey])
const duration = (window.expressionDurations && window.expressionDurations[this.lastExpressionKey])
|| expression.duration;
setTimeout(() => {
this.reset();
if (!this.enabled) return;
this.scheduleNext();
}, duration);
},

View File

@ -65,10 +65,10 @@
</label>
<div class="param-group" id="blinkParams">
<div class="param-item">
<label>频率间隔 (秒): <span class="param-value" id="blinkIntervalValue">2-5</span></label>
<input type="range" id="blinkIntervalMin" min="1" max="5" step="0.5" value="2"
<label>频率间隔 (秒): <span class="param-value" id="blinkIntervalValue">1-2</span></label>
<input type="range" id="blinkIntervalMin" min="1" max="5" step="0.5" value="1"
oninput="updateBlinkInterval()">
<input type="range" id="blinkIntervalMax" min="3" max="10" step="0.5" value="5"
<input type="range" id="blinkIntervalMax" min="2" max="10" step="0.5" value="2"
oninput="updateBlinkInterval()">
</div>
<div class="param-item">
@ -93,10 +93,10 @@
</label>
<div class="param-group" id="eyeLookParams">
<div class="param-item">
<label>频率间隔 (秒): <span class="param-value" id="eyeLookIntervalValue">2-6</span></label>
<input type="range" id="eyeLookIntervalMin" min="1" max="5" step="0.5" value="2"
<label>频率间隔 (秒): <span class="param-value" id="eyeLookIntervalValue">1-2</span></label>
<input type="range" id="eyeLookIntervalMin" min="1" max="5" step="0.5" value="1"
oninput="updateEyeLookInterval()">
<input type="range" id="eyeLookIntervalMax" min="3" max="10" step="0.5" value="6"
<input type="range" id="eyeLookIntervalMax" min="2" max="10" step="0.5" value="2"
oninput="updateEyeLookInterval()">
</div>
<div class="param-item">
@ -129,10 +129,10 @@
</div>
</div>
<div class="param-item">
<label>频率间隔 (秒): <span class="param-value" id="expressionIntervalValue">3-8</span></label>
<input type="range" id="expressionIntervalMin" min="2" max="8" step="0.5" value="3"
<label>频率间隔 (秒): <span class="param-value" id="expressionIntervalValue">1-1</span></label>
<input type="range" id="expressionIntervalMin" min="1" max="8" step="0.5" value="1"
oninput="updateExpressionInterval()">
<input type="range" id="expressionIntervalMax" min="5" max="15" step="0.5" value="8"
<input type="range" id="expressionIntervalMax" min="1" max="15" step="0.5" value="1"
oninput="updateExpressionInterval()">
</div>
<div class="param-item">

View File

@ -36,6 +36,8 @@ function init() {
window.enabledExpressions = enabledExpressions;
window.expressionDurations = expressionDurations;
updateExpressionInterval();
// 加载3D模型
sceneManager.loadModel('head_a01.glb',
(meshes) => {