fragment-tools 0.2.8 → 0.2.10

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 (98) hide show
  1. package/README.md +14 -10
  2. package/bin/index.js +4 -0
  3. package/package.json +11 -4
  4. package/src/cli/build.js +1 -3
  5. package/src/cli/create.js +55 -6
  6. package/src/cli/createConfig.js +9 -24
  7. package/src/cli/createFragmentFile.js +44 -46
  8. package/src/cli/getEntries.js +13 -5
  9. package/src/cli/plugins/check-dependencies.js +1 -1
  10. package/src/cli/plugins/save.js +7 -2
  11. package/src/cli/run.js +12 -3
  12. package/src/cli/templates/blank/index.js +4 -4
  13. package/src/cli/templates/blank/index.ts +15 -0
  14. package/src/cli/templates/default/index.js +7 -6
  15. package/src/cli/templates/default/index.ts +20 -0
  16. package/src/cli/templates/fragment-gl/fragment.fs +1 -1
  17. package/src/cli/templates/fragment-gl/index.js +3 -3
  18. package/src/cli/templates/fragment-gl/index.ts +20 -0
  19. package/src/cli/templates/p5/index.js +6 -6
  20. package/src/cli/templates/p5/index.ts +14 -0
  21. package/src/cli/templates/p5-webgl/fragment.fs +2 -4
  22. package/src/cli/templates/p5-webgl/index.js +9 -15
  23. package/src/cli/templates/p5-webgl/index.ts +43 -0
  24. package/src/cli/templates/three-fragment/fragment.fs +1 -1
  25. package/src/cli/templates/three-fragment/index.js +10 -4
  26. package/src/cli/templates/three-fragment/index.ts +68 -0
  27. package/src/cli/templates/three-orthographic/index.js +10 -4
  28. package/src/cli/templates/three-orthographic/index.ts +29 -0
  29. package/src/cli/templates/three-perspective/index.js +10 -4
  30. package/src/cli/templates/three-perspective/index.ts +26 -0
  31. package/src/cli/utils.js +3 -0
  32. package/src/client/app/components/HintRecord.svelte +3 -3
  33. package/src/client/app/hooks.js +5 -5
  34. package/src/client/app/lib/canvas-recorder/CanvasRecorder.js +3 -1
  35. package/src/client/app/lib/canvas-recorder/GIFRecorder.js +11 -1
  36. package/src/client/app/lib/canvas-recorder/MediaBunnyRecorder.js +97 -0
  37. package/src/client/app/lib/gl/Renderer.js +1 -1
  38. package/src/client/app/lib/gl/Texture.js +1 -1
  39. package/src/client/app/lib/gl/index.js +2 -2
  40. package/src/client/app/modules/AudioAnalyser/Range.svelte +2 -2
  41. package/src/client/app/modules/AudioAnalyser/Spectrum.svelte +3 -3
  42. package/src/client/app/modules/Console/ConsoleLine.svelte +13 -13
  43. package/src/client/app/modules/Console.svelte +6 -4
  44. package/src/client/app/modules/Exports.svelte +28 -4
  45. package/src/client/app/renderers/2DRenderer.js +6 -3
  46. package/src/client/app/renderers/FragmentRenderer.js +39 -2
  47. package/src/client/app/renderers/P5GLRenderer.js +28 -26
  48. package/src/client/app/renderers/P5Renderer.js +49 -9
  49. package/src/client/app/renderers/THREERenderer.js +64 -12
  50. package/src/client/app/state/exports.svelte.js +40 -2
  51. package/src/client/app/state/rendering.svelte.js +2 -2
  52. package/src/client/app/state/utils.svelte.js +9 -2
  53. package/src/client/app/stores/sketches.js +2 -1
  54. package/src/client/app/ui/ErrorOverlay.svelte +5 -5
  55. package/src/client/app/ui/Field.svelte +12 -8
  56. package/src/client/app/ui/FieldGroup.svelte +5 -5
  57. package/src/client/app/ui/FieldSection.svelte +8 -8
  58. package/src/client/app/ui/FieldSpace.svelte +2 -2
  59. package/src/client/app/ui/FieldTrigger.svelte +6 -6
  60. package/src/client/app/ui/FloatingParams.svelte +1 -1
  61. package/src/client/app/ui/LayoutBuild.svelte +1 -1
  62. package/src/client/app/ui/LayoutComponent.svelte +7 -7
  63. package/src/client/app/ui/LayoutResizer.svelte +1 -1
  64. package/src/client/app/ui/LayoutToolbar.svelte +6 -6
  65. package/src/client/app/ui/Module.svelte +6 -4
  66. package/src/client/app/ui/ModuleRenderer.svelte +3 -3
  67. package/src/client/app/ui/OutputRenderer.svelte +4 -1
  68. package/src/client/app/ui/SketchRenderer.svelte +9 -2
  69. package/src/client/app/ui/fields/ButtonInput.svelte +11 -11
  70. package/src/client/app/ui/fields/CheckboxInput.svelte +27 -19
  71. package/src/client/app/ui/fields/ColorInput.svelte +9 -7
  72. package/src/client/app/ui/fields/ImageInput.svelte +43 -23
  73. package/src/client/app/ui/fields/Input.svelte +13 -13
  74. package/src/client/app/ui/fields/IntervalInput.svelte +11 -14
  75. package/src/client/app/ui/fields/ListInput.svelte +9 -8
  76. package/src/client/app/ui/fields/ProgressInput.svelte +9 -9
  77. package/src/client/app/ui/fields/Select.svelte +13 -12
  78. package/src/client/app/ui/fields/VectorInput.svelte +1 -1
  79. package/src/client/app/utils/canvas.utils.js +21 -19
  80. package/src/client/public/css/global.css +26 -27
  81. package/src/types/client.d.ts +36 -0
  82. package/src/types/gl.d.ts +130 -0
  83. package/src/types/helpers.d.ts +5 -0
  84. package/src/types/hooks.d.ts +14 -0
  85. package/src/types/index.d.ts +8 -0
  86. package/src/types/midi.d.ts +176 -0
  87. package/src/types/props.d.ts +72 -0
  88. package/src/types/renderers.d.ts +100 -0
  89. package/src/types/sketch.d.ts +45 -0
  90. package/src/types/triggers.d.ts +45 -0
  91. package/src/types/utils.ts +11 -0
  92. package/tsconfig.json +38 -0
  93. package/.prettierignore +0 -4
  94. package/.prettierrc +0 -25
  95. package/src/client/app/lib/canvas-recorder/MP4Recorder.js +0 -44
  96. package/src/client/app/lib/canvas-recorder/WebMRecorder.js +0 -29
  97. package/src/client/app/lib/canvas-recorder/mp4.js +0 -1654
  98. package/src/client/app/lib/canvas-recorder/mp4.wasm +0 -0
@@ -3,8 +3,34 @@ import { client } from '@fragment/client';
3
3
  import { getShaderPath } from '../utils/glsl.utils';
4
4
  import { clearError } from '../state/errors.svelte';
5
5
 
6
+ /**
7
+ * @typedef {object} MountParamsThreeRenderer
8
+ * @property {HTMLCanvasElement} canvas
9
+ * @property {THREE.Scene} scene
10
+ * @property {THREE.WebGLRenderer} renderer
11
+ */
12
+
13
+ /**
14
+ * @typedef {object} PreviewThreeRenderer
15
+ * @property {number} id
16
+ * @property {THREE.Scene} scene
17
+ * @property {THREE.renderer} renderer
18
+ * @property {rendered} boolean
19
+ */
20
+
21
+ /** @type {PreviewThreeRenderer[]} */
6
22
  let previews = [];
7
23
 
24
+ /**
25
+ * @param {object} params
26
+ * @param {number} params.id
27
+ * @param {HTMLCanvasElement} params.canvas
28
+ * @param {HTMLDivElement} params.container
29
+ * @param {number} params.width
30
+ * @param {number} params.height
31
+ * @param {number} params.pixelRatio
32
+ * @returns {MountParamsThreeRenderer}
33
+ */
8
34
  export let onMountPreview = ({ id, canvas }) => {
9
35
  let renderer = new WebGLRenderer({ antialias: true, canvas });
10
36
 
@@ -32,18 +58,12 @@ export let onMountPreview = ({ id, canvas }) => {
32
58
  };
33
59
  };
34
60
 
35
- export let onDestroyPreview = ({ id }) => {
36
- const previewIndex = previews.findIndex((p) => p.id === id);
37
- const preview = previews[previewIndex];
38
-
39
- if (preview) {
40
- const { renderer } = preview;
41
- clearError(renderer.getContext().__uuid);
42
- renderer.dispose();
43
- previews.splice(previewIndex, 1);
44
- }
45
- };
46
-
61
+ /**
62
+ * @param {MountParamsThreeRenderer} params
63
+ * @param {number} params.id
64
+ * @param {HTMLCanvasElement} params.canvas
65
+ * @param {HTMLDivElement} params.container
66
+ */
47
67
  export let onBeforeUpdatePreview = ({ id }) => {
48
68
  const preview = previews.find((p) => p.id === id);
49
69
 
@@ -52,6 +72,12 @@ export let onBeforeUpdatePreview = ({ id }) => {
52
72
  }
53
73
  };
54
74
 
75
+ /**
76
+ * @param {MountParamsThreeRenderer} params
77
+ * @param {number} params.id
78
+ * @param {HTMLCanvasElement} params.canvas
79
+ * @param {HTMLDivElement} params.container
80
+ */
55
81
  export let onAfterUpdatePreview = ({ id }) => {
56
82
  const preview = previews.find((p) => p.id === id);
57
83
 
@@ -67,6 +93,14 @@ export let onAfterUpdatePreview = ({ id }) => {
67
93
  }
68
94
  };
69
95
 
96
+ /**
97
+ * @param {MountParamsThreeRenderer} params
98
+ * @param {number} params.id
99
+ * @param {HTMLCanvasElement} params.canvas
100
+ * @param {number} params.width
101
+ * @param {number} params.height
102
+ * @param {number} params.pixelRatio
103
+ */
70
104
  export let onResizePreview = ({ id, width, height, pixelRatio }) => {
71
105
  const preview = previews.find((p) => p.id === id);
72
106
 
@@ -77,6 +111,24 @@ export let onResizePreview = ({ id, width, height, pixelRatio }) => {
77
111
  }
78
112
  };
79
113
 
114
+ /**
115
+ * @param {MountParamsThreeRenderer} params
116
+ * @param {number} params.id
117
+ * @param {HTMLCanvasElement} params.canvas
118
+ * @param {HTMLElement} params.container
119
+ */
120
+ export let onDestroyPreview = ({ id }) => {
121
+ const previewIndex = previews.findIndex((p) => p.id === id);
122
+ const preview = previews[previewIndex];
123
+
124
+ if (preview) {
125
+ const { renderer } = preview;
126
+ clearError(renderer.getContext().__uuid);
127
+ renderer.dispose();
128
+ previews.splice(previewIndex, 1);
129
+ }
130
+ };
131
+
80
132
  /* HOT SHADER RELOADING */
81
133
  let _shaderUpdates = [];
82
134
 
@@ -6,13 +6,47 @@ export const IMAGE_ENCODINGS = ['png', 'jpeg', 'webp'];
6
6
  export const VIDEO_FORMATS = {
7
7
  FRAMES: 'frames',
8
8
  MP4: 'mp4',
9
- GIF: 'gif',
10
9
  WEBM: 'webm',
10
+ GIF: 'gif',
11
+ MKV: 'mkv',
12
+ MOV: 'mov',
13
+ };
14
+
15
+ export const VIDEO_CODECS = {
16
+ AVC: 'avc',
17
+ HEVC: 'hevc',
18
+ VP8: 'vp8',
19
+ VP9: 'vp9',
20
+ AV1: 'av1',
11
21
  };
12
22
 
23
+ export const VIDEO_CODECS_FORMATS = new Map();
24
+ VIDEO_CODECS_FORMATS.set(VIDEO_CODECS.AVC, ['mp4', 'mkv', 'mov']);
25
+ VIDEO_CODECS_FORMATS.set(VIDEO_CODECS.HEVC, ['mp4', 'mkv', 'mov']);
26
+ VIDEO_CODECS_FORMATS.set(VIDEO_CODECS.VP8, ['webm', 'mkv']);
27
+ VIDEO_CODECS_FORMATS.set(VIDEO_CODECS.VP9, ['webm', 'mkv']);
28
+ VIDEO_CODECS_FORMATS.set(VIDEO_CODECS.AV1, ['webm', 'mkv']);
29
+
30
+ /**
31
+ * List valid codecs based on format
32
+ * @param {string} format
33
+ * @return {string[]}
34
+ */
35
+ export function getCodecsForFormat(format) {
36
+ const codecs = [];
37
+
38
+ for (const [codec, formats] of VIDEO_CODECS_FORMATS) {
39
+ if (formats.includes(format)) {
40
+ codecs.push(codec);
41
+ }
42
+ }
43
+
44
+ return codecs;
45
+ }
46
+
13
47
  class Exports {
14
48
  imageEncoding = $state(IMAGE_ENCODINGS[0]);
15
- videoFormat = $state(Object.values(VIDEO_FORMATS)[0]);
49
+ videoFormat = $state(VIDEO_FORMATS.MP4);
16
50
  pixelsPerInch = $state(72);
17
51
  framerate = $state(60);
18
52
  useDuration = $state(true);
@@ -20,6 +54,7 @@ class Exports {
20
54
  loopCount = $state(1);
21
55
  imageQuality = $state(100);
22
56
  videoQuality = $state(100);
57
+ videoCodec = $state(VIDEO_CODECS.HEVC);
23
58
  imageCount = $state(1);
24
59
  recording = $state(false);
25
60
  capturing = $state(false);
@@ -41,6 +76,7 @@ class Exports {
41
76
  loopCount: this.loopCount,
42
77
  imageQuality: this.imageQuality,
43
78
  videoQuality: this.videoQuality,
79
+ videoCodec: this.videoCodec,
44
80
  imageCount: this.imageCount,
45
81
  videoCollapsed: this.videoCollapsed,
46
82
  imageCollapsed: this.imageCollapsed,
@@ -105,6 +141,7 @@ class Exports {
105
141
  format = this.videoFormat,
106
142
  imageEncoding = this.imageEncoding,
107
143
  quality = this.videoQuality,
144
+ codec = this.videoCodec,
108
145
  duration,
109
146
  filename,
110
147
  pattern,
@@ -133,6 +170,7 @@ class Exports {
133
170
  onTick,
134
171
  framerate,
135
172
  format,
173
+ codec,
136
174
  imageEncoding,
137
175
  quality,
138
176
  duration: duration * this.loopCount,
@@ -128,15 +128,15 @@ class Rendering {
128
128
  const params =
129
129
  instance.init?.({
130
130
  canvas: document.createElement('canvas'),
131
- pixelRatio: this.pixelRatio,
132
131
  width: this.width,
133
132
  height: this.height,
133
+ pixelRatio: this.pixelRatio,
134
134
  }) ?? {};
135
135
 
136
136
  instance.resize?.({
137
- pixelRatio: this.pixelRatio,
138
137
  width: this.width,
139
138
  height: this.height,
139
+ pixelRatio: this.pixelRatio,
140
140
  ...params,
141
141
  });
142
142
 
@@ -81,8 +81,15 @@ export function deepClone(value) {
81
81
  }
82
82
 
83
83
  if (isObject(value)) {
84
- const clone = structuredClone(value);
85
- return clone;
84
+ try {
85
+ const clone = structuredClone(
86
+ Array.isArray(value) ? [...value] : { ...value },
87
+ );
88
+ return clone;
89
+ } catch (error) {
90
+ console.error(error);
91
+ return value;
92
+ }
86
93
  }
87
94
 
88
95
  return value;
@@ -1,6 +1,7 @@
1
+ import { sketches as all } from 'virtual:sketches';
2
+
1
3
  import { createStore } from './utils.js';
2
4
  import { displayError } from '../stores/errors';
3
- import { sketches as all } from '@fragment/sketches';
4
5
 
5
6
  export const sketches = createStore('sketches', {});
6
7
  export const sketchesKeys = createStore('sketchesKeys', Object.keys(all));
@@ -111,9 +111,9 @@
111
111
  justify-content: stretch;
112
112
  color: #2a0000;
113
113
  padding: 12px 0;
114
- font-size: var(--font-size-input);
114
+ font-size: var(--fragment-input-font-size);
115
115
  background-color: #ff8081;
116
- border-radius: var(--border-radius-input);
116
+ border-radius: var(--fragment-input-border-radius);
117
117
  overflow-x: auto;
118
118
  }
119
119
 
@@ -126,8 +126,8 @@
126
126
  }
127
127
 
128
128
  .extract::-webkit-scrollbar-thumb {
129
- background-color: #f0f0f0; /* color of the scroll thumb */
130
- border-radius: 20px; /* roundness of the scroll thumb */
129
+ background-color: var(--fragment-color-white);
130
+ border-radius: 20px;
131
131
  }
132
132
 
133
133
  .extract-line {
@@ -143,6 +143,6 @@
143
143
  }
144
144
 
145
145
  .console {
146
- font-size: var(--font-size-input);
146
+ font-size: var(--fragment-input-font-size);
147
147
  }
148
148
  </style>
@@ -67,10 +67,14 @@
67
67
  value(event);
68
68
  onclick(event);
69
69
  },
70
- download: (event) => {
71
- let [data, filename] = value(event);
70
+ download: async (event) => {
71
+ try {
72
+ let [data, filename] = await value(event);
72
73
 
73
- download(data, filename);
74
+ download(data, filename);
75
+ } catch (error) {
76
+ console.error(`Error while trying to download:`, error);
77
+ }
74
78
  },
75
79
  number: (event = {}) => {
76
80
  const isValueInRange = event.value >= 0 && event.value <= 1;
@@ -185,7 +189,7 @@
185
189
  width: 100%;
186
190
 
187
191
  padding: 3px 6px 3px 12px;
188
- border-bottom: 1px solid var(--color-spacing);
192
+ border-bottom: 1px solid var(--fragment-spacing-color);
189
193
  }
190
194
 
191
195
  .field.changed:before {
@@ -205,8 +209,8 @@
205
209
 
206
210
  background: repeating-linear-gradient(
207
211
  45deg,
208
- var(--color-active) calc(0px + var(--stripes-offset)),
209
- var(--color-active) calc(2px + var(--stripes-offset)),
212
+ var(--fragment-accent-color) calc(0px + var(--stripes-offset)),
213
+ var(--fragment-accent-color) calc(2px + var(--stripes-offset)),
210
214
  transparent calc(2px + var(--stripes-offset)),
211
215
  transparent calc(4px + var(--stripes-offset))
212
216
  );
@@ -218,7 +222,7 @@
218
222
  }
219
223
 
220
224
  :global(.field__input .field:last-child) {
221
- border-bottom: 0px solid #323233 !important;
225
+ border-bottom-width: 0px !important;
222
226
  padding-bottom: 0px !important;
223
227
  }
224
228
 
@@ -256,7 +260,7 @@
256
260
  }
257
261
 
258
262
  .field__action {
259
- color: var(--color-text);
263
+ color: var(--fragment-text-color);
260
264
 
261
265
  opacity: 0.6;
262
266
  background-color: transparent;
@@ -51,12 +51,12 @@
51
51
  width: 12px;
52
52
  height: 1px;
53
53
 
54
- background-color: #323233;
54
+ background-color: var(--fragment-spacing-color);
55
55
  }
56
56
 
57
57
  .header {
58
58
  padding: 3px 6px;
59
- border-bottom: 1px solid #323233;
59
+ border-bottom: 1px solid var(--fragment-spacing-color);
60
60
  }
61
61
 
62
62
  .header__action {
@@ -73,7 +73,7 @@
73
73
  .header__icon {
74
74
  padding-bottom: 1px;
75
75
 
76
- color: #f0f0f0;
76
+ color: var(--fragment-text-color);
77
77
  transform: rotate(90deg);
78
78
  opacity: 0.5;
79
79
  transition: opacity 0.1s ease;
@@ -89,7 +89,7 @@
89
89
  }
90
90
 
91
91
  .field-group__name {
92
- color: #f0f0f0;
92
+ color: var(--fragment-text-color);
93
93
 
94
94
  font-size: 11px;
95
95
  font-weight: 700;
@@ -108,7 +108,7 @@
108
108
 
109
109
  .content {
110
110
  margin-left: 12px;
111
- border-left: 1px solid #323233;
111
+ border-left: 1px solid var(--fragment-spacing-color);
112
112
  }
113
113
 
114
114
  .field-group.collapsed .content {
@@ -77,7 +77,7 @@
77
77
  width: 1px;
78
78
  height: var(--margin);
79
79
 
80
- background-color: var(--color-spacing);
80
+ background-color: var(--fragment-spacing-color);
81
81
  }
82
82
 
83
83
  .field__infos {
@@ -87,12 +87,12 @@
87
87
  align-items: center;
88
88
  justify-content: space-between;
89
89
 
90
- color: var(--color-text);
90
+ color: var(--fragment-text-color);
91
91
  }
92
92
 
93
93
  .field__label {
94
94
  color: inherit;
95
- font-size: var(--font-size-input);
95
+ font-size: var(--fragment-input-font-size);
96
96
  user-select: none;
97
97
 
98
98
  opacity: 0.6;
@@ -100,12 +100,12 @@
100
100
  transition: opacity 0.1s ease;
101
101
  }
102
102
 
103
- button.field__label {
103
+ button.field__label:not(:disabled) {
104
104
  cursor: pointer;
105
105
  }
106
106
 
107
107
  .field__label:focus-visible {
108
- outline: 2px var(--color-active) solid;
108
+ outline: 2px var(--fragment-accent-color) solid;
109
109
  outline-offset: 2px;
110
110
  border-radius: 1px;
111
111
  }
@@ -123,7 +123,7 @@
123
123
 
124
124
  padding-left: 5px;
125
125
 
126
- background-color: #242425;
126
+ background-color: var(--fragment-background-color);
127
127
  }
128
128
 
129
129
  .field__input {
@@ -132,11 +132,11 @@
132
132
  justify-content: center;
133
133
  align-items: flex-start;
134
134
 
135
- min-height: calc(var(--height-input) + 4px);
135
+ min-height: calc(var(--fragment-input-height) + 4px);
136
136
  }
137
137
 
138
138
  .field__section.secondary .field__input {
139
139
  padding: var(--column-gap);
140
- border: 1px solid var(--color-spacing);
140
+ border: 1px solid var(--fragment-spacing-color);
141
141
  }
142
142
  </style>
@@ -8,7 +8,7 @@
8
8
  .field-space {
9
9
  position: relative;
10
10
 
11
- border-bottom: 1px solid var(--color-spacing);
11
+ border-bottom: 1px solid var(--fragment-spacing-color);
12
12
  overflow: hidden;
13
13
  }
14
14
 
@@ -22,7 +22,7 @@
22
22
  width: 100%;
23
23
  height: 1px;
24
24
 
25
- background-color: var(--color-spacing);
25
+ background-color: var(--fragment-spacing-color);
26
26
  }
27
27
 
28
28
  .field-space:before {
@@ -217,9 +217,9 @@
217
217
  label="delete"
218
218
  showLabel={false}
219
219
  onclick={handleClickDelete}
220
- --color-text="white"
221
- --background-color="var(--color-red)"
222
- --box-shadow-color-active="var(--color-lightred)"
220
+ --text-color="white"
221
+ --background-color="var(--fragment-color-red)"
222
+ --box-shadow-color-active="var(--fragment-color-lightred)"
223
223
  >
224
224
  <IconCross />
225
225
  </ButtonInput>
@@ -228,7 +228,7 @@
228
228
 
229
229
  <style>
230
230
  .field-trigger {
231
- --width-delete: var(--height-input);
231
+ --width-delete: var(--fragment-input-height);
232
232
  --width-input: 90px;
233
233
  --width-activity: 16px;
234
234
  --width-cols: 1fr;
@@ -264,11 +264,11 @@
264
264
  }
265
265
 
266
266
  .activity.valid.enabled {
267
- --background-color: var(--color-green);
267
+ --background-color: var(--fragment-color-green);
268
268
  }
269
269
 
270
270
  .activity.valid.disabled {
271
- --background-color: var(--color-red);
271
+ --background-color: var(--fragment-color-red);
272
272
  }
273
273
 
274
274
  .field-trigger.mouse {
@@ -55,7 +55,7 @@
55
55
 
56
56
  height: auto;
57
57
 
58
- border-radius: calc(var(--border-radius-input) * 2);
58
+ border-radius: calc(var(--fragment-input-border-radius) * 2);
59
59
  overflow: hidden;
60
60
  }
61
61
 
@@ -9,7 +9,7 @@
9
9
 
10
10
  let gui = $derived(buildConfig.gui ?? {});
11
11
  let layout = $derived(buildConfig.layout ?? {});
12
- let headless = $derived(layout.headless ?? false);
12
+ let headless = $derived(layout.headless ?? true);
13
13
  let resizable = $derived(layout.resizable ?? false);
14
14
 
15
15
  let guiOutput = $derived(gui.output ?? true);
@@ -106,7 +106,7 @@
106
106
  >
107
107
  {#if isRoot && layout.previewing}
108
108
  <Preview />
109
- {:else if childComponents.length > 0}
109
+ {:else if childComponents.length > 0 && layout.persistent}
110
110
  {#each childComponents as child (child.id)}
111
111
  {#if child.type === 'column' || child.type === 'row'}
112
112
  <LayoutComponent
@@ -142,7 +142,7 @@
142
142
  {#if !isRoot}
143
143
  <Resizer
144
144
  direction={isColumn ? 'vertical' : 'horizontal'}
145
- {current}
145
+ bind:current
146
146
  disabled={!resizable}
147
147
  />
148
148
  {/if}
@@ -166,11 +166,11 @@
166
166
  }
167
167
 
168
168
  .column:not(:last-child) {
169
- border-right: 0.5px solid var(--color-lightblack);
169
+ border-right: 0.5px solid var(--fragment-color-lightblack);
170
170
  }
171
171
 
172
172
  .column:not(:first-child) {
173
- border-left: 0.5px solid var(--color-lightblack);
173
+ border-left: 0.5px solid var(--fragment-color-lightblack);
174
174
  }
175
175
 
176
176
  .row {
@@ -181,14 +181,14 @@
181
181
  width: 100%;
182
182
  height: 100%;
183
183
 
184
- background-color: var(--color-background);
184
+ background-color: var(--fragment-background-color);
185
185
  }
186
186
 
187
187
  .row:not(:first-child) {
188
- border-top: 0.5px solid var(--color-lightblack);
188
+ border-top: 0.5px solid var(--fragment-color-lightblack);
189
189
  }
190
190
 
191
191
  .row:not(:last-child) {
192
- border-bottom: 0.5px solid var(--color-lightblack);
192
+ border-bottom: 0.5px solid var(--fragment-color-lightblack);
193
193
  }
194
194
  </style>
@@ -196,7 +196,7 @@
196
196
 
197
197
  .resizer.dragging .resizer-hover.visible:before {
198
198
  opacity: 1;
199
- background-color: #177bd0;
199
+ background-color: var(--fragment-accent-color);
200
200
  }
201
201
 
202
202
  .resizer--horizontal {
@@ -64,9 +64,9 @@
64
64
  label="Delete"
65
65
  showLabel={false}
66
66
  onclick={onDelete}
67
- --color-text="white"
68
- --background-color="var(--color-red)"
69
- --box-shadow-color-active="var(--color-lightred)"
67
+ --fragment-text-color="white"
68
+ --background-color="var(--fragment-color-red)"
69
+ --box-shadow-color-active="var(--fragment-color-lightred)"
70
70
  >
71
71
  <IconCross />
72
72
  </ButtonInput>
@@ -156,7 +156,7 @@
156
156
  width: 1px;
157
157
  height: var(--size);
158
158
 
159
- background-color: var(--color-border-input);
159
+ background-color: var(--fragment-input-border-color);
160
160
  }
161
161
 
162
162
  .content.vertical .separator:after {
@@ -174,8 +174,8 @@
174
174
  display: flex;
175
175
  align-items: center;
176
176
  padding: 6px;
177
- border-radius: var(--border-radius-input);
178
- background-color: var(--color-background);
177
+ border-radius: var(--fragment-input-border-radius);
178
+ background-color: var(--fragment-background-color);
179
179
  border: 1px solid #555;
180
180
  /* background: rgba(0, 0, 0, 0.8); */
181
181
 
@@ -79,7 +79,7 @@
79
79
  flex-shrink: 0;
80
80
  align-items: center;
81
81
 
82
- background-color: var(--color-lightblack);
82
+ background-color: var(--fragment-color-lightblack);
83
83
  }
84
84
 
85
85
  .slot {
@@ -114,7 +114,7 @@
114
114
  .module__container {
115
115
  position: relative;
116
116
 
117
- background-color: var(--color-background);
117
+ background-color: var(--fragment-background-color);
118
118
  }
119
119
 
120
120
  .module.scrollable .module__container {
@@ -135,7 +135,9 @@
135
135
  }
136
136
 
137
137
  .module__container::-webkit-scrollbar-thumb {
138
- background-color: var(--color-active); /* color of the scroll thumb */
138
+ background-color: var(
139
+ --fragment-accent-color
140
+ ); /* color of the scroll thumb */
139
141
  border-radius: 20px; /* roundness of the scroll thumb*/
140
142
  }
141
143
 
@@ -144,6 +146,6 @@
144
146
  }
145
147
 
146
148
  .footer {
147
- height: var(--height-input);
149
+ height: var(--fragment-input-height);
148
150
  }
149
151
  </style>
@@ -74,14 +74,14 @@
74
74
  text-transform: capitalize;
75
75
  user-select: none;
76
76
 
77
- background-color: var(--color-lightblack);
77
+ background-color: var(--fragment-color-lightblack);
78
78
  }
79
79
 
80
80
  .module-renderer-error {
81
81
  display: flex;
82
82
  flex-direction: column;
83
83
  justify-content: center;
84
- color: var(--color-red);
84
+ color: var(--fragment-color-red);
85
85
  font-size: 11px;
86
86
  text-align: center;
87
87
  background: #2a0000;
@@ -89,7 +89,7 @@
89
89
  }
90
90
 
91
91
  .message {
92
- color: var(--color-text);
92
+ color: var(--fragment-text-color);
93
93
  }
94
94
 
95
95
  .module-name {
@@ -134,7 +134,10 @@ void main() {
134
134
  height: 100%;
135
135
  justify-content: center;
136
136
 
137
- background-color: var(--background-color, var(--color-lightblack));
137
+ background-color: var(
138
+ --background-color,
139
+ var(--fragment-color-lightblack)
140
+ );
138
141
  }
139
142
 
140
143
  .output-renderer :global(canvas) {