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,33 +1,71 @@
1
+ /**
2
+ * @typedef {Object} File
3
+ * @property {string} filepath
4
+ * @property {string} exportDir
5
+ * @property {string} data
6
+ * @property {string} [encoding]
7
+ */
8
+
9
+ /**
10
+ * Transform a Blob into a Data URL
11
+ * @param {Blob} blob
12
+ * @returns {Promise<string>}
13
+ */
14
+ export async function createDataURLFromBlob(blob) {
15
+ return new Promise((resolve, reject) => {
16
+ const reader = new FileReader();
17
+
18
+ reader.onerror = (err) => {
19
+ reject(err);
20
+ };
21
+
22
+ reader.onload = (e) => {
23
+ resolve(e.target.result);
24
+ };
25
+
26
+ reader.readAsDataURL(blob);
27
+ });
28
+ }
29
+
30
+ /**
31
+ * Transform a Data URL into a blob
32
+ * @param {string} dataURL
33
+ * @returns {Blob}
34
+ */
1
35
  export function createBlobFromDataURL(dataURL) {
2
- return new Promise((resolve, reject) => {
3
- const splitIndex = dataURL.indexOf(',');
4
-
5
- if (splitIndex === -1) {
6
- reject(new Error(`createBlobFromDataURL: dataURL doesn't contain extension data.`))
7
- return;
8
- }
9
-
10
- const base64 = dataURL.slice(splitIndex + 1);
11
- const byteString = window.atob(base64);
12
- const type = dataURL.slice(0, splitIndex);
13
- const mimeMatch = /data:([^;]+)/.exec(type);
14
- const mime = (mimeMatch ? mimeMatch[1] : '') || undefined;
15
- const ab = new ArrayBuffer(byteString.length);
16
- const ia = new Uint8Array(ab);
17
- for (var i = 0; i < byteString.length; i++) {
18
- ia[i] = byteString.charCodeAt(i);
19
- }
20
-
21
- resolve(new window.Blob([ ab ], { type: mime }));
22
- });
36
+ return new Promise((resolve, reject) => {
37
+ const splitIndex = dataURL.indexOf(',');
38
+
39
+ if (splitIndex === -1) {
40
+ reject(
41
+ new Error(
42
+ `createBlobFromDataURL: dataURL doesn't contain extension data.`,
43
+ ),
44
+ );
45
+ return;
46
+ }
47
+
48
+ const base64 = dataURL.slice(splitIndex + 1);
49
+ const byteString = window.atob(base64);
50
+ const type = dataURL.slice(0, splitIndex);
51
+ const mimeMatch = /data:([^;]+)/.exec(type);
52
+ const mime = (mimeMatch ? mimeMatch[1] : '') || undefined;
53
+ const ab = new ArrayBuffer(byteString.length);
54
+ const ia = new Uint8Array(ab);
55
+ for (var i = 0; i < byteString.length; i++) {
56
+ ia[i] = byteString.charCodeAt(i);
57
+ }
58
+
59
+ resolve(new window.Blob([ab], { type: mime }));
60
+ });
23
61
  }
24
62
 
25
63
  export function download(data, filename) {
26
64
  let extension = getFileExtension(filename);
27
65
 
28
- if (typeof data === "object" && ["json", "txt"].includes(extension)) {
29
- data = JSON.stringify(data, undefined, 4);
30
- }
66
+ if (typeof data === 'object' && ['json', 'txt'].includes(extension)) {
67
+ data = JSON.stringify(data, undefined, 4);
68
+ }
31
69
 
32
70
  let type = getMimeType(extension);
33
71
  let blob = new Blob([data], { type });
@@ -35,14 +73,20 @@ export function download(data, filename) {
35
73
  downloadBlob(blob, { filename });
36
74
  }
37
75
 
38
- export function downloadBlob(blob, { filename = "untitled" } = {}) {
76
+ /**
77
+ * Download a blob from the browser
78
+ * @param {Blob} blob
79
+ * @param {object} [options]
80
+ * @param {string} [options.filename="untitled"]
81
+ */
82
+ export function downloadBlob(blob, { filename = 'untitled' } = {}) {
39
83
  let a = document.createElement('a');
40
84
  a.style.visibility = 'hidden';
41
- a.target = '_blank';
85
+ a.target = '_blank';
42
86
 
43
- a.download = filename;
44
- a.href = window.URL.createObjectURL(blob);
45
- // a.dataset.downloadurl = [type, a.download, a.href].join(':');
87
+ a.download = filename;
88
+ a.href = window.URL.createObjectURL(blob);
89
+ // a.dataset.downloadurl = [type, a.download, a.href].join(':');
46
90
 
47
91
  a.onclick = () => {
48
92
  a.onclick = () => {};
@@ -53,7 +97,26 @@ export function downloadBlob(blob, { filename = "untitled" } = {}) {
53
97
  });
54
98
  };
55
99
 
56
- a.click();
100
+ a.click();
101
+ }
102
+
103
+ /**
104
+ * Extract filename and extension from a string path
105
+ * @param {string} path
106
+ * @returns {string} filename
107
+ */
108
+ export function getFilename(path) {
109
+ return path.split(/[\\/]/).pop();
110
+ }
111
+
112
+ /**
113
+ * Estimate file size in megabytes from a Data URL
114
+ * @param {string} data
115
+ * @returns {number}
116
+ */
117
+ export function estimateFileSize(data) {
118
+ const base64Length = data.length - (data.indexOf(',') + 1);
119
+ return (base64Length * (3 / 4) - 2) / 1024 / 1024;
57
120
  }
58
121
 
59
122
  export function getFileExtension(path) {
@@ -65,13 +128,122 @@ export function getFileExtension(path) {
65
128
  }
66
129
 
67
130
  /**
68
- *
69
- * @param {string} extension
70
- * @returns {string} mimeType
131
+ *
132
+ * @param {string} extension
133
+ * @returns {string}
71
134
  */
72
135
  export function getMimeType(extension) {
73
- if (extension === "json") return "application/json";
74
- if (extension === "txt") return "text";
75
- if (extension === "png") return "image/png";
76
- if (extension === "jpeg" || extension === "jpg") return "image/jpeg";
136
+ if (extension === 'json') return 'application/json';
137
+ if (extension === 'txt') return 'text';
138
+ if (extension === 'png') return 'image/png';
139
+ if (extension === 'jpeg' || extension === 'jpg') return 'image/jpeg';
140
+ }
141
+
142
+ /**
143
+ *
144
+ * @param {File|File[]} files
145
+ */
146
+ export async function saveInBrowser(files) {
147
+ /**
148
+ * @param {File} file
149
+ */
150
+ async function saveFile({ filename, data, blob }) {
151
+ if (!blob) {
152
+ blob = await createBlobFromDataURL(data);
153
+ }
154
+
155
+ await downloadBlob(blob, { filename });
156
+ }
157
+
158
+ if (Array.isArray(files)) {
159
+ return Promise.all(files.map((file) => saveFile(file)));
160
+ } else {
161
+ await saveFile(files);
162
+ }
163
+ }
164
+
165
+ /**
166
+ * Save files to disk by sending them to Fragment save plugin. Fallback to saveInBrowser if fails
167
+ * @param {File[]} files
168
+ * @returns {Promise<string[]>}
169
+ */
170
+ export async function saveFiles(files = [], out = []) {
171
+ if (__DEV__) {
172
+ files.forEach((file) => {
173
+ if (!file.size) {
174
+ file.size = estimateFileSize(file.data);
175
+ }
176
+ });
177
+
178
+ const limitInMb = 100;
179
+ const body = {
180
+ files: [],
181
+ };
182
+
183
+ let size = 0;
184
+
185
+ for (let i = 0; i < files.length; i++) {
186
+ const file = files[i];
187
+ if (size < limitInMb) {
188
+ body.files.push(file);
189
+ size += file.size;
190
+ } else {
191
+ break;
192
+ }
193
+ }
194
+
195
+ const response = await fetch('/save', {
196
+ method: 'POST',
197
+ body: JSON.stringify(body),
198
+ headers: {
199
+ Accept: 'application/json',
200
+ 'Content-Type': 'application/json',
201
+ },
202
+ });
203
+ const { filepaths, error } = await response.json();
204
+
205
+ if (response.ok && filepaths?.length) {
206
+ out.push(...filepaths);
207
+
208
+ if (body.files.length < files.length) {
209
+ return saveFiles(files.slice(body.files.length), out);
210
+ }
211
+
212
+ if (out.length < 15) {
213
+ out.forEach((filepath) => {
214
+ console.log(`[fragment] Saved ${filepath}`);
215
+ });
216
+ } else {
217
+ console.log(`[fragment] Saved ${out.length} files.`, {
218
+ filepaths: out,
219
+ });
220
+ }
221
+
222
+ return out;
223
+ } else {
224
+ console.error(`[fragment] Error while saving files on disk.`);
225
+ await saveInBrowser(files);
226
+ }
227
+ } else {
228
+ await saveInBrowser(files);
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Save a blob on disk
234
+ * @param {Blob} blob
235
+ * @param {object} options
236
+ * @returns {Promise<string[]>}
237
+ */
238
+ export async function saveBlob(blob, { filename, exportDir }) {
239
+ const data = await createDataURLFromBlob(blob);
240
+
241
+ return saveFiles([
242
+ {
243
+ filename,
244
+ data,
245
+ exportDir,
246
+ encoding: 'base64',
247
+ },
248
+ ]);
77
249
  }
@@ -3,11 +3,11 @@ const regex = /<filepath:\/\/(.*)>/;
3
3
  export function getShaderPath(shader) {
4
4
  const match = shader.match(/<filepath:\/\/(.*)>/);
5
5
  return match && match[1];
6
- };
6
+ }
7
7
 
8
8
  export function removeShaderPath(shader, filepath = getShaderPath(shader)) {
9
9
  if (filepath) {
10
- return shader.replace(`// <filepath://${filepath}>`, "");
10
+ return shader.replace(`// <filepath://${filepath}>`, '');
11
11
  }
12
12
 
13
13
  return shader;
@@ -1,5 +1,5 @@
1
- import { displayError } from "../stores/errors";
2
- import { getShaderPath, removeShaderPath } from "./glsl.utils";
1
+ import { displayError } from '../stores/errors';
2
+ import { getShaderPath, removeShaderPath } from './glsl.utils';
3
3
 
4
4
  const methods = ['attachShader'];
5
5
 
@@ -13,38 +13,52 @@ for (let i = 0; i < methods.length; i++) {
13
13
 
14
14
  function createUUID() {
15
15
  function s4() {
16
- return Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
16
+ return Math.floor((1 + Math.random()) * 0x10000)
17
+ .toString(16)
18
+ .substring(1);
17
19
  }
18
20
 
19
- return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
20
- };
21
+ return (
22
+ s4() +
23
+ s4() +
24
+ '-' +
25
+ s4() +
26
+ '-' +
27
+ s4() +
28
+ '-' +
29
+ s4() +
30
+ '-' +
31
+ s4() +
32
+ s4() +
33
+ s4()
34
+ );
35
+ }
21
36
 
22
37
  function e(method, fn) {
23
- contexts.forEach(context => {
38
+ contexts.forEach((context) => {
24
39
  const f = context.prototype[method];
25
40
 
26
- context.prototype[method] = function() {
27
- var res = f.apply( this, arguments );
28
- res = fn.apply( this, [ res, arguments ] ) || res;
41
+ context.prototype[method] = function () {
42
+ var res = f.apply(this, arguments);
43
+ res = fn.apply(this, [res, arguments]) || res;
29
44
  return res;
30
- }
31
- })
45
+ };
46
+ });
32
47
  }
33
48
 
34
49
  const FRAGMENT_SHADER = 35632;
35
50
  const VERTEX_SHADER = 35633;
36
51
 
37
52
  class ShaderCompileError extends Error {
38
-
39
53
  constructor({
40
54
  source,
41
- filename = "",
55
+ filename = '',
42
56
  lineNumber,
43
- message = `Cannot compile ${filename !== "" ? filename : "shader"}`
57
+ message = `Cannot compile ${filename !== '' ? filename : 'shader'}`,
44
58
  } = {}) {
45
59
  super(message, filename, lineNumber);
46
60
 
47
- this.name = "ShaderCompileError";
61
+ this.name = 'ShaderCompileError';
48
62
  this.source = source;
49
63
  this.lineNumber = lineNumber;
50
64
 
@@ -52,7 +66,7 @@ class ShaderCompileError extends Error {
52
66
  }
53
67
  }
54
68
 
55
- e('createShader', function(res, args) {
69
+ e('createShader', function (res, args) {
56
70
  if (!this.__uuid) {
57
71
  this.__uuid = createUUID();
58
72
  }
@@ -61,18 +75,18 @@ e('createShader', function(res, args) {
61
75
  res.__type = args[0];
62
76
  });
63
77
 
64
- e('attachShader', function(res, args) {
78
+ e('attachShader', function (res, args) {
65
79
  const program = args[0];
66
80
  const shader = args[1];
67
81
 
68
82
  if (shader.__type === FRAGMENT_SHADER) {
69
- program.__fragmentShader = shader;
83
+ program.__fragmentShader = shader;
70
84
  } else if (shader.__type === VERTEX_SHADER) {
71
85
  program.__vertexShader = shader;
72
86
  }
73
87
  });
74
88
 
75
- e('shaderSource', function(res, args) {
89
+ e('shaderSource', function (res, args) {
76
90
  const shader = args[0];
77
91
  const source = args[1];
78
92
 
@@ -81,25 +95,29 @@ e('shaderSource', function(res, args) {
81
95
  const filepath = getShaderPath(source);
82
96
 
83
97
  if (filepath) {
84
- const filename = filepath.replace(`${__CWD__}/`, "");
98
+ const filename = filepath.replace(`${__CWD__}/`, '');
85
99
 
86
100
  shader.__filepath = filepath;
87
101
  shader.__filename = filename;
88
102
  }
89
103
  });
90
104
 
91
- e('createProgram', function(res, args) {
105
+ e('createProgram', function (res, args) {
92
106
  res.__uuid = createUUID();
93
107
  });
94
108
 
95
- e('compileShader', function(res, args) {
109
+ e('compileShader', function (res, args) {
96
110
  const gl = this;
97
111
  const shader = args[0];
98
112
  const filename = shader.__filename;
99
113
 
100
114
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
101
- const { source, lineNumber, message } = getShaderError(gl, shader, shader.__type);
102
-
115
+ const { source, lineNumber, message } = getShaderError(
116
+ gl,
117
+ shader,
118
+ shader.__type,
119
+ );
120
+
103
121
  const error = new ShaderCompileError({
104
122
  source,
105
123
  message,
@@ -118,7 +136,7 @@ function getShaderError(gl, shader, type) {
118
136
  if (status && errors === '') return '';
119
137
 
120
138
  const errorMatches = errors.match(/ERROR: 0:(\d+):([\s\S]*$)/);
121
-
139
+
122
140
  if (errorMatches) {
123
141
  const lineNumber = parseInt(errorMatches[1]);
124
142
  const message = errorMatches[2];
@@ -126,7 +144,7 @@ function getShaderError(gl, shader, type) {
126
144
  const source = handleSource(shaderSource, lineNumber);
127
145
 
128
146
  return {
129
- message,
147
+ message,
130
148
  source: source,
131
149
  lineNumber,
132
150
  };
@@ -141,14 +159,14 @@ function handleSource(source, errorLine) {
141
159
  const lines = (hasPath ? removeShaderPath(source) : source).split('\n');
142
160
  const lines2 = [];
143
161
 
144
- const from = Math.max( errorLine - 6, 0 );
145
- const to = Math.min( errorLine + 6, lines.length );
162
+ const from = Math.max(errorLine - 6, 0);
163
+ const to = Math.min(errorLine + 6, lines.length);
146
164
 
147
- for ( let i = from; i < to; i ++ ) {
165
+ for (let i = from; i < to; i++) {
148
166
  const line = i + 1;
149
167
 
150
- lines2.push( `${line === errorLine ? '>' : ' '} ${line}: ${lines[ i ]}` );
168
+ lines2.push(`${line === errorLine ? '>' : ' '} ${line}: ${lines[i]}`);
151
169
  }
152
170
 
153
- return lines2.join( '\n' );
171
+ return lines2.join('\n');
154
172
  }
@@ -1,39 +1,42 @@
1
1
  /**
2
- *
3
- * @param {Map} map
4
- * @param {string} key
5
- * @param {any} find
2
+ *
3
+ * @param {Map} map
4
+ * @param {string} key
5
+ * @param {any} find
6
6
  */
7
7
  export const addToMapArray = (map, key, item) => {
8
- if (map.has(key)) {
9
- map.set(key, [...map.get(key), item]);
10
- } else {
11
- map.set(key, [item]);
12
- }
13
- }
8
+ if (map.has(key)) {
9
+ map.set(key, [...map.get(key), item]);
10
+ } else {
11
+ map.set(key, [item]);
12
+ }
13
+ };
14
14
 
15
15
  /**
16
- *
17
- * @param {Map} map
18
- * @param {string} key
19
- * @param {function} findIndex
16
+ *
17
+ * @param {Map} map
18
+ * @param {string} key
19
+ * @param {function} findIndex
20
20
  */
21
21
  export const removeFromMapArray = (map, key, findIndex) => {
22
- if (map.has(key)) {
23
- const items = map.get(key);
24
- const index = items.findIndex(findIndex);
22
+ if (map.has(key)) {
23
+ const items = map.get(key);
24
+ const index = items.findIndex(findIndex);
25
25
 
26
- if (index >= 0) {
27
- const newItems = [...items];
28
- newItems.splice(index, 1);
26
+ if (index >= 0) {
27
+ const newItems = [...items];
28
+ newItems.splice(index, 1);
29
29
 
30
- if (newItems.length > 0) {
31
- map.set(key, newItems);
32
- } else {
33
- map.delete(key);
34
- }
35
- }
36
- } else {
37
- console.error(`removeFromMapArray: key ${key} doesn't exist in Map.`, map);
38
- }
30
+ if (newItems.length > 0) {
31
+ map.set(key, newItems);
32
+ } else {
33
+ map.delete(key);
34
+ }
35
+ }
36
+ } else {
37
+ console.error(
38
+ `removeFromMapArray: key ${key} doesn't exist in Map.`,
39
+ map,
40
+ );
41
+ }
39
42
  };
@@ -1,23 +1,27 @@
1
1
  /**
2
2
  * Map a value from one range to another
3
- * @param {Number} value
4
- * @param {Number} min
5
- * @param {Number} max
6
- * @param {Number} nmin - The new minimum
7
- * @param {Number} nmax - The new maximum
3
+ * @param {Number} value
4
+ * @param {Number} min
5
+ * @param {Number} max
6
+ * @param {Number} nmin - The new minimum
7
+ * @param {Number} nmax - The new maximum
8
8
  * @returns {Number} result
9
9
  */
10
10
  export function map(value, min, max, nmin, nmax) {
11
- return ((value - min) / (max - min)) * (nmax - nmin) + nmin;
11
+ return ((value - min) / (max - min)) * (nmax - nmin) + nmin;
12
12
  }
13
13
 
14
14
  /**
15
15
  * Clamp a number between min and max
16
- * @param {Number} value
17
- * @param {Number} min
18
- * @param {Number} max
16
+ * @param {Number} value
17
+ * @param {Number} min
18
+ * @param {Number} max
19
19
  * @returns {Number} result
20
20
  */
21
21
  export function clamp(value, min, max) {
22
- return Math.max(min, Math.min(value, max));
22
+ return Math.max(min, Math.min(value, max));
23
+ }
24
+
25
+ export function roundToStep(value, step) {
26
+ return Math.round(value * (1 / step)) / (1 / step);
23
27
  }
@@ -1,18 +1,18 @@
1
- <!DOCTYPE html>
1
+ <!doctype html>
2
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <link rel="icon" href="/favicon.ico" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <link rel="stylesheet" href="/css/global.css" />
8
- <title>fragment</title>
9
- </head>
10
- <body>
11
- <div class="loading">
12
- <h1 class="loading__title">[fragment]</h1>
13
- <span class="loading__step">▢ Loading dependencies...</span>
14
- </div>
15
- <div id="app"></div>
16
- <script type="module" src="/main.js"></script>
17
- </body>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" href="/favicon.ico" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <link rel="stylesheet" href="/css/global.css" />
8
+ <title>fragment</title>
9
+ </head>
10
+ <body>
11
+ <div class="loading">
12
+ <h1 class="loading__title">[fragment]</h1>
13
+ <span class="loading__step">▢ Loading dependencies...</span>
14
+ </div>
15
+ <div id="app"></div>
16
+ <script type="module" src="/main.js"></script>
17
+ </body>
18
18
  </html>
@@ -1,9 +1,9 @@
1
- import "./app/stores/console";
1
+ import './app/stores/console';
2
2
  import App from './app/App.svelte';
3
3
 
4
4
  const app = new App({
5
- target: document.getElementById('app'),
6
- props: {},
5
+ target: document.getElementById('app'),
6
+ props: {},
7
7
  });
8
8
 
9
- export default app
9
+ export default app;