@mingxy/opencode-mascot 0.2.8 → 0.3.0
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
CHANGED
|
@@ -81,17 +81,18 @@ export function HomeMascot(props: HomeMascotProps): JSX.Element {
|
|
|
81
81
|
setPosX(dragAnchorX + (e.x - dragStartX));
|
|
82
82
|
setPosY(dragAnchorY + (e.y - dragStartY));
|
|
83
83
|
e.preventDefault();
|
|
84
|
-
e.stopPropagation();
|
|
85
84
|
props.api.renderer.clearSelection();
|
|
86
85
|
}
|
|
87
86
|
}}
|
|
88
87
|
onMouseUp={() => {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
renderers[currentName()].setDragging(false);
|
|
92
|
-
}
|
|
88
|
+
isDragging = false;
|
|
89
|
+
renderers[currentName()].setDragging(false);
|
|
93
90
|
}}
|
|
94
91
|
onMouseDragEnd={() => {
|
|
92
|
+
isDragging = false;
|
|
93
|
+
renderers[currentName()].setDragging(false);
|
|
94
|
+
}}
|
|
95
|
+
onMouseOut={() => {
|
|
95
96
|
if (isDragging) {
|
|
96
97
|
isDragging = false;
|
|
97
98
|
renderers[currentName()].setDragging(false);
|
|
@@ -226,22 +226,23 @@ export function SidebarMascot(props: SidebarMascotProps): JSX.Element {
|
|
|
226
226
|
setPosX(clampX(dragAnchorX + (e.x - dragStartX)));
|
|
227
227
|
setPosY(clampY(dragAnchorY + (e.y - dragStartY)));
|
|
228
228
|
e.preventDefault();
|
|
229
|
-
e.stopPropagation();
|
|
230
229
|
props.api.renderer.clearSelection();
|
|
231
230
|
}
|
|
232
231
|
}}
|
|
233
232
|
onMouseUp={() => {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
checkEdge();
|
|
238
|
-
}
|
|
233
|
+
isDragging = false;
|
|
234
|
+
renderers[currentName()].setDragging(false);
|
|
235
|
+
checkEdge();
|
|
239
236
|
}}
|
|
240
237
|
onMouseDragEnd={() => {
|
|
238
|
+
isDragging = false;
|
|
239
|
+
renderers[currentName()].setDragging(false);
|
|
240
|
+
checkEdge();
|
|
241
|
+
}}
|
|
242
|
+
onMouseOut={() => {
|
|
241
243
|
if (isDragging) {
|
|
242
244
|
isDragging = false;
|
|
243
245
|
renderers[currentName()].setDragging(false);
|
|
244
|
-
checkEdge();
|
|
245
246
|
}
|
|
246
247
|
}}
|
|
247
248
|
>
|
|
@@ -36,21 +36,14 @@ 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"] ?? [];
|
|
42
45
|
}
|
|
43
46
|
|
|
44
|
-
function renderLines(lines: string[], fg?: string): JSX.Element {
|
|
45
|
-
return (
|
|
46
|
-
<box flexDirection="column">
|
|
47
|
-
{lines.map((line: string) => (
|
|
48
|
-
<text fg={fg}>{line}</text>
|
|
49
|
-
))}
|
|
50
|
-
</box>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
47
|
export function createAnimatedRenderer(pack: MascotPack): {
|
|
55
48
|
element: () => JSX.Element;
|
|
56
49
|
setState: (s: MascotState) => void;
|
|
@@ -72,6 +65,19 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
72
65
|
const [walkEnabled, setWalkEnabled] = createSignal(anim.walkEnabled ?? true);
|
|
73
66
|
const [dragging, setDraggingSignal] = createSignal(false);
|
|
74
67
|
const [celebrate, setCelebrate] = createSignal<{ text: string; count: number } | null>(null);
|
|
68
|
+
const [flashColor, setFlashColor] = createSignal<string | null>(null);
|
|
69
|
+
const [dragMsg, setDragMsg] = createSignal<string | null>(null);
|
|
70
|
+
|
|
71
|
+
let flashTimer: ReturnType<typeof setInterval> | null = null;
|
|
72
|
+
let dragMsgTimer: ReturnType<typeof setInterval> | null = null;
|
|
73
|
+
|
|
74
|
+
const stopFlash = () => {
|
|
75
|
+
if (flashTimer) { clearInterval(flashTimer); flashTimer = null; }
|
|
76
|
+
};
|
|
77
|
+
const stopDragMsg = () => {
|
|
78
|
+
if (dragMsgTimer) { clearInterval(dragMsgTimer); dragMsgTimer = null; }
|
|
79
|
+
setDragMsg(null);
|
|
80
|
+
};
|
|
75
81
|
|
|
76
82
|
let idleSleepTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
77
83
|
|
|
@@ -230,6 +236,8 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
230
236
|
if (idleSleepTimeout) clearTimeout(idleSleepTimeout);
|
|
231
237
|
if (walkInterval) clearInterval(walkInterval);
|
|
232
238
|
for (const t of effectTimers) clearInterval(t);
|
|
239
|
+
stopFlash();
|
|
240
|
+
stopDragMsg();
|
|
233
241
|
});
|
|
234
242
|
|
|
235
243
|
// ─── Render ───
|
|
@@ -241,6 +249,8 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
241
249
|
currentState();
|
|
242
250
|
dragging();
|
|
243
251
|
celebrate();
|
|
252
|
+
flashColor();
|
|
253
|
+
dragMsg();
|
|
244
254
|
|
|
245
255
|
for (const [, [get]] of extraSignals) {
|
|
246
256
|
get();
|
|
@@ -276,11 +286,17 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
276
286
|
const top = jumpOffset();
|
|
277
287
|
const left = offset > 0 ? offset : 0;
|
|
278
288
|
const cel = celebrate();
|
|
289
|
+
const dm = dragMsg();
|
|
279
290
|
|
|
280
291
|
return (
|
|
281
292
|
<box flexDirection="column" left={left} top={top}>
|
|
282
|
-
{cel ? <text fg={fg}>{cel.text}</text> : null}
|
|
283
|
-
{
|
|
293
|
+
{cel ? <text fg={flashColor() ?? fg}>{cel.text}</text> : null}
|
|
294
|
+
{dm ? <text fg="#FF4081">{dm}</text> : null}
|
|
295
|
+
<box flexDirection="column">
|
|
296
|
+
{lines.map((line: string) => (
|
|
297
|
+
<text fg={flashColor() ?? fg}>{line}</text>
|
|
298
|
+
))}
|
|
299
|
+
</box>
|
|
284
300
|
</box>
|
|
285
301
|
);
|
|
286
302
|
};
|
|
@@ -297,6 +313,15 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
297
313
|
walkTimeout = scheduleNextWalk();
|
|
298
314
|
jumpTimeout = scheduleNextJump();
|
|
299
315
|
}
|
|
316
|
+
|
|
317
|
+
if (s === "thinking" || s === "busy") {
|
|
318
|
+
stopFlash();
|
|
319
|
+
flashTimer = setInterval(() => {
|
|
320
|
+
setFlashColor(FLASH_COLORS[Math.floor(Math.random() * FLASH_COLORS.length)]);
|
|
321
|
+
}, 120);
|
|
322
|
+
} else {
|
|
323
|
+
stopFlash();
|
|
324
|
+
}
|
|
300
325
|
};
|
|
301
326
|
|
|
302
327
|
const toggleWalk = () => {
|
|
@@ -312,13 +337,23 @@ export function createAnimatedRenderer(pack: MascotPack): {
|
|
|
312
337
|
const setDragging = (v: boolean) => {
|
|
313
338
|
setDraggingSignal(v);
|
|
314
339
|
if (v) {
|
|
315
|
-
// 睡着时被拖拽 → 惊醒到 idle,切回 default 帧后手臂 ┃███┃ 才能被扇手渲染匹配
|
|
316
340
|
if (currentState() === "sleeping") {
|
|
317
341
|
setState("idle");
|
|
318
342
|
}
|
|
319
343
|
setJumpOffset(-1);
|
|
344
|
+
stopDragMsg();
|
|
345
|
+
setDragMsg(DRAG_MSGS[Math.floor(Math.random() * DRAG_MSGS.length)]);
|
|
346
|
+
dragMsgTimer = setInterval(() => {
|
|
347
|
+
setDragMsg(DRAG_MSGS[Math.floor(Math.random() * DRAG_MSGS.length)]);
|
|
348
|
+
}, 800);
|
|
349
|
+
stopFlash();
|
|
350
|
+
flashTimer = setInterval(() => {
|
|
351
|
+
setFlashColor(FLASH_COLORS[Math.floor(Math.random() * FLASH_COLORS.length)]);
|
|
352
|
+
}, 100);
|
|
320
353
|
} else {
|
|
321
354
|
setJumpOffset(0);
|
|
355
|
+
stopDragMsg();
|
|
356
|
+
stopFlash();
|
|
322
357
|
}
|
|
323
358
|
};
|
|
324
359
|
|