@mingxy/opencode-mascot 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/core/ascii-renderer.tsx +40 -3
package/package.json
CHANGED
|
@@ -36,6 +36,9 @@ const DEFAULT_ANIM = {
|
|
|
36
36
|
|
|
37
37
|
const WALK_PATH = [1, 2, 3, 4, 3, 2, 1, 0, -1, -2, -3, -2, -1, 0];
|
|
38
38
|
|
|
39
|
+
const FLASH_COLORS = ["#FF006E", "#FFBE0B", "#8338EC", "#3A86FF", "#FB5607", "#06FFA5", "#FF4081", "#00E5FF"];
|
|
40
|
+
const DRAG_MSGS = ["ᶠᵃⁿᵍ!..", "ᵏᵃⁱ~..", "ᵇᵘᶠᵃⁿᵍ~..", "ʷᵒ~..", "ⁿⁱᵘ~..", "ᵃᵃ~.."];
|
|
41
|
+
|
|
39
42
|
function getFrameLines(pack: MascotPack, frameName: string): string[] {
|
|
40
43
|
const frames = pack.frames as Record<string, string[] | undefined>;
|
|
41
44
|
return frames[frameName] ?? frames["default"] ?? [];
|
|
@@ -72,6 +75,19 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
72
75
|
const [walkEnabled, setWalkEnabled] = createSignal(anim.walkEnabled ?? true);
|
|
73
76
|
const [dragging, setDraggingSignal] = createSignal(false);
|
|
74
77
|
const [celebrate, setCelebrate] = createSignal<{ text: string; count: number } | null>(null);
|
|
78
|
+
const [flashColor, setFlashColor] = createSignal<string | null>(null);
|
|
79
|
+
const [dragMsg, setDragMsg] = createSignal<string | null>(null);
|
|
80
|
+
|
|
81
|
+
let flashTimer: ReturnType<typeof setInterval> | null = null;
|
|
82
|
+
let dragMsgTimer: ReturnType<typeof setInterval> | null = null;
|
|
83
|
+
|
|
84
|
+
const stopFlash = () => {
|
|
85
|
+
if (flashTimer) { clearInterval(flashTimer); flashTimer = null; }
|
|
86
|
+
};
|
|
87
|
+
const stopDragMsg = () => {
|
|
88
|
+
if (dragMsgTimer) { clearInterval(dragMsgTimer); dragMsgTimer = null; }
|
|
89
|
+
setDragMsg(null);
|
|
90
|
+
};
|
|
75
91
|
|
|
76
92
|
let idleSleepTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
77
93
|
|
|
@@ -230,6 +246,8 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
230
246
|
if (idleSleepTimeout) clearTimeout(idleSleepTimeout);
|
|
231
247
|
if (walkInterval) clearInterval(walkInterval);
|
|
232
248
|
for (const t of effectTimers) clearInterval(t);
|
|
249
|
+
stopFlash();
|
|
250
|
+
stopDragMsg();
|
|
233
251
|
});
|
|
234
252
|
|
|
235
253
|
// ─── Render ───
|
|
@@ -241,6 +259,8 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
241
259
|
currentState();
|
|
242
260
|
dragging();
|
|
243
261
|
celebrate();
|
|
262
|
+
flashColor();
|
|
263
|
+
dragMsg();
|
|
244
264
|
|
|
245
265
|
for (const [, [get]] of extraSignals) {
|
|
246
266
|
get();
|
|
@@ -276,11 +296,14 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
276
296
|
const top = jumpOffset();
|
|
277
297
|
const left = offset > 0 ? offset : 0;
|
|
278
298
|
const cel = celebrate();
|
|
299
|
+
const dm = dragMsg();
|
|
300
|
+
const color = flashColor() ?? fg;
|
|
279
301
|
|
|
280
302
|
return (
|
|
281
303
|
<box flexDirection="column" left={left} top={top}>
|
|
282
|
-
{cel ? <text fg={
|
|
283
|
-
{
|
|
304
|
+
{cel ? <text fg={color}>{cel.text}</text> : null}
|
|
305
|
+
{dm ? <text fg="#FF4081">{dm}</text> : null}
|
|
306
|
+
{renderLines(lines, color)}
|
|
284
307
|
</box>
|
|
285
308
|
);
|
|
286
309
|
};
|
|
@@ -297,6 +320,15 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
297
320
|
walkTimeout = scheduleNextWalk();
|
|
298
321
|
jumpTimeout = scheduleNextJump();
|
|
299
322
|
}
|
|
323
|
+
|
|
324
|
+
if (s === "thinking" || s === "busy") {
|
|
325
|
+
stopFlash();
|
|
326
|
+
flashTimer = setInterval(() => {
|
|
327
|
+
setFlashColor(FLASH_COLORS[Math.floor(Math.random() * FLASH_COLORS.length)]);
|
|
328
|
+
}, 120);
|
|
329
|
+
} else {
|
|
330
|
+
stopFlash();
|
|
331
|
+
}
|
|
300
332
|
};
|
|
301
333
|
|
|
302
334
|
const toggleWalk = () => {
|
|
@@ -312,13 +344,18 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
312
344
|
const setDragging = (v: boolean) => {
|
|
313
345
|
setDraggingSignal(v);
|
|
314
346
|
if (v) {
|
|
315
|
-
// 睡着时被拖拽 → 惊醒到 idle,切回 default 帧后手臂 ┃███┃ 才能被扇手渲染匹配
|
|
316
347
|
if (currentState() === "sleeping") {
|
|
317
348
|
setState("idle");
|
|
318
349
|
}
|
|
319
350
|
setJumpOffset(-1);
|
|
351
|
+
stopDragMsg();
|
|
352
|
+
setDragMsg(DRAG_MSGS[Math.floor(Math.random() * DRAG_MSGS.length)]);
|
|
353
|
+
dragMsgTimer = setInterval(() => {
|
|
354
|
+
setDragMsg(DRAG_MSGS[Math.floor(Math.random() * DRAG_MSGS.length)]);
|
|
355
|
+
}, 800);
|
|
320
356
|
} else {
|
|
321
357
|
setJumpOffset(0);
|
|
358
|
+
stopDragMsg();
|
|
322
359
|
}
|
|
323
360
|
};
|
|
324
361
|
|