distark-render 1.0.5 → 1.0.7

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.
Files changed (94) hide show
  1. package/README.md +158 -154
  2. package/dist/cli/animate.d.ts +8 -0
  3. package/dist/cli/animate.d.ts.map +1 -0
  4. package/dist/cli/animate.js +121 -0
  5. package/dist/cli/animate.js.map +1 -0
  6. package/dist/cli/diff.d.ts +8 -0
  7. package/dist/cli/diff.d.ts.map +1 -0
  8. package/dist/cli/diff.js +124 -0
  9. package/dist/cli/diff.js.map +1 -0
  10. package/dist/cli/distark-check.d.ts +13 -0
  11. package/dist/cli/distark-check.d.ts.map +1 -0
  12. package/dist/cli/distark-check.js +69 -0
  13. package/dist/cli/distark-check.js.map +1 -0
  14. package/dist/cli/query.d.ts +12 -0
  15. package/dist/cli/query.d.ts.map +1 -0
  16. package/dist/cli/query.js +64 -0
  17. package/dist/cli/query.js.map +1 -0
  18. package/dist/cli/record.d.ts +13 -0
  19. package/dist/cli/record.d.ts.map +1 -0
  20. package/dist/cli/record.js +97 -0
  21. package/dist/cli/record.js.map +1 -0
  22. package/dist/cli/render.d.ts +40 -0
  23. package/dist/cli/render.d.ts.map +1 -0
  24. package/dist/cli/render.js +75 -0
  25. package/dist/cli/render.js.map +1 -0
  26. package/dist/cli/shared.d.ts +6 -0
  27. package/dist/cli/shared.d.ts.map +1 -0
  28. package/dist/cli/shared.js +54 -0
  29. package/dist/cli/shared.js.map +1 -0
  30. package/dist/cli/test.d.ts +13 -0
  31. package/dist/cli/test.d.ts.map +1 -0
  32. package/dist/cli/test.js +130 -0
  33. package/dist/cli/test.js.map +1 -0
  34. package/dist/cli/verify.d.ts +21 -0
  35. package/dist/cli/verify.d.ts.map +1 -0
  36. package/dist/cli/verify.js +175 -0
  37. package/dist/cli/verify.js.map +1 -0
  38. package/dist/modules/adapters/p5Renderer.d.ts +0 -0
  39. package/dist/modules/adapters/p5Renderer.d.ts.map +0 -0
  40. package/dist/modules/adapters/p5Renderer.js +0 -0
  41. package/dist/modules/adapters/p5Renderer.js.map +0 -0
  42. package/dist/modules/adapters/skiaRenderer.d.ts +0 -0
  43. package/dist/modules/adapters/skiaRenderer.d.ts.map +0 -0
  44. package/dist/modules/adapters/skiaRenderer.js +0 -0
  45. package/dist/modules/adapters/skiaRenderer.js.map +0 -0
  46. package/dist/modules/animationDiff.d.ts +101 -0
  47. package/dist/modules/animationDiff.d.ts.map +1 -0
  48. package/dist/modules/animationDiff.js +327 -0
  49. package/dist/modules/animationDiff.js.map +1 -0
  50. package/dist/modules/eyeSystem.d.ts +0 -0
  51. package/dist/modules/eyeSystem.d.ts.map +0 -0
  52. package/dist/modules/eyeSystem.js +0 -0
  53. package/dist/modules/eyeSystem.js.map +0 -0
  54. package/dist/modules/imageLoad.d.ts +0 -0
  55. package/dist/modules/imageLoad.d.ts.map +0 -0
  56. package/dist/modules/imageLoad.js +0 -0
  57. package/dist/modules/imageLoad.js.map +0 -0
  58. package/dist/modules/mouthSystem.d.ts +0 -0
  59. package/dist/modules/mouthSystem.d.ts.map +0 -0
  60. package/dist/modules/mouthSystem.js +0 -0
  61. package/dist/modules/mouthSystem.js.map +0 -0
  62. package/dist/modules/renderRig.d.ts +0 -0
  63. package/dist/modules/renderRig.d.ts.map +0 -0
  64. package/dist/modules/renderRig.js +0 -0
  65. package/dist/modules/renderRig.js.map +0 -0
  66. package/dist/tests/test-animation-diff-rendering.d.ts +7 -0
  67. package/dist/tests/test-animation-diff-rendering.d.ts.map +1 -0
  68. package/dist/tests/test-animation-diff-rendering.js +444 -0
  69. package/dist/tests/test-animation-diff-rendering.js.map +1 -0
  70. package/dist/tests/test-animation-diff.d.ts +7 -0
  71. package/dist/tests/test-animation-diff.d.ts.map +1 -0
  72. package/dist/tests/test-animation-diff.js +488 -0
  73. package/dist/tests/test-animation-diff.js.map +1 -0
  74. package/dist/tests/test-cli.d.ts +8 -0
  75. package/dist/tests/test-cli.d.ts.map +1 -0
  76. package/dist/tests/test-cli.js +307 -0
  77. package/dist/tests/test-cli.js.map +1 -0
  78. package/dist/tests/test-joint-movement.d.ts +0 -0
  79. package/dist/tests/test-joint-movement.d.ts.map +0 -0
  80. package/dist/tests/test-joint-movement.js +0 -0
  81. package/dist/tests/test-joint-movement.js.map +0 -0
  82. package/dist/tests/test-skia.d.ts +0 -0
  83. package/dist/tests/test-skia.d.ts.map +0 -0
  84. package/dist/tests/test-skia.js +0 -0
  85. package/dist/tests/test-skia.js.map +0 -0
  86. package/dist/tests/test-visual-verification.d.ts +0 -0
  87. package/dist/tests/test-visual-verification.d.ts.map +0 -0
  88. package/dist/tests/test-visual-verification.js +0 -0
  89. package/dist/tests/test-visual-verification.js.map +0 -0
  90. package/dist/types.d.ts +0 -0
  91. package/dist/types.d.ts.map +0 -0
  92. package/dist/types.js +0 -0
  93. package/dist/types.js.map +0 -0
  94. package/package.json +13 -2
package/README.md CHANGED
@@ -1,154 +1,158 @@
1
- # Distark Render
2
-
3
- Rendering-agnostic character rig system with TypeScript. Render 2D character rigs to HTML Canvas with automatic image loading and caching.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install distark-render
9
- ```
10
-
11
- ## Usage
12
-
13
- ### Browser (ES Modules)
14
-
15
- ```html
16
- <canvas id="canvas" width="800" height="800"></canvas>
17
-
18
- <script type="module">
19
- import { ImageLoader, CharacterRigRenderer } from 'https://unpkg.com/distark-render';
20
-
21
- const imageLoader = new ImageLoader();
22
- const renderer = new CharacterRigRenderer(imageLoader);
23
- const canvas = document.getElementById('canvas');
24
-
25
- // Load character data
26
- const characterData = await fetch('character.json').then(r => r.json());
27
-
28
- // Render to canvas
29
- await renderer.render(canvas, characterData);
30
- </script>
31
- ```
32
-
33
- ### Node.js
34
-
35
- ```javascript
36
- import { ImageLoader, CharacterRigRenderer } from 'distark-render';
37
-
38
- const imageLoader = new ImageLoader();
39
- const renderer = new CharacterRigRenderer(imageLoader);
40
- const canvas = document.getElementById('canvas');
41
- const characterData = await fetch('character.json').then(r => r.json());
42
- await renderer.render(canvas, characterData);
43
- ```
44
-
45
- ## Features
46
-
47
- - 🎨 Rendering-agnostic architecture
48
- - 🖼️ Automatic image loading and caching
49
- - 🔄 Support for MD5 hashes and direct URLs
50
- - 👁️ Eye and mouth animation systems
51
- - ⚡ TypeScript support with full type definitions
52
- - 🌐 Works in browser and Node.js
53
-
54
- ## Testing
55
-
56
- ### Automated Test Suite
57
-
58
- Run all automated tests to verify rendering and joint movement:
59
-
60
- ```bash
61
- # Run all tests (visual verification + joint movement)
62
- npm test
63
-
64
- # Or run tests individually
65
- npm run test-visual # Eyes and mouth rendering
66
- npm run test-joints # Joint movement and limb positioning
67
- ```
68
-
69
- ### Visual Verification Test
70
-
71
- Verify that eyes and mouth are rendering correctly using automated color comparison:
72
-
73
- ```bash
74
- # Test a specific character file
75
- npm run test-visual
76
- node dist/tests/test-visual-verification.js character.json
77
- ```
78
-
79
- **What it tests:**
80
- - ✅ Left eye region has rendered content
81
- - ✅ Right eye region has rendered content
82
- - ✅ Mouth region has rendered content
83
-
84
- The test uses pixel sampling and color comparison to verify that character features are actually being rendered to the canvas. It calculates expected regions based on the rig data and checks that those regions contain pixels different from the background color.
85
-
86
- ### Joint Movement Test
87
-
88
- Verify that character joints move correctly and limbs appear in expected screen sectors:
89
-
90
- ```bash
91
- # Test joint movements
92
- npm run test-joints
93
- node dist/tests/test-joint-movement.js character.json
94
- ```
95
-
96
- **What it tests:**
97
- - ✅ **Arm Raised**: Left arm rotates upward and appears in top/middle-left sector
98
- - ✅ **Leg Forward**: Right leg moves forward and appears in middle/bottom-right sector
99
- - ✅ **Head Rotation**: Head turns and remains in top/middle-center sector
100
- - ✅ **Multiple Joints**: Arms spread and legs move simultaneously (T-pose)
101
-
102
- The test modifies joint rotation values and verifies that limbs render in the expected screen sectors by sampling pixels and checking for content (non-background pixels). This ensures the rendering pipeline correctly applies transformations to the character rig.
103
-
104
- ### Manual Testing with Command Line
105
-
106
- You can also manually test character rigs and save rendered output:
107
-
108
- ```bash
109
- # Build the project first
110
- npm run build
111
-
112
- # Run test-skia with default settings (renders tank.json)
113
- npm run test-skia
114
-
115
- # Or run directly with custom parameters:
116
- node dist/tests/test-skia.js [input.json] [output.png] [width] [height]
117
-
118
- # Examples:
119
- node dist/tests/test-skia.js tank.json output.png 1000 1000
120
- node dist/tests/test-skia.js character.json render.png 800 600
121
- ```
122
-
123
- **Parameters:**
124
- - `input.json` - Path to your character rig JSON file (default: `assets/tank.json`)
125
- - `output.png` - Output image filename (default: `output-tank.png`)
126
- - `width` - Canvas width in pixels (default: `1000`)
127
- - `height` - Canvas height in pixels (default: `1000`)
128
-
129
- The test script will:
130
- 1. Load your character rig JSON
131
- 2. Automatically fetch and cache all images
132
- 3. Render the character to a PNG file
133
- 4. Show pivot points for debugging
134
-
135
- ## API
136
-
137
- ### ImageLoader
138
-
139
- Handles loading images from URLs or MD5 hashes with automatic caching.
140
-
141
- ```typescript
142
- const imageLoader = new ImageLoader(baseHost?: string);
143
- ```
144
-
145
- ### CharacterRigRenderer
146
-
147
- Renders character rigs to canvas.
148
-
149
- ```typescript
150
- const renderer = new CharacterRigRenderer(imageLoader?: ImageLoader);
151
- await renderer.render(canvas, rigData, loadedImages?, cameraOffset?, showPivotPoints?);
152
- ```
153
-
154
-
1
+ # Distark Render
2
+
3
+ Rendering-agnostic character rig system with TypeScript. Render 2D character rigs to HTML Canvas with automatic image loading and caching.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install distark-render
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Browser (ES Modules)
14
+
15
+ ```html
16
+ <canvas id="canvas" width="800" height="800"></canvas>
17
+
18
+ <script type="module">
19
+ import { ImageLoader, CharacterRigRenderer } from 'https://unpkg.com/distark-render';
20
+
21
+ const imageLoader = new ImageLoader();
22
+ const renderer = new CharacterRigRenderer(imageLoader);
23
+ const canvas = document.getElementById('canvas');
24
+
25
+ // Load character data
26
+ const characterData = await fetch('character.json').then(r => r.json());
27
+
28
+ // Render to canvas
29
+ await renderer.render(canvas, characterData);
30
+ </script>
31
+ ```
32
+
33
+ ### Node.js
34
+
35
+ ```javascript
36
+ import { ImageLoader, CharacterRigRenderer } from 'distark-render';
37
+
38
+ const imageLoader = new ImageLoader();
39
+ const renderer = new CharacterRigRenderer(imageLoader);
40
+ const canvas = document.getElementById('canvas');
41
+ const characterData = await fetch('character.json').then(r => r.json());
42
+ await renderer.render(canvas, characterData);
43
+ ```
44
+
45
+ ## Features
46
+
47
+ - 🎨 Rendering-agnostic architecture
48
+ - 🖼️ Automatic image loading and caching
49
+ - 🔄 Support for MD5 hashes and direct URLs
50
+ - 👁️ Eye and mouth animation systems
51
+ - ⚡ TypeScript support with full type definitions
52
+ - 🌐 Works in browser and Node.js
53
+
54
+ ## Testing
55
+
56
+ ### Automated Test Suite
57
+
58
+ Run all automated tests to verify rendering and joint movement:
59
+
60
+ ```bash
61
+ # Run all tests (visual verification + joint movement)
62
+ npm test
63
+
64
+ # Or run tests individually
65
+ npm run test-visual # Eyes and mouth rendering
66
+ npm run test-joints # Joint movement and limb positioning
67
+ ```
68
+
69
+ ### Visual Verification Test
70
+
71
+ Verify that eyes and mouth are rendering correctly using automated color comparison:
72
+
73
+ ```bash
74
+ # Test a specific character file
75
+ npm run test-visual
76
+ node dist/tests/test-visual-verification.js character.json
77
+ ```
78
+
79
+ **What it tests:**
80
+ - ✅ Left eye region has rendered content
81
+ - ✅ Right eye region has rendered content
82
+ - ✅ Mouth region has rendered content
83
+
84
+ The test uses pixel sampling and color comparison to verify that character features are actually being rendered to the canvas. It calculates expected regions based on the rig data and checks that those regions contain pixels different from the background color.
85
+
86
+ ### Joint Movement Test
87
+
88
+ Verify that character joints move correctly and limbs appear in expected screen sectors:
89
+
90
+ ```bash
91
+ # Test joint movements
92
+ npm run test-joints
93
+ node dist/tests/test-joint-movement.js character.json
94
+ ```
95
+
96
+ **What it tests:**
97
+ - ✅ **Arm Raised**: Left arm rotates upward and appears in top/middle-left sector
98
+ - ✅ **Leg Forward**: Right leg moves forward and appears in middle/bottom-right sector
99
+ - ✅ **Head Rotation**: Head turns and remains in top/middle-center sector
100
+ - ✅ **Multiple Joints**: Arms spread and legs move simultaneously (T-pose)
101
+
102
+ The test modifies joint rotation values and verifies that limbs render in the expected screen sectors by sampling pixels and checking for content (non-background pixels). This ensures the rendering pipeline correctly applies transformations to the character rig.
103
+
104
+ ### Manual Testing with Command Line
105
+
106
+ You can also manually test character rigs and save rendered output:
107
+
108
+ ```bash
109
+ # Build the project first
110
+ npm run build
111
+
112
+ # Run test-skia with default settings (renders tank.json)
113
+ npm run test-skia
114
+
115
+ # Or run directly with custom parameters:
116
+ node dist/tests/test-skia.js [input.json] [output.png] [width] [height]
117
+
118
+ # Examples:
119
+ node dist/tests/test-skia.js tank.json output.png 1000 1000
120
+ node dist/tests/test-skia.js character.json render.png 800 600
121
+ ```
122
+
123
+ **Parameters:**
124
+ - `input.json` - Path to your character rig JSON file (default: `assets/tank.json`)
125
+ - `output.png` - Output image filename (default: `output-tank.png`)
126
+ - `width` - Canvas width in pixels (default: `1000`)
127
+ - `height` - Canvas height in pixels (default: `1000`)
128
+
129
+ The test script will:
130
+ 1. Load your character rig JSON
131
+ 2. Automatically fetch and cache all images
132
+ 3. Render the character to a PNG file
133
+ 4. Show pivot points for debugging
134
+
135
+ ## API
136
+
137
+ ### ImageLoader
138
+
139
+ Handles loading images from URLs or MD5 hashes with automatic caching.
140
+
141
+ ```typescript
142
+ const imageLoader = new ImageLoader(baseHost?: string);
143
+ ```
144
+
145
+ ### CharacterRigRenderer
146
+
147
+ Renders character rigs to canvas.
148
+
149
+ ```typescript
150
+ const renderer = new CharacterRigRenderer(imageLoader?: ImageLoader);
151
+ await renderer.render(canvas, rigData, loadedImages?, cameraOffset?, showPivotPoints?);
152
+ ```
153
+
154
+ ### In action
155
+ https://studyturtle.com
156
+ https://www.youtube.com/@studyturtlehq
157
+
158
+
@@ -0,0 +1,8 @@
1
+ /**
2
+ * animate command - Render animation keyframes to numbered PNGs with a manifest
3
+ *
4
+ * Usage:
5
+ * distark-check animate <rig.json> <animation.json> [-o frames/] [--width 1000] [--height 1000]
6
+ */
7
+ export declare function runAnimate(args: string[]): Promise<void>;
8
+ //# sourceMappingURL=animate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animate.d.ts","sourceRoot":"","sources":["../../cli/animate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgCH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuH9D"}
@@ -0,0 +1,121 @@
1
+ /**
2
+ * animate command - Render animation keyframes to numbered PNGs with a manifest
3
+ *
4
+ * Usage:
5
+ * distark-check animate <rig.json> <animation.json> [-o frames/] [--width 1000] [--height 1000]
6
+ */
7
+ import { SkiaRenderer } from '../modules/adapters/skiaRenderer.js';
8
+ import { expandDiffBasedAnimation, isDiffBasedFormat } from '../modules/animationDiff.js';
9
+ import { readFile, writeFile, mkdir } from 'fs/promises';
10
+ function objBounds(obj) {
11
+ return {
12
+ x: Math.round(obj.x - obj.width * obj.anchorX),
13
+ y: Math.round(obj.y - obj.height * obj.anchorY),
14
+ w: Math.round(obj.width),
15
+ h: Math.round(obj.height),
16
+ };
17
+ }
18
+ export async function runAnimate(args) {
19
+ const positional = args.filter(a => !a.startsWith('-'));
20
+ const rigFile = positional[0];
21
+ const animFile = positional[1];
22
+ if (!rigFile || !animFile) {
23
+ console.error('Usage: distark-check animate <rig.json> <animation.json> [-o frames/] [--width N] [--height N]');
24
+ process.exit(1);
25
+ }
26
+ const outIdx = args.indexOf('-o');
27
+ const outputDir = outIdx !== -1 ? args[outIdx + 1] : 'frames';
28
+ const width = parseInt(args[args.indexOf('--width') + 1]) || 1000;
29
+ const height = parseInt(args[args.indexOf('--height') + 1]) || 1000;
30
+ const rigData = JSON.parse(await readFile(rigFile, 'utf-8'));
31
+ const animRaw = JSON.parse(await readFile(animFile, 'utf-8'));
32
+ // Expand animation frames (handles both diff and full-state formats)
33
+ let frames;
34
+ if (isDiffBasedFormat(animRaw)) {
35
+ frames = expandDiffBasedAnimation(animRaw);
36
+ }
37
+ else if (Array.isArray(animRaw)) {
38
+ frames = animRaw;
39
+ }
40
+ else {
41
+ console.error('Unrecognized animation format');
42
+ process.exit(1);
43
+ }
44
+ await mkdir(outputDir, { recursive: true });
45
+ // Redirect console.log to stderr during image loading
46
+ const origLog = console.log;
47
+ console.log = (...a) => console.error(...a);
48
+ const renderer = new SkiaRenderer();
49
+ await renderer.loadImages(rigData);
50
+ console.log = origLog;
51
+ const manifest = {
52
+ rig_input: rigFile,
53
+ animation_input: animFile,
54
+ frame_count: frames.length,
55
+ output_dir: outputDir,
56
+ frames: [],
57
+ };
58
+ let prevBoundsMap = null;
59
+ for (let i = 0; i < frames.length; i++) {
60
+ const frame = frames[i];
61
+ const mergedRig = {
62
+ ...rigData,
63
+ ...frame,
64
+ rotationValues: { ...rigData.rotationValues, ...frame.rotationValues },
65
+ selfRotationValues: { ...rigData.selfRotationValues, ...frame.selfRotationValues },
66
+ dimensionValues: { ...rigData.dimensionValues, ...frame.dimensionValues },
67
+ pivotPoints: { ...rigData.pivotPoints, ...frame.pivotPoints },
68
+ zIndexValues: { ...rigData.zIndexValues, ...frame.zIndexValues },
69
+ };
70
+ const padded = String(i).padStart(3, '0');
71
+ const filename = `${outputDir}/${padded}.png`;
72
+ await renderer.renderToFile(filename, mergedRig, {
73
+ canvasWidth: width,
74
+ canvasHeight: height,
75
+ showPivots: false,
76
+ });
77
+ const renderData = renderer.compute(mergedRig, { canvasWidth: width, canvasHeight: height });
78
+ const boundsMap = {};
79
+ const currentPosMap = {};
80
+ for (const obj of renderData.objects) {
81
+ boundsMap[obj.name] = objBounds(obj);
82
+ currentPosMap[obj.name] = { x: Math.round(obj.x), y: Math.round(obj.y), rot: obj.rotation };
83
+ }
84
+ const entry = {
85
+ index: i,
86
+ file: `${padded}.png`,
87
+ character_bounds: boundsMap,
88
+ };
89
+ // Compute deltas from previous frame
90
+ if (prevBoundsMap) {
91
+ const deltas = {};
92
+ for (const [name, pos] of Object.entries(currentPosMap)) {
93
+ const prev = prevBoundsMap[name];
94
+ if (prev) {
95
+ const dx = pos.x - prev.x;
96
+ const dy = pos.y - prev.y;
97
+ const dRot = Math.round((pos.rot - prev.rot) * 180 / Math.PI * 100) / 100;
98
+ if (dx !== 0 || dy !== 0 || Math.abs(dRot) > 0.01) {
99
+ const delta = {};
100
+ if (dx !== 0 || dy !== 0)
101
+ delta.moved = { dx, dy };
102
+ if (Math.abs(dRot) > 0.01)
103
+ delta.rotated = dRot;
104
+ deltas[name] = delta;
105
+ }
106
+ }
107
+ }
108
+ if (Object.keys(deltas).length > 0) {
109
+ entry.delta_from_prev = deltas;
110
+ }
111
+ }
112
+ prevBoundsMap = currentPosMap;
113
+ manifest.frames.push(entry);
114
+ console.error(`Frame ${i}/${frames.length - 1}: ${filename}`);
115
+ }
116
+ const manifestFile = `${outputDir}/manifest.json`;
117
+ await writeFile(manifestFile, JSON.stringify(manifest, null, 2));
118
+ // Output manifest to stdout for LLM
119
+ console.log(JSON.stringify(manifest, null, 2));
120
+ }
121
+ //# sourceMappingURL=animate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"animate.js","sourceRoot":"","sources":["../../cli/animate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * diff command - Compare two rendered PNGs and output a pixel-diff image + report
3
+ *
4
+ * Usage:
5
+ * distark-check diff <before.png> <after.png> [-o diff.png] [--threshold 10]
6
+ */
7
+ export declare function runDiff(args: string[]): Promise<void>;
8
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../cli/diff.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAqI3D"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * diff command - Compare two rendered PNGs and output a pixel-diff image + report
3
+ *
4
+ * Usage:
5
+ * distark-check diff <before.png> <after.png> [-o diff.png] [--threshold 10]
6
+ */
7
+ import { readFile, writeFile } from 'fs/promises';
8
+ export async function runDiff(args) {
9
+ const positional = args.filter(a => !a.startsWith('-'));
10
+ const beforeFile = positional[0];
11
+ const afterFile = positional[1];
12
+ if (!beforeFile || !afterFile) {
13
+ console.error('Usage: distark-check diff <before.png> <after.png> [-o diff.png] [--threshold N]');
14
+ process.exit(1);
15
+ }
16
+ const outIdx = args.indexOf('-o');
17
+ const diffFile = outIdx !== -1 ? args[outIdx + 1] : 'diff.png';
18
+ const threshIdx = args.indexOf('--threshold');
19
+ const threshold = threshIdx !== -1 ? parseInt(args[threshIdx + 1]) : 10;
20
+ // Dynamic import skia-canvas
21
+ let loadImage;
22
+ let createCanvas;
23
+ try {
24
+ // @ts-ignore - Optional dependency
25
+ const mod = await import('@napi-rs/canvas');
26
+ loadImage = mod.loadImage;
27
+ createCanvas = mod.createCanvas;
28
+ }
29
+ catch {
30
+ const mod = await import('skia-canvas');
31
+ loadImage = mod.loadImage;
32
+ createCanvas = mod.Canvas
33
+ ? (w, h) => new mod.Canvas(w, h)
34
+ : mod.createCanvas;
35
+ }
36
+ // Load both images
37
+ const beforeBuf = await readFile(beforeFile);
38
+ const afterBuf = await readFile(afterFile);
39
+ const beforeImg = await loadImage(beforeBuf);
40
+ const afterImg = await loadImage(afterBuf);
41
+ const width = beforeImg.width;
42
+ const height = beforeImg.height;
43
+ if (afterImg.width !== width || afterImg.height !== height) {
44
+ console.error(`Image dimensions mismatch: ${width}x${height} vs ${afterImg.width}x${afterImg.height}`);
45
+ process.exit(1);
46
+ }
47
+ // Draw both to get pixel data
48
+ const canvasBefore = createCanvas(width, height);
49
+ const ctxBefore = canvasBefore.getContext('2d');
50
+ ctxBefore.drawImage(beforeImg, 0, 0);
51
+ const dataBefore = ctxBefore.getImageData(0, 0, width, height);
52
+ const canvasAfter = createCanvas(width, height);
53
+ const ctxAfter = canvasAfter.getContext('2d');
54
+ ctxAfter.drawImage(afterImg, 0, 0);
55
+ const dataAfter = ctxAfter.getImageData(0, 0, width, height);
56
+ // Create diff image
57
+ const canvasDiff = createCanvas(width, height);
58
+ const ctxDiff = canvasDiff.getContext('2d');
59
+ const diffData = ctxDiff.createImageData(width, height);
60
+ let changedPixels = 0;
61
+ const totalPixels = width * height;
62
+ // Track per-sector changes (3x3 grid)
63
+ const sectorW = width / 3;
64
+ const sectorH = height / 3;
65
+ const sectorChanges = new Array(9).fill(0);
66
+ const sectorTotals = new Array(9).fill(0);
67
+ const sectorNames = [
68
+ 'Top-Left', 'Top-Center', 'Top-Right',
69
+ 'Middle-Left', 'Middle-Center', 'Middle-Right',
70
+ 'Bottom-Left', 'Bottom-Center', 'Bottom-Right',
71
+ ];
72
+ for (let i = 0; i < dataBefore.data.length; i += 4) {
73
+ const pixelIdx = i / 4;
74
+ const px = pixelIdx % width;
75
+ const py = Math.floor(pixelIdx / width);
76
+ const sectorCol = Math.min(Math.floor(px / sectorW), 2);
77
+ const sectorRow = Math.min(Math.floor(py / sectorH), 2);
78
+ const sectorIdx = sectorRow * 3 + sectorCol;
79
+ sectorTotals[sectorIdx]++;
80
+ const rDiff = Math.abs(dataBefore.data[i] - dataAfter.data[i]);
81
+ const gDiff = Math.abs(dataBefore.data[i + 1] - dataAfter.data[i + 1]);
82
+ const bDiff = Math.abs(dataBefore.data[i + 2] - dataAfter.data[i + 2]);
83
+ if (rDiff > threshold || gDiff > threshold || bDiff > threshold) {
84
+ changedPixels++;
85
+ sectorChanges[sectorIdx]++;
86
+ // Red highlight for changed pixels
87
+ diffData.data[i] = 255;
88
+ diffData.data[i + 1] = 0;
89
+ diffData.data[i + 2] = 0;
90
+ diffData.data[i + 3] = 255;
91
+ }
92
+ else {
93
+ // Dimmed version of original for context
94
+ diffData.data[i] = Math.floor(dataAfter.data[i] * 0.3);
95
+ diffData.data[i + 1] = Math.floor(dataAfter.data[i + 1] * 0.3);
96
+ diffData.data[i + 2] = Math.floor(dataAfter.data[i + 2] * 0.3);
97
+ diffData.data[i + 3] = 255;
98
+ }
99
+ }
100
+ ctxDiff.putImageData(diffData, 0, 0);
101
+ // Save diff image
102
+ const buffer = await canvasDiff.toBuffer('image/png');
103
+ await writeFile(diffFile, buffer);
104
+ const changedRegions = sectorNames
105
+ .map((name, idx) => ({
106
+ sector: name,
107
+ percent_changed: sectorTotals[idx] > 0
108
+ ? Math.round(sectorChanges[idx] / sectorTotals[idx] * 10000) / 100
109
+ : 0,
110
+ }))
111
+ .filter(r => r.percent_changed > 0);
112
+ const report = {
113
+ before: beforeFile,
114
+ after: afterFile,
115
+ diff_image: diffFile,
116
+ dimensions: { width, height },
117
+ total_pixels: totalPixels,
118
+ changed_pixels: changedPixels,
119
+ percent_changed: Math.round(changedPixels / totalPixels * 10000) / 100,
120
+ changed_regions: changedRegions,
121
+ };
122
+ console.log(JSON.stringify(report, null, 2));
123
+ }
124
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../cli/diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * distark-check - CLI tool for LLM-driven rig testing
4
+ *
5
+ * Commands:
6
+ * render <rig.json> Render rig to PNG + JSON report
7
+ * verify <rig.json> Math-based sanity checks (no rendering)
8
+ * animate <rig.json> <animation.json> Render animation frames + manifest
9
+ * diff <before.png> <after.png> Pixel-diff two images
10
+ * query <image|rig> --prompt "..." Send to Gemini for visual analysis
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=distark-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distark-check.d.ts","sourceRoot":"","sources":["../../cli/distark-check.ts"],"names":[],"mappings":";AACA;;;;;;;;;GASG"}