修正開啟追視後 renderer 崩潰,追視改為只在待機時生效
摘要:
startAnim 對 look 會丟 TypeError 導致動畫迴圈整個死掉;另把追視改成只在 idle 時覆蓋。
根本原因:
1. 追視是單一靜態擺姿,TIMINGS 裡沒有 look 這個動作。但序列模型改寫後,
tick 在動畫改變時無條件呼叫 startAnim(anim),傳入 "look" 時會走到
cycleOf("look") → TIMINGS["look"].map → TypeError。
例外從 requestAnimationFrame 的 callback 拋出,迴圈就此中止,
整隻寵物凍結,也不再回應任何 hook 事件——就是使用者回報的「直接沒反應」。
2. 對照 Codex 時把 lookFrame 改成覆蓋所有狀態。但 Codex 的追視來源是 quick chat 的
文字游標,只有使用者真的在打字時才存在;滑鼠卻是一直都在,照搬會讓工作中的
running / waiting / review 動畫永遠被靜態擺姿蓋掉,寵物失去反映狀態的作用。
影響:
選單一勾「跟著游標看」,游標一動寵物就完全凍結,且不會恢復。
修法:
- startAnim 開頭對 look 早退,直接設成空的幀序列(靜態擺姿),
不進入 cycleOf / baseSequence。draw 本來就單獨處理 look,tick 的推幀也已排除 look。
- resolveAnim 先取 baseState(),只有 base 為 idle 時才回傳 look;
一併避免原本重複呼叫 baseState() 的副作用。
- README 的特色、行為對照表、與 Codex 的對照三處同步更新,
對照表把「追視」拆成來源與優先序兩列並說明為何刻意不同。
不動的部分:
hover 跳躍維持進入時播 3 次、之後停住不再跳(使用者確認就是要這個行為)。
另已確認跳躍結束後會回到當下的基礎狀態而非一律 idle。
驗證:
- 單元測試(抽出實際程式碼執行):修正前 startAnim("look") 拋
TypeError: Cannot read properties of undefined (reading 'map'),修正後回傳空序列;
idle 6 幀、running 24 幀正常;resolveAnim 在追視開啟下
idle→look、running→running、waiting→waiting、review→review,
hover 跳躍優先於 look 與 running,跳躍結束回到 running 而非 idle,共 11 項全過。
- 實機開啟 followCursor 啟動:/state 持續回應且 anim 為 look(修正前此處即崩潰),
log 無任何例外;灌入事件後 running / waiting 正確蓋過追視。
- 以 ELECTRON_RUN_AS_NODE 讀打包後 app.asar:版本 2.0.2、崩潰修正與追視優先序都在,
hover 跳躍、矩形判定、右鍵選單未受影響;exe FileVersion 為 2.0.2。
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+12
-3
@@ -103,6 +103,12 @@ function baseSequence(anim) {
|
||||
const reducedMotionQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
||||
|
||||
function startAnim(anim, now) {
|
||||
// 追視是單一靜態擺姿,沒有幀序列(TIMINGS 裡沒有 look)。
|
||||
// 少了這道判斷會走進 cycleOf("look") 而丟 TypeError,requestAnimationFrame 迴圈整個死掉。
|
||||
if (anim === "look") {
|
||||
player = { anim, frames: [], loopStart: null, step: 0, stepStart: now };
|
||||
return;
|
||||
}
|
||||
let seq;
|
||||
if (reducedMotionQuery.matches) {
|
||||
// 與 Codex 相同:系統關閉動畫時只顯示該狀態的第一格
|
||||
@@ -287,9 +293,12 @@ function resolveAnim() {
|
||||
// 一次性動作(點擊揮手、初次問候)。Codex 的 lookFrame 會蓋過這些,但它的追視來源不是滑鼠;
|
||||
// 滑鼠永遠在畫面上,若照搬會讓點擊揮手永遠看不到,所以這裡讓手勢優先。
|
||||
if (overlay) return overlay.anim;
|
||||
// Codex:lookFrame 一旦有值就覆蓋所有狀態,靜態擺姿
|
||||
if (followCursor && petInfo?.version === 2 && look.idx !== null) return "look";
|
||||
return baseState();
|
||||
const base = baseState();
|
||||
// Codex 的 lookFrame 會覆蓋所有狀態,但它的追視來源是 quick chat 的文字游標,
|
||||
// 只有你真的在那裡打字時才存在。滑鼠則是一直都在,照搬會讓工作中的動畫永遠被靜態擺姿蓋掉,
|
||||
// 寵物就失去反映 Claude Code 狀態的作用,所以只在 idle 時追視。
|
||||
if (base === "idle" && followCursor && petInfo?.version === 2 && look.idx !== null) return "look";
|
||||
return base;
|
||||
}
|
||||
|
||||
function projectName(cwd) {
|
||||
|
||||
Reference in New Issue
Block a user