castle-web-cli 0.4.71 → 0.4.73
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/dist/agent-prompts.js +22 -3
- package/dist/agent.js +731 -313
- package/dist/init.js +1 -1
- package/dist/shell/assets/index-Dfn29Bkt.js +108 -0
- package/dist/shell/assets/{index-CVEnWuGV.css → index-WNbOHPBj.css} +1 -1
- package/dist/shell/index.html +2 -2
- package/dist/vitePlugins.js +3 -2
- package/kits/basic-2d/CLAUDE.md +29 -8
- package/kits/basic-2d/behaviors/Collider.jsx +6 -4
- package/kits/basic-2d/behaviors/Layout.jsx +2 -2
- package/kits/basic-2d/behaviors/Sprite.jsx +210 -0
- package/kits/basic-2d/behaviors/tint.js +47 -0
- package/kits/basic-2d/docs/pxart-format.md +298 -0
- package/kits/basic-2d/drawings/pig.pxart +59 -0
- package/kits/basic-2d/editors/App.jsx +125 -76
- package/kits/basic-2d/editors/CodeEditor.jsx +9 -45
- package/kits/basic-2d/editors/FileBrowser.jsx +234 -47
- package/kits/basic-2d/editors/PlayOnly.jsx +9 -7
- package/kits/basic-2d/editors/PxArtEditor.jsx +662 -0
- package/kits/basic-2d/editors/SceneEditor.jsx +587 -221
- package/kits/basic-2d/editors/SelectionOverlay.jsx +808 -0
- package/kits/basic-2d/editors/SingleEditor.jsx +38 -20
- package/kits/basic-2d/editors/codeTheme.js +135 -0
- package/kits/basic-2d/editors/editorHistory.js +44 -17
- package/kits/basic-2d/editors/inspectorSheet.js +23 -0
- package/kits/basic-2d/editors/pixelCanvas.js +11 -0
- package/kits/basic-2d/editors/pixelEditorChrome.jsx +55 -0
- package/kits/basic-2d/editors/pixelGeometry.js +45 -0
- package/kits/basic-2d/editors/pixelInspector.jsx +416 -0
- package/kits/basic-2d/editors/pxArtEditorModel.js +718 -0
- package/kits/basic-2d/editors/pxArtPlayback.js +92 -0
- package/kits/basic-2d/editors/pxArtTimeline.jsx +752 -0
- package/kits/basic-2d/editors/pxArtTimeline.module.css +506 -0
- package/kits/basic-2d/editors/pxArtTools.js +124 -0
- package/kits/basic-2d/editors/useArtboardFit.js +102 -0
- package/kits/basic-2d/engine/ScenePlayer.jsx +10 -4
- package/kits/basic-2d/engine/SceneUI.jsx +3 -11
- package/kits/basic-2d/engine/assets.js +15 -0
- package/kits/basic-2d/engine/files.js +57 -2
- package/kits/basic-2d/engine/pxart.js +985 -0
- package/kits/basic-2d/engine/scene.js +222 -41
- package/kits/basic-2d/engine/ui.jsx +155 -26
- package/kits/basic-2d/engine/ui.module.css +1280 -344
- package/kits/basic-2d/eslint.config.js +21 -0
- package/kits/basic-2d/index.html +13 -0
- package/kits/basic-2d/package.json +1 -0
- package/kits/basic-2d/pnpm-lock.yaml +5 -5
- package/kits/basic-2d/scenes/main.scene +19 -26
- package/kits/basic-2d/scripts/draw.mjs +121 -0
- package/kits/basic-3d/editors/PlayOnly.jsx +9 -1
- package/kits/basic-3d/engine/ScenePlayer.jsx +7 -1
- package/package.json +1 -1
- package/dist/shell/assets/index-BY21Og40.js +0 -106
- package/kits/basic-2d/behaviors/Drawing.jsx +0 -142
- package/kits/basic-2d/drawings/block.drawing +0 -70
- package/kits/basic-2d/drawings/default.drawing +0 -70
- package/kits/basic-2d/editors/DrawingEditor.jsx +0 -224
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { frameCount } from '../engine/pxart';
|
|
3
|
+
|
|
4
|
+
// Preview-playback helpers for the PxArt editor. These mirror the Sprite
|
|
5
|
+
// behavior's runtime semantics (frame stepping by durationMs, tag range +
|
|
6
|
+
// direction, repeat) so the in-editor preview agrees with how the sprite plays
|
|
7
|
+
// at runtime — but they run on a rAF clock and drive a React index rather than
|
|
8
|
+
// the engine's actor state.
|
|
9
|
+
|
|
10
|
+
// Resolve the tag that should drive the preview: an explicit name, else the
|
|
11
|
+
// sprite's defaultTag, else null (whole-timeline forward loop).
|
|
12
|
+
export function resolveActiveTag(sprite, name) {
|
|
13
|
+
const wanted = name || sprite.defaultTag;
|
|
14
|
+
if (!wanted) return null;
|
|
15
|
+
return sprite.tags.find((tag) => tag.name === wanted) ?? null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function tagBounds(tag, total) {
|
|
19
|
+
if (!tag) return { lo: 0, hi: total - 1, dir: 'forward' };
|
|
20
|
+
let lo = Math.min(Math.max(tag.from, 0), total - 1);
|
|
21
|
+
let hi = Math.min(Math.max(tag.to, 0), total - 1);
|
|
22
|
+
if (lo > hi) [lo, hi] = [hi, lo];
|
|
23
|
+
return { lo, hi, dir: tag.direction };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// The ordered frame indices the preview steps through for a tag (or the whole
|
|
27
|
+
// timeline). Pingpong appends the interior frames in reverse; reverse flips.
|
|
28
|
+
export function playbackOrder(sprite, tag) {
|
|
29
|
+
const total = Math.max(frameCount(sprite), 1);
|
|
30
|
+
const { lo, hi, dir } = tagBounds(tag, total);
|
|
31
|
+
const order = [];
|
|
32
|
+
for (let f = lo; f <= hi; f++) order.push(f);
|
|
33
|
+
if (dir === 'reverse') order.reverse();
|
|
34
|
+
else if (dir === 'pingpong') for (let f = hi - 1; f > lo; f--) order.push(f);
|
|
35
|
+
return order.length ? order : [0];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// The per-step durations (ms) aligned to a playback order.
|
|
39
|
+
export function frameDurations(sprite, order) {
|
|
40
|
+
return order.map((f) => sprite.frames[f]?.durationMs ?? sprite.defaultDurationMs);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Advance a mutable playhead {pos, acc, loops, done} by the elapsed budget in
|
|
44
|
+
// `acc`, honoring repeat (0 = forever; otherwise hold the final step).
|
|
45
|
+
function step(state, durations, length, repeat) {
|
|
46
|
+
let guard = 0;
|
|
47
|
+
while (!state.done && guard++ < 1000) {
|
|
48
|
+
const dur = durations[state.pos] > 0 ? durations[state.pos] : 100;
|
|
49
|
+
if (state.acc < dur) break;
|
|
50
|
+
state.acc -= dur;
|
|
51
|
+
state.pos += 1;
|
|
52
|
+
if (state.pos < length) continue;
|
|
53
|
+
state.loops += 1;
|
|
54
|
+
if (repeat !== 0 && state.loops >= repeat) {
|
|
55
|
+
state.pos = length - 1;
|
|
56
|
+
state.done = true;
|
|
57
|
+
} else {
|
|
58
|
+
state.pos = 0;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Drive a preview frame index while `playing`. Reads the latest order/durations
|
|
64
|
+
// through a ref so a re-derived sprite object doesn't restart playback; only
|
|
65
|
+
// toggling `playing` (re)starts the clock. Returns `fallbackIndex` when paused.
|
|
66
|
+
export function usePreviewPlayback({ order, durations, repeat }, playing, fallbackIndex) {
|
|
67
|
+
const [pos, setPos] = useState(0);
|
|
68
|
+
const dataRef = useRef({ order, durations, repeat });
|
|
69
|
+
dataRef.current = { order, durations, repeat };
|
|
70
|
+
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!playing) return undefined;
|
|
73
|
+
const playhead = { pos: 0, acc: 0, loops: 0, done: false };
|
|
74
|
+
setPos(0);
|
|
75
|
+
let raf = 0;
|
|
76
|
+
let last = performance.now();
|
|
77
|
+
const tick = (now) => {
|
|
78
|
+
const data = dataRef.current;
|
|
79
|
+
playhead.acc += now - last;
|
|
80
|
+
last = now;
|
|
81
|
+
step(playhead, data.durations, data.order.length, data.repeat);
|
|
82
|
+
setPos(Math.min(playhead.pos, data.order.length - 1));
|
|
83
|
+
raf = requestAnimationFrame(tick);
|
|
84
|
+
};
|
|
85
|
+
raf = requestAnimationFrame(tick);
|
|
86
|
+
return () => cancelAnimationFrame(raf);
|
|
87
|
+
}, [playing]);
|
|
88
|
+
|
|
89
|
+
if (!playing) return fallbackIndex;
|
|
90
|
+
const order2 = dataRef.current.order;
|
|
91
|
+
return order2[Math.min(pos, order2.length - 1)] ?? fallbackIndex;
|
|
92
|
+
}
|