distark-render 1.1.9 → 1.1.11

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 (156) hide show
  1. package/README.md +0 -0
  2. package/assets/tank.json +0 -0
  3. package/dist/cli/animate.d.ts +0 -0
  4. package/dist/cli/animate.d.ts.map +0 -0
  5. package/dist/cli/animate.js +0 -0
  6. package/dist/cli/animate.js.map +0 -0
  7. package/dist/cli/diff.d.ts +0 -0
  8. package/dist/cli/diff.d.ts.map +0 -0
  9. package/dist/cli/diff.js +0 -0
  10. package/dist/cli/diff.js.map +0 -0
  11. package/dist/cli/distark-check.d.ts +0 -0
  12. package/dist/cli/distark-check.d.ts.map +0 -0
  13. package/dist/cli/distark-check.js +16 -16
  14. package/dist/cli/distark-check.js.map +0 -0
  15. package/dist/cli/query.d.ts +0 -0
  16. package/dist/cli/query.d.ts.map +0 -0
  17. package/dist/cli/query.js +0 -0
  18. package/dist/cli/query.js.map +0 -0
  19. package/dist/cli/record.d.ts +0 -0
  20. package/dist/cli/record.d.ts.map +0 -0
  21. package/dist/cli/record.js +0 -0
  22. package/dist/cli/record.js.map +0 -0
  23. package/dist/cli/render.d.ts +0 -0
  24. package/dist/cli/render.d.ts.map +0 -0
  25. package/dist/cli/render.js +0 -0
  26. package/dist/cli/render.js.map +0 -0
  27. package/dist/cli/scene.d.ts +2 -12
  28. package/dist/cli/scene.d.ts.map +1 -1
  29. package/dist/cli/scene.js +4 -235
  30. package/dist/cli/scene.js.map +1 -1
  31. package/dist/cli/shared.d.ts +0 -0
  32. package/dist/cli/shared.d.ts.map +0 -0
  33. package/dist/cli/shared.js +0 -0
  34. package/dist/cli/shared.js.map +0 -0
  35. package/dist/cli/test.d.ts +0 -0
  36. package/dist/cli/test.d.ts.map +0 -0
  37. package/dist/cli/test.js +0 -0
  38. package/dist/cli/test.js.map +0 -0
  39. package/dist/cli/verify.d.ts +0 -0
  40. package/dist/cli/verify.d.ts.map +0 -0
  41. package/dist/cli/verify.js +0 -0
  42. package/dist/cli/verify.js.map +0 -0
  43. package/dist/modules/adapters/p5Renderer.d.ts +0 -0
  44. package/dist/modules/adapters/p5Renderer.d.ts.map +1 -1
  45. package/dist/modules/adapters/p5Renderer.js +40 -17
  46. package/dist/modules/adapters/p5Renderer.js.map +1 -1
  47. package/dist/modules/adapters/skiaRenderer.d.ts +2 -0
  48. package/dist/modules/adapters/skiaRenderer.d.ts.map +1 -1
  49. package/dist/modules/adapters/skiaRenderer.js +47 -16
  50. package/dist/modules/adapters/skiaRenderer.js.map +1 -1
  51. package/dist/modules/animationDiff.d.ts +0 -0
  52. package/dist/modules/animationDiff.d.ts.map +0 -0
  53. package/dist/modules/animationDiff.js +0 -0
  54. package/dist/modules/animationDiff.js.map +0 -0
  55. package/dist/modules/browserSceneRenderer.d.ts +21 -0
  56. package/dist/modules/browserSceneRenderer.d.ts.map +1 -0
  57. package/dist/modules/browserSceneRenderer.js +263 -0
  58. package/dist/modules/browserSceneRenderer.js.map +1 -0
  59. package/dist/modules/eyeSystem.d.ts +0 -0
  60. package/dist/modules/eyeSystem.d.ts.map +0 -0
  61. package/dist/modules/eyeSystem.js +0 -0
  62. package/dist/modules/eyeSystem.js.map +0 -0
  63. package/dist/modules/imageLoad.d.ts +22 -8
  64. package/dist/modules/imageLoad.d.ts.map +1 -1
  65. package/dist/modules/imageLoad.js +203 -78
  66. package/dist/modules/imageLoad.js.map +1 -1
  67. package/dist/modules/mouthSystem.d.ts +0 -0
  68. package/dist/modules/mouthSystem.d.ts.map +0 -0
  69. package/dist/modules/mouthSystem.js +0 -0
  70. package/dist/modules/mouthSystem.js.map +0 -0
  71. package/dist/modules/renderRig.d.ts +0 -0
  72. package/dist/modules/renderRig.d.ts.map +1 -1
  73. package/dist/modules/renderRig.js +40 -0
  74. package/dist/modules/renderRig.js.map +1 -1
  75. package/dist/modules/sceneRenderer.d.ts +2 -1
  76. package/dist/modules/sceneRenderer.d.ts.map +1 -1
  77. package/dist/modules/sceneRenderer.js +9 -6
  78. package/dist/modules/sceneRenderer.js.map +1 -1
  79. package/dist/tests/helpers.d.ts +0 -0
  80. package/dist/tests/helpers.d.ts.map +0 -0
  81. package/dist/tests/helpers.js +0 -0
  82. package/dist/tests/helpers.js.map +0 -0
  83. package/dist/tests/test-animation-diff-rendering.d.ts +0 -0
  84. package/dist/tests/test-animation-diff-rendering.d.ts.map +0 -0
  85. package/dist/tests/test-animation-diff-rendering.js +0 -0
  86. package/dist/tests/test-animation-diff-rendering.js.map +0 -0
  87. package/dist/tests/test-animation-diff.d.ts +0 -0
  88. package/dist/tests/test-animation-diff.d.ts.map +0 -0
  89. package/dist/tests/test-animation-diff.js +0 -0
  90. package/dist/tests/test-animation-diff.js.map +0 -0
  91. package/dist/tests/test-autofit.d.ts +0 -0
  92. package/dist/tests/test-autofit.d.ts.map +0 -0
  93. package/dist/tests/test-autofit.js +0 -0
  94. package/dist/tests/test-autofit.js.map +0 -0
  95. package/dist/tests/test-base-autofit.d.ts +0 -0
  96. package/dist/tests/test-base-autofit.d.ts.map +0 -0
  97. package/dist/tests/test-base-autofit.js +0 -0
  98. package/dist/tests/test-base-autofit.js.map +0 -0
  99. package/dist/tests/test-browser-scene.d.ts +2 -0
  100. package/dist/tests/test-browser-scene.d.ts.map +1 -0
  101. package/dist/tests/test-browser-scene.js +132 -0
  102. package/dist/tests/test-browser-scene.js.map +1 -0
  103. package/dist/tests/test-cli.d.ts +0 -0
  104. package/dist/tests/test-cli.d.ts.map +0 -0
  105. package/dist/tests/test-cli.js +0 -0
  106. package/dist/tests/test-cli.js.map +0 -0
  107. package/dist/tests/test-image-loading.d.ts +0 -0
  108. package/dist/tests/test-image-loading.d.ts.map +0 -0
  109. package/dist/tests/test-image-loading.js +0 -0
  110. package/dist/tests/test-image-loading.js.map +0 -0
  111. package/dist/tests/test-joint-movement.d.ts +0 -0
  112. package/dist/tests/test-joint-movement.d.ts.map +0 -0
  113. package/dist/tests/test-joint-movement.js +0 -0
  114. package/dist/tests/test-joint-movement.js.map +0 -0
  115. package/dist/tests/test-p5-image-types.d.ts +0 -0
  116. package/dist/tests/test-p5-image-types.d.ts.map +0 -0
  117. package/dist/tests/test-p5-image-types.js +0 -0
  118. package/dist/tests/test-p5-image-types.js.map +0 -0
  119. package/dist/tests/test-render-cache-visual.d.ts +2 -0
  120. package/dist/tests/test-render-cache-visual.d.ts.map +1 -0
  121. package/dist/tests/test-render-cache-visual.js +108 -0
  122. package/dist/tests/test-render-cache-visual.js.map +1 -0
  123. package/dist/tests/test-render-cache.d.ts +2 -0
  124. package/dist/tests/test-render-cache.d.ts.map +1 -0
  125. package/dist/tests/test-render-cache.js +124 -0
  126. package/dist/tests/test-render-cache.js.map +1 -0
  127. package/dist/tests/test-scene-object-svg-rerasterization.d.ts +2 -0
  128. package/dist/tests/test-scene-object-svg-rerasterization.d.ts.map +1 -0
  129. package/dist/tests/test-scene-object-svg-rerasterization.js +86 -0
  130. package/dist/tests/test-scene-object-svg-rerasterization.js.map +1 -0
  131. package/dist/tests/test-scene.d.ts +0 -0
  132. package/dist/tests/test-scene.d.ts.map +0 -0
  133. package/dist/tests/test-scene.js +0 -0
  134. package/dist/tests/test-scene.js.map +0 -0
  135. package/dist/tests/test-skia.d.ts +0 -0
  136. package/dist/tests/test-skia.d.ts.map +0 -0
  137. package/dist/tests/test-skia.js +0 -0
  138. package/dist/tests/test-skia.js.map +0 -0
  139. package/dist/tests/test-svg-rerasterization.d.ts +2 -0
  140. package/dist/tests/test-svg-rerasterization.d.ts.map +1 -0
  141. package/dist/tests/test-svg-rerasterization.js +97 -0
  142. package/dist/tests/test-svg-rerasterization.js.map +1 -0
  143. package/dist/tests/test-torso-pivot.d.ts +0 -0
  144. package/dist/tests/test-torso-pivot.d.ts.map +0 -0
  145. package/dist/tests/test-torso-pivot.js +0 -0
  146. package/dist/tests/test-torso-pivot.js.map +0 -0
  147. package/dist/tests/test-visual-verification.d.ts +0 -0
  148. package/dist/tests/test-visual-verification.d.ts.map +0 -0
  149. package/dist/tests/test-visual-verification.js +0 -0
  150. package/dist/tests/test-visual-verification.js.map +0 -0
  151. package/dist/types.d.ts +0 -0
  152. package/dist/types.d.ts.map +0 -0
  153. package/dist/types.js +0 -0
  154. package/dist/types.js.map +0 -0
  155. package/package.json +5 -1
  156. package/assets/presets/jumping-jack.json +0 -194
@@ -0,0 +1,132 @@
1
+ import { BrowserSceneRenderer } from '../modules/browserSceneRenderer.js';
2
+ import { assert, printSummary } from './helpers.js';
3
+ class FakeContext {
4
+ constructor() {
5
+ this.drawCalls = [];
6
+ this.fillStyle = '';
7
+ }
8
+ clearRect() { }
9
+ fillRect() { }
10
+ save() { }
11
+ restore() { }
12
+ translate() { }
13
+ rotate() { }
14
+ scale() { }
15
+ beginPath() { }
16
+ arc() { }
17
+ fill() { }
18
+ stroke() { }
19
+ drawImage(img, _x, _y, width, height) {
20
+ this.drawCalls.push({ img, width, height });
21
+ }
22
+ }
23
+ class FakeCanvas {
24
+ constructor(width, height) {
25
+ this.width = width;
26
+ this.height = height;
27
+ this.ctx = new FakeContext();
28
+ }
29
+ getContext(kind) {
30
+ return kind === '2d' ? this.ctx : null;
31
+ }
32
+ }
33
+ function makeRig(headKey) {
34
+ return {
35
+ imagePaths: {
36
+ torso: 'torso_base',
37
+ head: headKey
38
+ },
39
+ dimensionValues: {
40
+ torso: { width: 80, height: 120 },
41
+ head: { width: 60, height: 60 }
42
+ },
43
+ rotationValues: {},
44
+ selfRotationValues: {},
45
+ pivotPoints: {
46
+ root_torso: { x: 0, y: 0 },
47
+ torso_head: { x: 0, y: -100 }
48
+ },
49
+ zIndexValues: {
50
+ torso: 1,
51
+ head: 2
52
+ }
53
+ };
54
+ }
55
+ function makeWorld() {
56
+ return {
57
+ scene: { background: null },
58
+ characters: [
59
+ { id: 'Tank', xCoor: 400, yCoor: 420, width: 120, height: 220, renderScale: 1 }
60
+ ],
61
+ timeline: [
62
+ {
63
+ characterId: '__camera__',
64
+ lanes: [{
65
+ property: 'camera',
66
+ keyframes: [{ time: 0, value: { x: 1280, y: 720, width: 2560, height: 1440 }, easing: 'instant' }]
67
+ }]
68
+ },
69
+ {
70
+ characterId: 'Tank',
71
+ lanes: [
72
+ {
73
+ property: 'animation',
74
+ keyframes: [{ time: 0, value: 'wave', easing: 'instant' }]
75
+ },
76
+ {
77
+ property: 'variation',
78
+ keyframes: [{ time: 0, value: 'sad', easing: 'instant' }]
79
+ }
80
+ ]
81
+ }
82
+ ],
83
+ animations: {
84
+ wave: {
85
+ id: 'wave',
86
+ name: 'Wave',
87
+ frames: [
88
+ { rotationValues: { head: 0 } },
89
+ { rotationValues: { head: 0.4 } }
90
+ ]
91
+ }
92
+ },
93
+ variations: [
94
+ {
95
+ id: 'sad',
96
+ characterId: 'Tank',
97
+ imagePaths: { head: 'head_sad' }
98
+ }
99
+ ]
100
+ };
101
+ }
102
+ async function testBrowserSceneRendererAppliesVariationAndAnimation() {
103
+ console.log('\nTest: BrowserSceneRenderer applies variation and animation');
104
+ const fakeCanvas = new FakeCanvas(160, 120);
105
+ const canvas = fakeCanvas;
106
+ const rigDataMap = { Tank: makeRig('head_base') };
107
+ const world = makeWorld();
108
+ const sadHeadImage = { width: 60, height: 60, key: 'head_sad' };
109
+ const renderer = new BrowserSceneRenderer(world, rigDataMap, {
110
+ loadedImagesByCharacter: {
111
+ Tank: {
112
+ torso_base: { width: 80, height: 120 },
113
+ head_base: { width: 60, height: 60 },
114
+ head_sad: sadHeadImage
115
+ }
116
+ }
117
+ });
118
+ await renderer.renderFrame(canvas, 0);
119
+ assert(fakeCanvas.ctx.drawCalls.length >= 2, `Expected at least 2 draw calls, got ${fakeCanvas.ctx.drawCalls.length}`);
120
+ assert(fakeCanvas.ctx.drawCalls.some(call => call.img === sadHeadImage), 'Variation head image should be rendered alongside animation');
121
+ }
122
+ async function run() {
123
+ try {
124
+ await testBrowserSceneRendererAppliesVariationAndAnimation();
125
+ }
126
+ catch (error) {
127
+ console.error(error);
128
+ }
129
+ printSummary();
130
+ }
131
+ run();
132
+ //# sourceMappingURL=test-browser-scene.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-browser-scene.js","sourceRoot":"","sources":["../../tests/test-browser-scene.ts"],"names":[],"mappings":"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"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-render-cache-visual.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-render-cache-visual.d.ts","sourceRoot":"","sources":["../../tests/test-render-cache-visual.ts"],"names":[],"mappings":""}
@@ -0,0 +1,108 @@
1
+ import { CharacterRigRenderer } from '../modules/renderRig.js';
2
+ import { ImageLoader } from '../modules/imageLoad.js';
3
+ import { mkdir } from 'fs/promises';
4
+ class FakeImageLoader extends ImageLoader {
5
+ constructor(imageStore) {
6
+ super('http://example.test');
7
+ this.imageStore = imageStore;
8
+ }
9
+ async loadAllRigImages(rigData, useCache = true) {
10
+ const hashes = this['collectImageHashes'](rigData, useCache);
11
+ for (const hash of hashes) {
12
+ const image = this.imageStore[hash];
13
+ if (image) {
14
+ this.cacheImage(hash, image);
15
+ }
16
+ }
17
+ const result = {};
18
+ this.getImageCache().forEach((img, key) => { result[key] = img; });
19
+ return result;
20
+ }
21
+ }
22
+ async function createCanvas(width, height) {
23
+ try {
24
+ // @ts-ignore optional dependency
25
+ const module = await import('@napi-rs/canvas');
26
+ return module.createCanvas(width, height);
27
+ }
28
+ catch {
29
+ // @ts-ignore optional dependency
30
+ const module = await import('skia-canvas');
31
+ return module.Canvas ? new module.Canvas(width, height) : module.createCanvas(width, height);
32
+ }
33
+ }
34
+ async function makeSolidImage(color, width, height) {
35
+ const canvas = await createCanvas(width, height);
36
+ const ctx = canvas.getContext('2d');
37
+ ctx.fillStyle = color;
38
+ ctx.fillRect(0, 0, width, height);
39
+ return canvas;
40
+ }
41
+ function makeRig(headKey) {
42
+ return {
43
+ imagePaths: {
44
+ torso: 'torso_base',
45
+ head: headKey
46
+ },
47
+ dimensionValues: {
48
+ torso: { width: 100, height: 140 },
49
+ head: { width: 80, height: 80 }
50
+ },
51
+ rotationValues: {},
52
+ selfRotationValues: {},
53
+ pivotPoints: {
54
+ root_torso: { x: 0, y: 0 },
55
+ torso_head: { x: 0, y: -110 }
56
+ },
57
+ zIndexValues: {
58
+ torso: 1,
59
+ head: 2
60
+ }
61
+ };
62
+ }
63
+ function countColorPixels(imageData, predicate) {
64
+ let count = 0;
65
+ for (let i = 0; i < imageData.data.length; i += 4) {
66
+ const [r, g, b, a] = [
67
+ imageData.data[i],
68
+ imageData.data[i + 1],
69
+ imageData.data[i + 2],
70
+ imageData.data[i + 3]
71
+ ];
72
+ if (predicate(r, g, b, a))
73
+ count++;
74
+ }
75
+ return count;
76
+ }
77
+ async function main() {
78
+ await mkdir('test-outputs', { recursive: true });
79
+ const images = {
80
+ torso_base: await makeSolidImage('#888888', 100, 140),
81
+ head_one: await makeSolidImage('#ff0000', 80, 80),
82
+ head_two: await makeSolidImage('#0000ff', 80, 80)
83
+ };
84
+ const renderer = new CharacterRigRenderer(new FakeImageLoader(images));
85
+ const rigOne = makeRig('head_one');
86
+ const rigTwo = makeRig('head_two');
87
+ const canvasOne = await createCanvas(300, 360);
88
+ await renderer.render(canvasOne, rigOne, undefined, { x: 0, y: 0 }, false, { autoFit: false });
89
+ await canvasOne.saveAs('test-outputs/cache-render-first.png');
90
+ const canvasTwo = await createCanvas(300, 360);
91
+ await renderer.render(canvasTwo, rigTwo, undefined, { x: 0, y: 0 }, false, { autoFit: false });
92
+ await canvasTwo.saveAs('test-outputs/cache-render-second.png');
93
+ const ctx = canvasTwo.getContext('2d');
94
+ const imageData = ctx.getImageData(0, 0, canvasTwo.width, canvasTwo.height);
95
+ const bluePixels = countColorPixels(imageData, (r, g, b, a) => a > 0 && b > 180 && r < 80 && g < 80);
96
+ if (bluePixels === 0) {
97
+ throw new Error('Expected second render to contain blue head pixels, found none');
98
+ }
99
+ console.log('Saved visual outputs:');
100
+ console.log(' test-outputs/cache-render-first.png');
101
+ console.log(' test-outputs/cache-render-second.png');
102
+ console.log(`Blue head pixels in second render: ${bluePixels}`);
103
+ }
104
+ main().catch(error => {
105
+ console.error(error);
106
+ process.exit(1);
107
+ });
108
+ //# sourceMappingURL=test-render-cache-visual.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-render-cache-visual.js","sourceRoot":"","sources":["../../tests/test-render-cache-visual.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-render-cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-render-cache.d.ts","sourceRoot":"","sources":["../../tests/test-render-cache.ts"],"names":[],"mappings":""}
@@ -0,0 +1,124 @@
1
+ import { CharacterRigRenderer } from '../modules/renderRig.js';
2
+ import { ImageLoader } from '../modules/imageLoad.js';
3
+ import { assert, printSummary } from './helpers.js';
4
+ class FakeContext {
5
+ constructor() {
6
+ this.drawCalls = [];
7
+ this.fillStyle = '';
8
+ }
9
+ clearRect() { }
10
+ fillRect() { }
11
+ save() { }
12
+ restore() { }
13
+ translate() { }
14
+ rotate() { }
15
+ scale() { }
16
+ beginPath() { }
17
+ arc() { }
18
+ fill() { }
19
+ stroke() { }
20
+ drawImage(img, _x, _y, width, height) {
21
+ this.drawCalls.push({ img, width, height });
22
+ }
23
+ }
24
+ class FakeCanvas {
25
+ constructor(width, height) {
26
+ this.width = width;
27
+ this.height = height;
28
+ this.ctx = new FakeContext();
29
+ }
30
+ getContext(kind) {
31
+ return kind === '2d' ? this.ctx : null;
32
+ }
33
+ }
34
+ class FakeImageLoader extends ImageLoader {
35
+ constructor(imageStore) {
36
+ super('http://example.test');
37
+ this.loadCount = 0;
38
+ this.imageStore = imageStore;
39
+ }
40
+ async loadAllRigImages(rigData, useCache = true) {
41
+ this.loadCount++;
42
+ const hashes = this['collectImageHashes'](rigData, useCache);
43
+ for (const hash of hashes) {
44
+ const image = this.imageStore[hash];
45
+ if (image) {
46
+ this.cacheImage(hash, image);
47
+ }
48
+ }
49
+ const result = {};
50
+ this.getImageCache().forEach((img, key) => { result[key] = img; });
51
+ return result;
52
+ }
53
+ }
54
+ function makeRig(headKey) {
55
+ return {
56
+ imagePaths: {
57
+ torso: 'torso_base',
58
+ head: headKey,
59
+ leftEyeImage: 'left_eye',
60
+ rightEyeImage: 'right_eye'
61
+ },
62
+ eyes: {
63
+ leftEyeImage: 'left_eye',
64
+ leftEyeXCoor: -18,
65
+ leftEyeYCoor: -120,
66
+ leftEyeImageWidth: 40,
67
+ leftEyeImageHeight: 40,
68
+ rightEyeImage: 'right_eye',
69
+ rightEyeXCoor: 18,
70
+ rightEyeYCoor: -120,
71
+ rightEyeImageWidth: 40,
72
+ rightEyeImageHeight: 40
73
+ },
74
+ dimensionValues: {
75
+ torso: { width: 80, height: 120 },
76
+ head: { width: 60, height: 60 }
77
+ },
78
+ rotationValues: {},
79
+ selfRotationValues: {},
80
+ pivotPoints: {
81
+ root_torso: { x: 0, y: 0 },
82
+ torso_head: { x: 0, y: -100 }
83
+ },
84
+ zIndexValues: {
85
+ torso: 1,
86
+ head: 2,
87
+ leftEye: 3,
88
+ rightEye: 4
89
+ }
90
+ };
91
+ }
92
+ async function testRendererLoadsMissingImagesWhenCacheAlreadyWarm() {
93
+ console.log('\nTest: render loads missing rig images when cache is already warm');
94
+ const images = {
95
+ torso_base: { key: 'torso' },
96
+ head_one: { key: 'head_one' },
97
+ head_two: { key: 'head_two' },
98
+ left_eye: { key: 'left_eye' },
99
+ right_eye: { key: 'right_eye' }
100
+ };
101
+ const loader = new FakeImageLoader(images);
102
+ const renderer = new CharacterRigRenderer(loader);
103
+ const rigOne = makeRig('head_one');
104
+ const rigTwo = makeRig('head_two');
105
+ const canvasOne = new FakeCanvas(200, 240);
106
+ await renderer.render(canvasOne, rigOne, undefined, { x: 0, y: 0 }, false, { autoFit: false });
107
+ assert(loader.loadCount === 1, `First render should load rig images once, got ${loader.loadCount}`);
108
+ assert(canvasOne.ctx.drawCalls.some((call) => call.img === images.head_one), 'First render should draw first head image');
109
+ const canvasTwo = new FakeCanvas(200, 240);
110
+ await renderer.render(canvasTwo, rigTwo, undefined, { x: 0, y: 0 }, false, { autoFit: false });
111
+ assert(loader.loadCount === 2, `Second render should request missing images for second rig, got ${loader.loadCount}`);
112
+ assert(canvasTwo.ctx.drawCalls.some((call) => call.img === images.head_two), 'Second render should draw second head image');
113
+ }
114
+ async function run() {
115
+ try {
116
+ await testRendererLoadsMissingImagesWhenCacheAlreadyWarm();
117
+ }
118
+ catch (error) {
119
+ console.error(error);
120
+ }
121
+ printSummary();
122
+ }
123
+ run();
124
+ //# sourceMappingURL=test-render-cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-render-cache.js","sourceRoot":"","sources":["../../tests/test-render-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-scene-object-svg-rerasterization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-scene-object-svg-rerasterization.d.ts","sourceRoot":"","sources":["../../tests/test-scene-object-svg-rerasterization.ts"],"names":[],"mappings":""}
@@ -0,0 +1,86 @@
1
+ import { SceneEngine } from '../modules/sceneRenderer.js';
2
+ import { SkiaImageLoader } from '../modules/adapters/skiaRenderer.js';
3
+ import { assert, printSummary } from './helpers.js';
4
+ class FakeContext {
5
+ constructor() {
6
+ this.drawCalls = [];
7
+ }
8
+ save() { }
9
+ restore() { }
10
+ translate() { }
11
+ rotate() { }
12
+ drawImage(img, _x, _y, width, height) {
13
+ this.drawCalls.push({ img, width, height });
14
+ }
15
+ }
16
+ class FakeObjectLoader extends SkiaImageLoader {
17
+ constructor() {
18
+ super('http://example.test');
19
+ }
20
+ async loadImageAsync(key, _imageData) {
21
+ const cached = this.getCachedImage(key);
22
+ if (cached) {
23
+ return cached;
24
+ }
25
+ const initialRaster = { width: 24, height: 24, key: 'initial' };
26
+ this.attachSvgMetadata(initialRaster, '<svg width="24" height="24"></svg>', 24, 24, 24, 24);
27
+ this.cacheImage(key, initialRaster);
28
+ return initialRaster;
29
+ }
30
+ async createSvgCanvas(svgSource, targetWidth, targetHeight) {
31
+ const upgradedRaster = {
32
+ width: targetWidth,
33
+ height: targetHeight,
34
+ key: `upgraded-${targetWidth}x${targetHeight}`,
35
+ };
36
+ this.attachSvgMetadata(upgradedRaster, svgSource, 24, 24, targetWidth, targetHeight);
37
+ return upgradedRaster;
38
+ }
39
+ }
40
+ async function main() {
41
+ console.log('\n=== Scene Object SVG Re-rasterization Tests ===\n');
42
+ const world = { scene: { background: null }, characters: [], objects: [], timeline: [] };
43
+ const engine = new SceneEngine(world, {});
44
+ const loader = new FakeObjectLoader();
45
+ engine.objectImageLoader = loader;
46
+ engine.objectLoadedImages = {};
47
+ const ctx = new FakeContext();
48
+ const objectSource = 'data:image/svg+xml;charset=utf-8,%3Csvg%20width%3D%2224%22%20height%3D%2224%22%3E%3C%2Fsvg%3E';
49
+ await engine.drawWorldObject(ctx, {
50
+ id: 'prop',
51
+ frontImage: objectSource,
52
+ xCoor: 100,
53
+ yCoor: 100,
54
+ width: 24,
55
+ height: 24,
56
+ });
57
+ const initialAsset = ctx.drawCalls[0]?.img;
58
+ assert(initialAsset?.key === 'initial', 'Initial object draw uses the first cached SVG raster');
59
+ await engine.drawWorldObject(ctx, {
60
+ id: 'prop',
61
+ frontImage: objectSource,
62
+ xCoor: 100,
63
+ yCoor: 100,
64
+ width: 25,
65
+ height: 25,
66
+ });
67
+ assert(ctx.drawCalls[1]?.img === initialAsset, 'First upscale draw uses the current raster while an upgrade is requested');
68
+ await loader.waitForPendingImageUpgrades();
69
+ await engine.drawWorldObject(ctx, {
70
+ id: 'prop',
71
+ frontImage: objectSource,
72
+ xCoor: 100,
73
+ yCoor: 100,
74
+ width: 25,
75
+ height: 25,
76
+ });
77
+ const upgradedAsset = ctx.drawCalls[2]?.img;
78
+ assert(upgradedAsset !== initialAsset, 'Later object draw swaps to the regenerated SVG raster');
79
+ assert(upgradedAsset?.width >= 25 && upgradedAsset?.height >= 25, 'Any object upscale immediately regenerates a larger SVG raster');
80
+ printSummary();
81
+ }
82
+ main().catch((error) => {
83
+ console.error(error);
84
+ process.exit(1);
85
+ });
86
+ //# sourceMappingURL=test-scene-object-svg-rerasterization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-scene-object-svg-rerasterization.js","sourceRoot":"","sources":["../../tests/test-scene-object-svg-rerasterization.ts"],"names":[],"mappings":"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"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test-svg-rerasterization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-svg-rerasterization.d.ts","sourceRoot":"","sources":["../../tests/test-svg-rerasterization.ts"],"names":[],"mappings":""}