fragment-tools 0.1.13 → 0.1.15

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 (184) hide show
  1. package/.prettierignore +1 -2
  2. package/.prettierrc +23 -7
  3. package/README.md +28 -9
  4. package/bin/index.js +70 -10
  5. package/package.json +14 -6
  6. package/src/cli/build.js +125 -0
  7. package/src/cli/create.js +238 -0
  8. package/src/cli/createConfig.js +82 -0
  9. package/src/cli/createFragmentFile.js +70 -0
  10. package/src/cli/getEntries.js +85 -0
  11. package/src/cli/log.js +36 -24
  12. package/src/cli/plugins/check-dependencies.js +88 -42
  13. package/src/cli/plugins/hot-shader-replacement.js +408 -0
  14. package/src/cli/plugins/hot-sketch-reload.js +21 -25
  15. package/src/cli/plugins/save.js +101 -0
  16. package/src/cli/preview.js +55 -0
  17. package/src/cli/prompts.js +260 -0
  18. package/src/cli/run.js +131 -0
  19. package/src/cli/templates/blank/index.js +33 -0
  20. package/src/cli/templates/blank/meta.json +4 -0
  21. package/src/cli/templates/default/index.js +39 -0
  22. package/src/cli/templates/default/meta.json +5 -0
  23. package/src/cli/templates/fragment-gl/index.js +37 -0
  24. package/src/cli/templates/fragment-gl/meta.json +4 -0
  25. package/src/cli/templates/p5/index.js +32 -0
  26. package/src/cli/templates/p5/meta.json +5 -0
  27. package/src/cli/templates/p5-webgl/fragment.fs +14 -0
  28. package/src/cli/templates/p5-webgl/index.js +67 -0
  29. package/src/cli/templates/p5-webgl/meta.json +5 -0
  30. package/src/cli/templates/three-fragment/fragment.fs +10 -0
  31. package/src/cli/templates/three-fragment/index.js +95 -0
  32. package/src/cli/templates/three-fragment/meta.json +5 -0
  33. package/src/cli/templates/three-orthographic/index.js +55 -0
  34. package/src/cli/templates/three-orthographic/meta.json +5 -0
  35. package/src/cli/templates/three-perspective/index.js +52 -0
  36. package/src/cli/templates/three-perspective/meta.json +5 -0
  37. package/src/cli/utils.js +70 -0
  38. package/src/cli/ws.js +87 -78
  39. package/src/client/app/App.svelte +3 -3
  40. package/src/client/app/client.js +55 -39
  41. package/src/client/app/components/IconCross.svelte +18 -18
  42. package/src/client/app/components/Init.svelte +40 -8
  43. package/src/client/app/components/KeyBinding.svelte +22 -22
  44. package/src/client/app/helpers.js +42 -0
  45. package/src/client/app/hooks.js +20 -0
  46. package/src/client/app/inputs/Input.js +9 -9
  47. package/src/client/app/inputs/Keyboard.js +13 -15
  48. package/src/client/app/inputs/MIDI.js +14 -15
  49. package/src/client/app/inputs/Mouse.js +1 -1
  50. package/src/client/app/inputs/Webcam.js +89 -88
  51. package/src/client/app/lib/canvas-recorder/CanvasRecorder.js +41 -21
  52. package/src/client/app/lib/canvas-recorder/FrameRecorder.js +7 -6
  53. package/src/client/app/lib/canvas-recorder/H264Recorder.js +45 -0
  54. package/src/client/app/lib/canvas-recorder/MP4Recorder.js +7 -9
  55. package/src/client/app/lib/canvas-recorder/WebMRecorder.js +3 -4
  56. package/src/client/app/lib/canvas-recorder/mp4.js +1649 -15
  57. package/src/client/app/lib/canvas-recorder/utils.js +33 -17
  58. package/src/client/app/lib/gl/Geometry.js +11 -8
  59. package/src/client/app/lib/gl/Program.js +38 -19
  60. package/src/client/app/lib/gl/Renderer.js +163 -156
  61. package/src/client/app/lib/gl/Texture.js +113 -85
  62. package/src/client/app/lib/gl/index.js +12 -12
  63. package/src/client/app/lib/gl/utils.js +1 -3
  64. package/src/client/app/lib/helpers/frameDebounce.js +30 -30
  65. package/src/client/app/lib/loader/index.js +10 -10
  66. package/src/client/app/lib/loader/loadImage.js +15 -15
  67. package/src/client/app/lib/loader/loadScript.js +1 -1
  68. package/src/client/app/lib/paper-sizes.js +75 -76
  69. package/src/client/app/lib/presets.js +25 -5
  70. package/src/client/app/lib/tempo/Analyser.js +18 -17
  71. package/src/client/app/lib/tempo/Range.js +15 -12
  72. package/src/client/app/lib/tempo/index.js +34 -27
  73. package/src/client/app/modules/AudioAnalyser/Range.svelte +69 -72
  74. package/src/client/app/modules/AudioAnalyser/Spectrum.svelte +20 -19
  75. package/src/client/app/modules/AudioAnalyser.svelte +52 -35
  76. package/src/client/app/modules/Console/ConsoleLine.svelte +193 -172
  77. package/src/client/app/modules/Console.svelte +76 -74
  78. package/src/client/app/modules/Exports.svelte +62 -43
  79. package/src/client/app/modules/MidiPanel.svelte +100 -101
  80. package/src/client/app/modules/Monitor.svelte +57 -57
  81. package/src/client/app/modules/Params.svelte +128 -103
  82. package/src/client/app/renderers/2DRenderer.js +3 -3
  83. package/src/client/app/renderers/FragmentRenderer.js +30 -23
  84. package/src/client/app/renderers/P5GLRenderer.js +144 -0
  85. package/src/client/app/renderers/P5Renderer.js +10 -7
  86. package/src/client/app/renderers/THREERenderer.js +136 -94
  87. package/src/client/app/stores/audioAnalysis.js +3 -4
  88. package/src/client/app/stores/console.js +9 -10
  89. package/src/client/app/stores/errors.js +1 -1
  90. package/src/client/app/stores/exports.js +36 -20
  91. package/src/client/app/stores/index.js +2 -2
  92. package/src/client/app/stores/layout.js +143 -138
  93. package/src/client/app/stores/multisampling.js +4 -4
  94. package/src/client/app/stores/props.js +76 -13
  95. package/src/client/app/stores/renderers.js +26 -15
  96. package/src/client/app/stores/rendering.js +108 -89
  97. package/src/client/app/stores/sketches.js +7 -9
  98. package/src/client/app/stores/time.js +18 -18
  99. package/src/client/app/stores/utils.js +95 -38
  100. package/src/client/app/transitions/fade.js +3 -3
  101. package/src/client/app/transitions/index.js +6 -7
  102. package/src/client/app/transitions/splitX.js +2 -2
  103. package/src/client/app/transitions/splitY.js +2 -2
  104. package/src/client/app/triggers/Keyboard.js +88 -79
  105. package/src/client/app/triggers/MIDI.js +110 -84
  106. package/src/client/app/triggers/Mouse.js +73 -65
  107. package/src/client/app/triggers/Trigger.js +59 -58
  108. package/src/client/app/triggers/index.js +7 -7
  109. package/src/client/app/triggers/shared.js +5 -5
  110. package/src/client/app/ui/Build.svelte +70 -71
  111. package/src/client/app/ui/ErrorOverlay.svelte +118 -104
  112. package/src/client/app/ui/Field.svelte +393 -258
  113. package/src/client/app/ui/FieldGroup.svelte +106 -94
  114. package/src/client/app/ui/FieldSection.svelte +127 -116
  115. package/src/client/app/ui/FieldSpace.svelte +29 -30
  116. package/src/client/app/ui/FieldTrigger.svelte +256 -244
  117. package/src/client/app/ui/FieldTriggers.svelte +46 -46
  118. package/src/client/app/ui/FloatingParams.svelte +29 -30
  119. package/src/client/app/ui/Layout.svelte +31 -32
  120. package/src/client/app/ui/LayoutColumn.svelte +4 -4
  121. package/src/client/app/ui/LayoutComponent.svelte +239 -225
  122. package/src/client/app/ui/LayoutResizer.svelte +195 -176
  123. package/src/client/app/ui/LayoutRoot.svelte +6 -6
  124. package/src/client/app/ui/LayoutRow.svelte +4 -4
  125. package/src/client/app/ui/LayoutToolbar.svelte +191 -194
  126. package/src/client/app/ui/Module.svelte +134 -135
  127. package/src/client/app/ui/ModuleHeaderAction.svelte +81 -78
  128. package/src/client/app/ui/ModuleHeaderButton.svelte +12 -12
  129. package/src/client/app/ui/ModuleHeaderSelect.svelte +47 -37
  130. package/src/client/app/ui/ModuleRenderer.svelte +26 -27
  131. package/src/client/app/ui/OutputRenderer.svelte +112 -105
  132. package/src/client/app/ui/ParamsMultisampling.svelte +96 -95
  133. package/src/client/app/ui/ParamsOutput.svelte +130 -113
  134. package/src/client/app/ui/Preview.svelte +7 -8
  135. package/src/client/app/ui/SelectChevrons.svelte +27 -15
  136. package/src/client/app/ui/SketchRenderer.svelte +780 -667
  137. package/src/client/app/ui/SketchSelect.svelte +50 -44
  138. package/src/client/app/ui/fields/ButtonInput.svelte +61 -48
  139. package/src/client/app/ui/fields/CheckboxInput.svelte +67 -61
  140. package/src/client/app/ui/fields/ColorInput.svelte +294 -238
  141. package/src/client/app/ui/fields/FieldInputRow.svelte +8 -8
  142. package/src/client/app/ui/fields/ImageInput.svelte +123 -121
  143. package/src/client/app/ui/fields/Input.svelte +100 -111
  144. package/src/client/app/ui/fields/IntervalInput.svelte +268 -0
  145. package/src/client/app/ui/fields/ListInput.svelte +96 -96
  146. package/src/client/app/ui/fields/NumberInput.svelte +120 -116
  147. package/src/client/app/ui/fields/ProgressInput.svelte +99 -73
  148. package/src/client/app/ui/fields/Select.svelte +137 -124
  149. package/src/client/app/ui/fields/TextInput.svelte +10 -11
  150. package/src/client/app/ui/fields/VectorInput.svelte +86 -82
  151. package/src/client/app/utils/canvas.utils.js +189 -208
  152. package/src/client/app/utils/color.utils.js +138 -101
  153. package/src/client/app/utils/fields.utils.js +131 -0
  154. package/src/client/app/utils/file.utils.js +209 -37
  155. package/src/client/app/utils/glsl.utils.js +2 -2
  156. package/src/client/app/utils/glslErrors.js +49 -31
  157. package/src/client/app/utils/index.js +32 -29
  158. package/src/client/app/utils/math.utils.js +14 -10
  159. package/src/client/index.html +16 -16
  160. package/src/client/main.js +4 -4
  161. package/src/client/public/css/global.css +26 -16
  162. package/src/cli/db.js +0 -17
  163. package/src/cli/index.js +0 -198
  164. package/src/cli/plugins/db.js +0 -12
  165. package/src/cli/plugins/hot-shader-reload.js +0 -86
  166. package/src/cli/plugins/screenshot.js +0 -46
  167. package/src/cli/server.js +0 -153
  168. package/src/cli/templates/2d.js +0 -15
  169. package/src/cli/templates/blank.js +0 -13
  170. package/src/cli/templates/fragment.js +0 -18
  171. package/src/cli/templates/index.js +0 -27
  172. package/src/cli/templates/p5.js +0 -13
  173. package/src/cli/templates/three-fragment.js +0 -53
  174. package/src/cli/templates/three-orthographic.js +0 -23
  175. package/src/cli/templates/three-perspective.js +0 -20
  176. package/src/client/app/lib/canvas-recorder/FFMPEGRecorder.js +0 -56
  177. package/src/client/app/utils/props.utils.js +0 -51
  178. package/src/client/public/fonts/Inter-Bold.woff2 +0 -0
  179. package/src/client/public/fonts/Inter-Italic.woff2 +0 -0
  180. package/src/client/public/fonts/Inter-Regular.woff2 +0 -0
  181. package/src/client/public/fonts/Inter-SemiBold.woff2 +0 -0
  182. package/src/client/public/js/ffmpeg.min.js +0 -2
  183. package/src/client/public/js/ffmpeg.min.js.map +0 -1
  184. /package/src/cli/templates/{fragment.fs → fragment-gl/fragment.fs} +0 -0
@@ -1,131 +1,134 @@
1
- import { writable, get } from "svelte/store";
2
- import { getStore, createStore } from "./utils";
3
- import { onMount } from "svelte";
4
-
5
- export const tree = getStore("layout.current", {}, {
6
- persist: !__BUILD__
7
- });
1
+ import { writable, get } from 'svelte/store';
2
+ import { getStore, createStore } from './utils';
3
+ import { onMount } from 'svelte';
4
+
5
+ export const tree = getStore(
6
+ 'layout.current',
7
+ {},
8
+ {
9
+ persist: !__BUILD__,
10
+ },
11
+ );
8
12
 
9
13
  export const layout = createStore('layout', {
10
- editing: false,
11
- previewing: false,
12
- registerChild: (component, children) => {
13
- onMount(() => {
14
- component.children = children();
15
-
16
- if (component.root) {
17
- tree.set(cleanNodes(component));
18
- }
19
- });
20
- },
14
+ editing: false,
15
+ previewing: false,
16
+ registerChild: (component, children) => {
17
+ onMount(() => {
18
+ component.children = children();
19
+
20
+ if (component.root) {
21
+ tree.set(cleanNodes(component));
22
+ }
23
+ });
24
+ },
21
25
  });
22
26
 
23
27
  function cleanNodes(value) {
24
- return JSON.parse(JSON.stringify(value, (key, value) => {
25
- if (!(value instanceof HTMLElement)) {
26
- return value;
27
- }
28
- }));
28
+ return JSON.parse(
29
+ JSON.stringify(value, (key, value) => {
30
+ if (!(value instanceof HTMLElement)) {
31
+ return value;
32
+ }
33
+ }),
34
+ );
29
35
  }
30
36
 
31
37
  export function traverse(fn = () => {}, node = get(tree)) {
32
- const { children = [] } = node;
38
+ const { children = [] } = node;
33
39
 
34
- fn(node);
40
+ fn(node);
35
41
 
36
- for (let i = 0; i < children.length; i++) {
37
- const child = children[i];
38
- traverse(fn, child);
39
- }
40
- };
42
+ for (let i = 0; i < children.length; i++) {
43
+ const child = children[i];
44
+ traverse(fn, child);
45
+ }
46
+ }
41
47
 
42
48
  export const replaceChildren = (component, newChildren) => {
43
- tree.update((t) => {
44
- traverse((c) => {
45
- if (c.id === component.id) {
46
- c.children = newChildren;
47
- }
48
- }, t);
49
-
50
- return t;
51
- });
49
+ tree.update((t) => {
50
+ traverse((c) => {
51
+ if (c.id === component.id) {
52
+ c.children = newChildren;
53
+ }
54
+ }, t);
55
+
56
+ return t;
57
+ });
52
58
  };
53
59
 
54
60
  export const swapRoot = (newRoot) => {
55
- tree.update((t) => {
56
- traverse((c) => {
57
- if (!c.root && c.type !== "module") {
58
- c.depth = c.depth + 1;
59
- }
60
- }, newRoot);
61
-
62
- return newRoot;
63
- })
61
+ tree.update((t) => {
62
+ traverse((c) => {
63
+ if (!c.root && c.type !== 'module') {
64
+ c.depth = c.depth + 1;
65
+ }
66
+ }, newRoot);
67
+
68
+ return newRoot;
69
+ });
64
70
  };
65
71
 
66
72
  export const addSibling = (component, sibling) => {
67
- tree.update((t) => {
68
- traverse((c) => {
69
- if (c.id === component.parent) {
70
- const index = c.children.findIndex( k => k.id === component.id);
73
+ tree.update((t) => {
74
+ traverse((c) => {
75
+ if (c.id === component.parent) {
76
+ const index = c.children.findIndex(
77
+ (k) => k.id === component.id,
78
+ );
71
79
 
72
- const { size } = c.children[index];
73
- c.children[index].size = size * 0.5;
74
- sibling.size = size * 0.5;
80
+ const { size } = c.children[index];
81
+ c.children[index].size = size * 0.5;
82
+ sibling.size = size * 0.5;
75
83
 
76
- const newChildren = [
77
- ...c.children,
78
- ];
84
+ const newChildren = [...c.children];
79
85
 
80
- newChildren.splice(index + 1, 0, sibling);
86
+ newChildren.splice(index + 1, 0, sibling);
81
87
 
82
- c.children = newChildren;
83
- }
84
- });
88
+ c.children = newChildren;
89
+ }
90
+ });
85
91
 
86
- return t;
87
- })
92
+ return t;
93
+ });
88
94
  };
89
95
 
90
96
  export const addChildren = (component, newChild) => {
91
- tree.update((t) => {
92
- traverse((c) => {
93
- if (c.id === component.id) {
94
- c.children = [
95
- ...c.children,
96
- newChild,
97
- ];
98
- }
99
- }, t);
100
-
101
- return t;
102
- })
97
+ tree.update((t) => {
98
+ traverse((c) => {
99
+ if (c.id === component.id) {
100
+ c.children = [...c.children, newChild];
101
+ }
102
+ }, t);
103
+
104
+ return t;
105
+ });
103
106
  };
104
107
 
105
108
  export const remove = (node) => {
106
- tree.update((t) => {
107
- traverse((c) => {
108
- const { children = [] } = c;
109
- const childIndex = children.findIndex( k => k.id === node.id);
109
+ tree.update((t) => {
110
+ traverse((c) => {
111
+ const { children = [] } = c;
112
+ const childIndex = children.findIndex((k) => k.id === node.id);
110
113
 
111
- if (childIndex >= 0) {
112
- const newChildren = [...children];
113
- newChildren.splice(childIndex, 1);
114
+ if (childIndex >= 0) {
115
+ const newChildren = [...children];
116
+ newChildren.splice(childIndex, 1);
114
117
 
115
- newChildren.forEach((k) => {
116
- k.size = 1. / newChildren.length;
117
- });
118
+ newChildren.forEach((k) => {
119
+ k.size = 1 / newChildren.length;
120
+ });
118
121
 
119
- if (newChildren.length === 0) {
120
- remove(c);
121
- }
122
+ if (newChildren.length === 0) {
123
+ remove(c);
124
+ }
122
125
 
123
- c.children = newChildren;
124
- }
125
- }, t);
126
+ c.children = newChildren;
127
+ }
128
+ }, t);
126
129
 
127
- return t;
128
- });
130
+ return t;
131
+ });
129
132
  };
130
133
 
131
134
  /**
@@ -134,54 +137,56 @@ export const remove = (node) => {
134
137
  * @param {object} newProperties - the new properties to assign to the component
135
138
  */
136
139
  export const updateComponent = (component, newProperties = {}) => {
137
- tree.update((t) => {
138
- let updated = false;
139
-
140
- traverse((c) => {
141
- if (c.id === component.id) {
142
- updated = true;
143
- if (typeof newProperties === "object") {
144
- Object.assign(c, newProperties);
145
- } else if (typeof newProperties === "function") {
146
- Object.assign(c, newProperties(c));
147
- }
148
- }
149
- }, t);
150
-
151
- if (!updated) {
152
- console.warn(`Cannot find component to update with id ${component.id}`);
153
- }
154
-
155
- return t;
156
- });
140
+ tree.update((t) => {
141
+ let updated = false;
142
+
143
+ traverse((c) => {
144
+ if (c.id === component.id) {
145
+ updated = true;
146
+ if (typeof newProperties === 'object') {
147
+ Object.assign(c, newProperties);
148
+ } else if (typeof newProperties === 'function') {
149
+ Object.assign(c, newProperties(c));
150
+ }
151
+ }
152
+ }, t);
153
+
154
+ if (!updated) {
155
+ console.warn(
156
+ `Cannot find component to update with id ${component.id}`,
157
+ );
158
+ }
159
+
160
+ return t;
161
+ });
157
162
  };
158
163
 
159
164
  export const updateModule = (m, newProperties = {}) => {
160
- tree.update((t) => {
161
- traverse((c) => {
162
- if (c.mID === m.mID) {
163
- if (typeof newProperties === "object") {
164
- Object.assign(c, newProperties);
165
- } else if (typeof newProperties === "function") {
166
- Object.assign(c, newProperties(c));
167
- }
168
- }
169
- }, t);
170
-
171
- return t;
172
- });
165
+ tree.update((t) => {
166
+ traverse((c) => {
167
+ if (c.mID === m.mID) {
168
+ if (typeof newProperties === 'object') {
169
+ Object.assign(c, newProperties);
170
+ } else if (typeof newProperties === 'function') {
171
+ Object.assign(c, newProperties(c));
172
+ }
173
+ }
174
+ }, t);
175
+
176
+ return t;
177
+ });
173
178
  };
174
179
 
175
180
  export const resize = (nodes = []) => {
176
- tree.update((t) => {
177
- traverse((c) => {
178
- nodes.forEach(n => {
179
- if (n.id === c.id) {
180
- c.size = n.size;
181
- }
182
- });
183
- }, t);
184
-
185
- return t;
186
- });
181
+ tree.update((t) => {
182
+ traverse((c) => {
183
+ nodes.forEach((n) => {
184
+ if (n.id === c.id) {
185
+ c.size = n.size;
186
+ }
187
+ });
188
+ }, t);
189
+
190
+ return t;
191
+ });
187
192
  };
@@ -1,16 +1,16 @@
1
- import { createStore } from "./utils";
1
+ import { createStore } from './utils';
2
2
 
3
- export const multisampling = createStore("multisampling", [], {
3
+ export const multisampling = createStore('multisampling', [], {
4
4
  persist: !__BUILD__,
5
5
  reset: true,
6
6
  });
7
7
 
8
- export const threshold = createStore("threshold", 0, {
8
+ export const threshold = createStore('threshold', 0, {
9
9
  persist: !__BUILD__,
10
10
  reset: false,
11
11
  });
12
12
 
13
- export const transition = createStore("transition", false, {
13
+ export const transition = createStore('transition', false, {
14
14
  persist: !__BUILD__,
15
15
  reset: false,
16
16
  });
@@ -1,26 +1,63 @@
1
- import { writable, get } from "svelte/store";
2
- import { sketches } from "./sketches";
1
+ import { sketches } from './sketches';
2
+ import { getStore } from './utils';
3
3
 
4
- export const props = writable({});
4
+ export const props = getStore('props', {});
5
5
 
6
- sketches.subscribe((sketches) => {
7
- props.update((currentProps) => {
8
- Object.keys(sketches).forEach((key) => {
9
- const sketch = sketches[key];
10
-
11
- if (sketch) { // sketch can be undefined if failed to load
12
- currentProps[key] = reconcile(sketch.props, currentProps[key]);
6
+ function resetProp(prop) {
7
+ function copyProperties(source, target) {
8
+ for (const key in source) {
9
+ if (source.hasOwnProperty(key)) {
10
+ // Check if the property is an object (including nested objects)
11
+ if (typeof source[key] === 'object' && source[key] !== null) {
12
+ // If the property is an object, recursively copy its properties
13
+ target[key] = target[key] || {};
14
+ copyProperties(source[key], target[key]);
15
+ } else {
16
+ // If the property is not an object, copy its value
17
+ target[key] = source[key];
18
+ }
13
19
  }
20
+ }
21
+ }
22
+
23
+ if (Array.isArray(prop.value)) {
24
+ for (let i = 0; i < prop.__initialValue.length; i++) {
25
+ prop.value[i] = prop.__initialValue[i];
26
+ }
27
+ } else if (typeof prop.value === 'object') {
28
+ copyProperties(prop.__initialValue, prop.value);
29
+ } else {
30
+ prop.value = prop.__initialValue;
31
+ }
32
+ }
33
+
34
+ export function resetProps(sketchKey, params = {}) {
35
+ props.update((all) => {
36
+ const sketchProps = all[sketchKey];
37
+
38
+ Object.keys(sketchProps).forEach((propKey) => {
39
+ const prop = sketchProps[propKey];
40
+ resetProp(prop);
41
+
42
+ prop.onChange?.(prop, params);
14
43
  });
15
44
 
16
- return currentProps;
45
+ return all;
17
46
  });
18
- });
47
+ }
19
48
 
20
- function reconcile(newProps = {}, prevProps = {}) {
49
+ export function reconcile(newProps = {}, prevProps = {}) {
21
50
  Object.keys(newProps).forEach((propKey) => {
22
51
  let newProp = newProps[propKey];
23
52
 
53
+ if (Array.isArray(newProp.value)) {
54
+ newProp.__initialValue = [...newProp.value];
55
+ } else if (typeof newProp.value === 'object') {
56
+ newProp.__initialValue = structuredClone(newProp.value);
57
+ } else {
58
+ newProp.__initialValue = newProp.value;
59
+ }
60
+
24
61
  if (!newProp.params) {
25
62
  newProp.params = {};
26
63
  }
@@ -32,6 +69,10 @@ function reconcile(newProps = {}, prevProps = {}) {
32
69
  let newProp = newProps[propKey];
33
70
 
34
71
  if (newProp) {
72
+ if (newProp.__initialValue === prevProp.__initialValue) {
73
+ newProp.value = prevProp.value;
74
+ }
75
+
35
76
  if (prevProp.params) {
36
77
  // reconcile locked VectorInput from UI
37
78
  if (prevProp.params.locked !== undefined) {
@@ -44,3 +85,25 @@ function reconcile(newProps = {}, prevProps = {}) {
44
85
 
45
86
  return newProps;
46
87
  }
88
+
89
+ /**
90
+ * Update prop value based on sketch key and prop key
91
+ * @param {string} sketchKey
92
+ * @param {string} propKey
93
+ * @param {any} newValue
94
+ */
95
+ export function updateProp(sketchKey, propKey, newValue, params = {}) {
96
+ props.update((currentProps) => {
97
+ const prop = currentProps[sketchKey][propKey];
98
+
99
+ if (prop) {
100
+ prop.value = newValue;
101
+
102
+ if (typeof prop.onChange === 'function') {
103
+ prop.onChange(prop, params);
104
+ }
105
+ }
106
+
107
+ return currentProps;
108
+ });
109
+ }
@@ -1,30 +1,41 @@
1
- import { rendering } from "./rendering";
1
+ import { rendering } from './rendering';
2
2
 
3
3
  export let renderers = {};
4
4
 
5
5
  function loadRenderer(renderingMode) {
6
- if (__THREE_RENDERER__ && renderingMode === "three") {
7
- return import("../renderers/THREERenderer.js");
6
+ if (renderers[renderingMode]) return renderers[renderingMode];
7
+
8
+ if (__THREE_RENDERER__ && renderingMode === 'three') {
9
+ return import('../renderers/THREERenderer.js');
8
10
  }
9
11
 
10
- if (__FRAGMENT_RENDERER__ && renderingMode === "fragment") {
11
- return import("../renderers/FragmentRenderer.js");
12
+ if (__FRAGMENT_RENDERER__ && renderingMode === 'fragment') {
13
+ return import('../renderers/FragmentRenderer.js');
12
14
  }
13
15
 
14
- if (__P5_RENDERER__ && renderingMode === "p5") {
15
- return import("../renderers/P5Renderer.js");
16
+ if (__P5_RENDERER__ && renderingMode === 'p5') {
17
+ return import('../renderers/P5Renderer.js');
16
18
  }
17
19
 
18
- if (__2D_RENDERER__ && renderingMode === "2d") {
19
- return import("../renderers/2DRenderer.js");
20
+ if (__P5_WEBGL_RENDERER__ && renderingMode === 'p5-webgl') {
21
+ return import('../renderers/P5GLRenderer.js');
20
22
  }
21
- }
22
23
 
23
- export async function findRenderer(renderingMode) {
24
- if (renderers[renderingMode]) return renderers[renderingMode];
24
+ if (__2D_RENDERER__ && renderingMode === '2d') {
25
+ return import('../renderers/2DRenderer.js');
26
+ }
27
+ }
25
28
 
29
+ export async function findRenderer({
30
+ rendering: renderingMode,
31
+ renderer: customRenderer,
32
+ }) {
26
33
  // load and save
27
- renderers[renderingMode] = await loadRenderer(renderingMode);
34
+ renderers[renderingMode] = customRenderer
35
+ ? typeof customRenderer === 'function'
36
+ ? await customRenderer()
37
+ : customRenderer
38
+ : await loadRenderer(renderingMode);
28
39
 
29
40
  // get
30
41
  let renderer = renderers[renderingMode];
@@ -35,7 +46,7 @@ export async function findRenderer(renderingMode) {
35
46
  let r;
36
47
 
37
48
  if (!initialized) {
38
- if (typeof renderer.init === "function") {
49
+ if (typeof renderer.init === 'function') {
39
50
  r = renderer.init({
40
51
  canvas: document.createElement('canvas'),
41
52
  pixelRatio: current.pixelRatio,
@@ -47,7 +58,7 @@ export async function findRenderer(renderingMode) {
47
58
 
48
59
  initialized = true;
49
60
 
50
- if (typeof renderer.resize === "function") {
61
+ if (typeof renderer.resize === 'function') {
51
62
  renderer.resize({
52
63
  width: current.width,
53
64
  height: current.height,