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
@@ -0,0 +1,97 @@
1
+ import CanvasRecorder from './CanvasRecorder.js';
2
+ import {
3
+ Output,
4
+ Mp4OutputFormat,
5
+ MkvOutputFormat,
6
+ MovOutputFormat,
7
+ WebMInputFormat,
8
+ BufferTarget,
9
+ CanvasSource,
10
+ Quality,
11
+ QUALITY_VERY_LOW,
12
+ QUALITY_LOW,
13
+ QUALITY_MEDIUM,
14
+ QUALITY_HIGH,
15
+ QUALITY_VERY_HIGH,
16
+ WebMOutputFormat,
17
+ } from 'mediabunny';
18
+ import { map } from '@fragment/utils/math.utils.js';
19
+ import { VIDEO_FORMATS } from '@fragment/state/exports.svelte.js';
20
+
21
+ class MediaBunnyRecorder extends CanvasRecorder {
22
+ /** @type Quality[] */
23
+ static BITRATES = [
24
+ QUALITY_VERY_LOW,
25
+ QUALITY_LOW,
26
+ QUALITY_MEDIUM,
27
+ QUALITY_HIGH,
28
+ QUALITY_VERY_HIGH,
29
+ ];
30
+
31
+ /**
32
+ *
33
+ * @param {HTMLCanvasElement} canvas
34
+ * @param {object} options
35
+ * @param {codec} options.string
36
+ */
37
+ constructor(canvas, { codec, ...options }) {
38
+ super(canvas, options);
39
+
40
+ /** @type {string} */
41
+ this.codec = codec;
42
+
43
+ const outputFormats = new Map();
44
+ outputFormats.set(VIDEO_FORMATS.MKV, MkvOutputFormat);
45
+ outputFormats.set(VIDEO_FORMATS.MP4, Mp4OutputFormat);
46
+ outputFormats.set(VIDEO_FORMATS.MOV, MovOutputFormat);
47
+ outputFormats.set(VIDEO_FORMATS.WEBM, WebMOutputFormat);
48
+
49
+ const outputFormat = outputFormats.get(this.format);
50
+
51
+ /** @type {Output} */
52
+ this.output = new Output({
53
+ format: new outputFormat(),
54
+ target: new BufferTarget(),
55
+ });
56
+
57
+ const { BITRATES } = MediaBunnyRecorder;
58
+
59
+ const bitrate =
60
+ BITRATES[
61
+ Math.floor(map(this.quality, 1, 100, 0, BITRATES.length - 1))
62
+ ];
63
+
64
+ /** @type {CanvasSource} */
65
+ this.videoSource = new CanvasSource(this.canvas, {
66
+ codec,
67
+ bitrate,
68
+ });
69
+
70
+ this.output.addVideoTrack(this.videoSource, {
71
+ frameRate: this.framerate,
72
+ });
73
+ }
74
+
75
+ async load() {
76
+ await this.output.start();
77
+ }
78
+
79
+ async tick({ frameCount, time }) {
80
+ const timestamp = frameCount / this.framerate;
81
+
82
+ this.videoSource.add(timestamp, this.frameDuration / 1000);
83
+ }
84
+
85
+ async end() {
86
+ await this.output.finalize();
87
+
88
+ const { mimeType } = this.output.format;
89
+ const { buffer } = this.output.target;
90
+
91
+ this.result = new Blob([buffer], { type: mimeType });
92
+
93
+ super.end();
94
+ }
95
+ }
96
+
97
+ export default MediaBunnyRecorder;
@@ -8,7 +8,7 @@ class Renderer {
8
8
  premultipliedAlpha = false,
9
9
  pixelRatio = window.devicePixelRatio,
10
10
  webgl = 2,
11
- }) {
11
+ } = {}) {
12
12
  let gl;
13
13
  let attributes = {
14
14
  depth,
@@ -8,7 +8,7 @@ class Texture {
8
8
  constructor(
9
9
  gl,
10
10
  {
11
- image,
11
+ image = null,
12
12
  name = '',
13
13
  target = gl.TEXTURE_2D,
14
14
  type = gl.UNSIGNED_BYTE,
@@ -9,7 +9,7 @@ export function fragment({
9
9
  canvas = document.createElement('canvas'),
10
10
  shader = defaultFragment,
11
11
  uniforms = {},
12
- }) {
12
+ } = {}) {
13
13
  let _fragmentShader = shader;
14
14
  let _vertexShader = defaultVertex;
15
15
  let _uniforms = uniforms;
@@ -30,7 +30,7 @@ export function fragment({
30
30
 
31
31
  let w, h, pr;
32
32
 
33
- function resize({ width = w, height = h, pixelRatio = pr }) {
33
+ function resize({ width = w, height = h, pixelRatio = pr } = {}) {
34
34
  renderer.setPixelRatio(pixelRatio);
35
35
  renderer.setSize({ width, height });
36
36
 
@@ -64,7 +64,7 @@
64
64
  bottom: 0;
65
65
  width: 1px;
66
66
 
67
- background-color: var(--color-border-input);
67
+ background-color: var(--fragment-input-border-color);
68
68
  }
69
69
 
70
70
  .row {
@@ -83,7 +83,7 @@
83
83
  width: 100%;
84
84
  height: 100%;
85
85
 
86
- background-color: var(--color-active);
86
+ background-color: var(--fragment-accent-color);
87
87
  opacity: var(--opacity, 0);
88
88
  border-radius: 2px;
89
89
  }
@@ -25,8 +25,8 @@
25
25
  grid-template-columns: repeat(10, 1fr);
26
26
  padding: 0 3px;
27
27
 
28
- border-radius: var(--border-radius-input);
29
- background-color: var(--color-background-input);
30
- box-shadow: inset 0 0 0 1px var(--color-border-input);
28
+ border-radius: var(--fragment-input-border-radius);
29
+ background-color: var(--fragment-input-background-color);
30
+ box-shadow: inset 0 0 0 1px var(--fragment-input-border-color);
31
31
  }
32
32
  </style>
@@ -90,12 +90,12 @@
90
90
  .log {
91
91
  --json-tree-string-color: #17d08e;
92
92
  --arrow-sign: rgba(255, 255, 255, 0.5);
93
- --json-tree-font-size: var(--font-size-input);
94
- --json-tree-font-family: var(--font-mono);
93
+ --json-tree-font-size: var(--fragment-input-font-size);
94
+ --json-tree-font-family: var(--fragment-font-family);
95
95
  --json-tree-number-color: #9980ff;
96
96
  --json-tree-symbol-color: #0a0606;
97
97
  --json-tree-boolean-color: #9980ff;
98
- --json-tree-function-color: var(--color-active);
98
+ --json-tree-function-color: var(--fragment-accent-color);
99
99
  /* --json-tree-number-color: #3029cf; */
100
100
  --json-tree-property-color: #5db0d7;
101
101
  --json-tree-label-color: rgba(240, 240, 240, 0.6);
@@ -124,22 +124,22 @@
124
124
 
125
125
  .string {
126
126
  display: block;
127
- font-size: var(--font-size-input);
127
+ font-size: var(--fragment-input-font-size);
128
128
  }
129
129
 
130
130
  .function {
131
- font-size: var(--font-size-input);
131
+ font-size: var(--fragment-input-font-size);
132
132
  font-style: italic;
133
133
  white-space: pre;
134
134
  tab-size: 2em;
135
135
  }
136
136
 
137
137
  :global(
138
- .log ul > .Number,
139
- .log ul > .Boolean,
140
- .log ul > .Date,
141
- .log ul > .Undefined
142
- ) {
138
+ .log ul > .Number,
139
+ .log ul > .Boolean,
140
+ .log ul > .Date,
141
+ .log ul > .Undefined
142
+ ) {
143
143
  margin-left: calc(var(--li-identation) * -1);
144
144
  }
145
145
 
@@ -204,7 +204,7 @@
204
204
  .trace {
205
205
  border-bottom: 1px solid #eee;
206
206
  font-size: 12px;
207
- font-family: var(--font-mono);
207
+ font-family: var(--fragment-font-family);
208
208
  padding: 4px 0 2px;
209
209
  }
210
210
 
@@ -234,7 +234,7 @@
234
234
  height: 16px;
235
235
 
236
236
  border-radius: 9px;
237
- background-color: var(--color-lightblack);
237
+ background-color: var(--fragment-color-lightblack);
238
238
  }
239
239
 
240
240
  .count span {
@@ -261,7 +261,7 @@
261
261
  }
262
262
 
263
263
  .title {
264
- font-family: var(--font-mono);
264
+ font-family: var(--fragment-font-family);
265
265
  font-size: 13px;
266
266
  font-weight: bold;
267
267
  padding-left: 11px;
@@ -114,8 +114,8 @@
114
114
  max-height: 100%;
115
115
 
116
116
  background-color: #1d1d1e;
117
- border-radius: var(--border-radius-input);
118
- box-shadow: inset 0 0 0 1px var(--color-border-input);
117
+ border-radius: var(--fragment-input-border-radius);
118
+ box-shadow: inset 0 0 0 1px var(--fragment-input-border-color);
119
119
  }
120
120
 
121
121
  .scroll {
@@ -138,12 +138,14 @@
138
138
 
139
139
  .scroll::-webkit-scrollbar-track {
140
140
  background-color: var(
141
- --color-lightblack
141
+ --fragment-color-lightblack
142
142
  ); /* color of the tracking area */
143
143
  }
144
144
 
145
145
  .scroll::-webkit-scrollbar-thumb {
146
- background-color: var(--color-active); /* color of the scroll thumb */
146
+ background-color: var(
147
+ --fragment-accent-color
148
+ ); /* color of the scroll thumb */
147
149
  border-radius: 20px; /* roundness of the scroll thumb */
148
150
  }
149
151
  </style>
@@ -7,6 +7,7 @@
7
7
  IMAGE_ENCODINGS,
8
8
  VIDEO_FORMATS,
9
9
  exports,
10
+ getCodecsForFormat,
10
11
  } from '../state/exports.svelte';
11
12
 
12
13
  let { id = layout.getID(), headless = false } = $props();
@@ -81,16 +82,39 @@
81
82
  params={{ options: Object.values(VIDEO_FORMATS) }}
82
83
  onchange={(value) => {
83
84
  exports.videoFormat = value;
85
+
86
+ if (
87
+ !getCodecsForFormat(exports.videoFormat).includes(
88
+ exports.videoCodec,
89
+ )
90
+ ) {
91
+ exports.videoCodec = getCodecsForFormat(
92
+ exports.videoFormat,
93
+ )?.[0];
94
+ }
84
95
  }}
85
96
  />
97
+ {#if [VIDEO_FORMATS.MKV, VIDEO_FORMATS.MP4, VIDEO_FORMATS.WEBM, VIDEO_FORMATS.MOV].includes(exports.videoFormat)}
98
+ <Field
99
+ key="codec"
100
+ value={exports.videoCodec}
101
+ params={{ options: getCodecsForFormat(exports.videoFormat) }}
102
+ onchange={(value) => {
103
+ exports.videoCodec = value;
104
+ }}
105
+ />
106
+ {/if}
86
107
  <Field
87
108
  key="quality"
88
109
  value={exports.videoQuality}
89
110
  params={{
90
- min: 1,
91
- max: 100,
92
- step: 1,
93
- suffix: '%',
111
+ options: [
112
+ { value: 100, label: 'very high' },
113
+ { value: 80, label: 'high' },
114
+ { value: 60, label: 'medium' },
115
+ { value: 40, label: 'low' },
116
+ { value: 20, label: 'very low' },
117
+ ],
94
118
  triggerable: false,
95
119
  }}
96
120
  onchange={(value) => {
@@ -1,13 +1,14 @@
1
1
  /**
2
2
  * @typedef {object} MountParams2DRenderer
3
+ * @property {HTMLCanvasElement} canvas
3
4
  * @property {CanvasRenderingContext2D} context
4
5
  */
5
6
 
6
7
  /**
7
8
  * @param {object} params
8
9
  * @param {number} params.id
9
- * @param {HTMLDivElement} params.container
10
10
  * @param {HTMLCanvasElement} params.canvas
11
+ * @param {HTMLElement} params.container
11
12
  * @param {number} params.width
12
13
  * @param {number} params.height
13
14
  * @param {number} params.pixelRatio
@@ -21,13 +22,15 @@ export let onMountPreview = ({ canvas }) => {
21
22
  };
22
23
 
23
24
  /**
24
- * @param {object} params
25
+ * @param {MountParams2DRenderer} params
26
+ * @param {number} params.id
25
27
  * @param {HTMLCanvasElement} params.canvas
28
+ * @param {HTMLElement} params.container
26
29
  * @param {number} params.width
27
30
  * @param {number} params.height
28
31
  * @param {number} params.pixelRatio
29
32
  */
30
- export let onResizePreview = ({ canvas, width, height, pixelRatio }) => {
33
+ export let onResizePreview = ({ id, canvas, width, height, pixelRatio }) => {
31
34
  canvas.width = width * pixelRatio;
32
35
  canvas.height = height * pixelRatio;
33
36
  canvas.style.width = `${width}px`;
@@ -3,9 +3,32 @@ 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} MountParamsFragmentRenderer
8
+ * @property {HTMLCanvasElement} canvas
9
+ * @property {Frag} frag
10
+ */
11
+
12
+ /**
13
+ * @typedef {object} FragFragmentRenderer
14
+ * @property {number} id
15
+ * @property {Frag} frag
16
+ */
17
+
18
+ /** @type {FragFragmentRenderer[]} */
6
19
  let frags = [];
7
20
 
8
- export let onMountPreview = ({ canvas, id }) => {
21
+ /**
22
+ * @param {object} params
23
+ * @param {number} params.id
24
+ * @param {HTMLCanvasElement} params.canvas
25
+ * @param {HTMLDivElement} params.container
26
+ * @param {number} params.width
27
+ * @param {number} params.height
28
+ * @param {number} params.pixelRatio
29
+ * @returns {MountParamsFragmentRenderer}
30
+ */
31
+ export let onMountPreview = ({ id, canvas }) => {
9
32
  let frag = fragment({
10
33
  canvas,
11
34
  });
@@ -18,13 +41,27 @@ export let onMountPreview = ({ canvas, id }) => {
18
41
  return { canvas, frag };
19
42
  };
20
43
 
44
+ /**
45
+ * @param {MountParamsFragmentRenderer} params
46
+ * @param {number} params.id
47
+ * @param {HTMLCanvasElement} params.canvas
48
+ * @param {number} params.width
49
+ * @param {number} params.height
50
+ * @param {number} params.pixelRatio
51
+ */
21
52
  export let onResizePreview = ({ id, width, height, pixelRatio }) => {
22
53
  let { frag } = frags.find((f) => f.id === id);
23
54
 
24
55
  frag.resize({ width, height, pixelRatio });
25
56
  };
26
57
 
27
- export let onDestroyPreview = ({ canvas, id }) => {
58
+ /**
59
+ * @param {MountParamsFragmentRenderer} params
60
+ * @param {number} params.id
61
+ * @param {HTMLCanvasElement} params.canvas
62
+ * @param {HTMLElement} params.container
63
+ */
64
+ export let onDestroyPreview = ({ id, canvas }) => {
28
65
  let fragIndex = frags.findIndex((f) => f.id === id);
29
66
  let { frag } = frags[fragIndex];
30
67
 
@@ -3,13 +3,6 @@ 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} PreviewP5GLRenderer
8
- * @property {number} id
9
- * @property {p5} p
10
- * @property {boolean} rendered
11
- */
12
-
13
6
  /**
14
7
  * @typedef {object} MountParamsP5GLRenderer
15
8
  * @property {HTMLCanvasElement} canvas
@@ -17,10 +10,10 @@ import { clearError } from '../state/errors.svelte';
17
10
  */
18
11
 
19
12
  /**
20
- * @typedef {object} PreviewParamsP5GLRenderer
21
- * @property {number} params.id
22
- * @property {HTMLDivElement} params.container
23
- * @property {HTMLCanvasElement} params.canvas
13
+ * @typedef {object} PreviewP5GLRenderer
14
+ * @property {number} id
15
+ * @property {p5} p
16
+ * @property {boolean} rendered
24
17
  */
25
18
 
26
19
  /** @type {PreviewP5GLRenderer[]} */
@@ -36,31 +29,30 @@ let previews = [];
36
29
  * @param {number} params.pixelRatio
37
30
  * @returns {MountParamsP5GLRenderer}
38
31
  */
39
- export let onMountPreview = ({ id, container, width, height }) => {
32
+ export let onMountPreview = ({ id, container, canvas, width, height }) => {
40
33
  const p = new p5((sketch) => {
41
34
  sketch.setup = () => {
42
- const canvas = sketch.createCanvas(width, height, 'webgl');
43
- canvas.parent(container);
35
+ sketch.createCanvas(width, height, 'webgl', canvas);
44
36
  };
45
- });
37
+ }, container);
46
38
 
47
- /** @type {PreviewP5GLRenderer} */
48
- const preview = {
39
+ previews.push({
49
40
  id,
50
41
  p,
51
42
  rendered: false,
52
- };
53
-
54
- previews.push(preview);
43
+ });
55
44
 
56
45
  return {
57
- canvas: p.canvas,
46
+ canvas,
58
47
  p,
59
48
  };
60
49
  };
61
50
 
62
51
  /**
63
- * @param {PreviewParamsP5GLRenderer} params
52
+ * @param {MountParamsP5GLRenderer} params
53
+ * @param {number} params.id
54
+ * @param {HTMLCanvasElement} params.canvas
55
+ * @param {HTMLDivElement} params.container
64
56
  */
65
57
  export let onBeforeUpdatePreview = ({ id }) => {
66
58
  const preview = previews.find((p) => p.id === id);
@@ -73,7 +65,10 @@ export let onBeforeUpdatePreview = ({ id }) => {
73
65
  };
74
66
 
75
67
  /**
76
- * @param {PreviewParamsP5GLRenderer} params
68
+ * @param {MountParamsP5GLRenderer} params
69
+ * @param {number} params.id
70
+ * @param {HTMLCanvasElement} params.canvas
71
+ * @param {HTMLDivElement} params.container
77
72
  */
78
73
  export let onAfterUpdatePreview = ({ id }) => {
79
74
  const preview = previews.find((p) => p.id === id);
@@ -91,7 +86,12 @@ export let onAfterUpdatePreview = ({ id }) => {
91
86
  };
92
87
 
93
88
  /**
94
- * @param {PreviewParamsP5GLRenderer} params
89
+ * @param {MountParamsP5GLRenderer} params
90
+ * @param {number} params.id
91
+ * @param {HTMLCanvasElement} params.canvas
92
+ * @param {number} params.width
93
+ * @param {number} params.height
94
+ * @param {number} params.pixelRatio
95
95
  */
96
96
  export let onResizePreview = ({ id, width, height, pixelRatio }) => {
97
97
  const preview = previews.find((p) => p.id === id);
@@ -103,7 +103,10 @@ export let onResizePreview = ({ id, width, height, pixelRatio }) => {
103
103
  };
104
104
 
105
105
  /**
106
- * @param {PreviewParamsP5GLRenderer} params
106
+ * @param {MountParamsP5GLRenderer} params
107
+ * @param {number} params.id
108
+ * @param {HTMLCanvasElement} params.canvas
109
+ * @param {HTMLElement} params.container
107
110
  */
108
111
  export let onDestroyPreview = ({ id }) => {
109
112
  const previewIndex = previews.findIndex((preview) => preview.id === id);
@@ -186,7 +189,6 @@ if (import.meta.hot) {
186
189
 
187
190
  client.on('shader-update', (shaderUpdates) => {
188
191
  previews.forEach(({ p }) => {
189
- console.log('clear error', p._renderer.GL.__uuid);
190
192
  clearError(p._renderer.GL.__uuid);
191
193
  });
192
194
 
@@ -1,28 +1,54 @@
1
1
  import p5 from 'p5';
2
2
 
3
+ /**
4
+ * @typedef {object} MountParamsP5Renderer
5
+ * @property {HTMLCanvasElement} canvas
6
+ * @property {p5} p
7
+ */
8
+
9
+ /**
10
+ * @typedef {object} PreviewP5Renderer
11
+ * @property {number} id
12
+ * @property {p5} p
13
+ */
14
+
15
+ /** @type {PreviewP5Renderer[]} */
3
16
  let previews = [];
4
17
 
5
- export let onMountPreview = ({ id, container, width, height }) => {
18
+ /**
19
+ * @param {object} params
20
+ * @param {number} params.id
21
+ * @param {HTMLCanvasElement} params.canvas
22
+ * @param {HTMLDivElement} params.container
23
+ * @param {number} params.width
24
+ * @param {number} params.height
25
+ * @param {number} params.pixelRatio
26
+ * @returns {MountParamsP5Renderer}
27
+ */
28
+ export let onMountPreview = ({ id, container, canvas, width, height }) => {
6
29
  const p = new p5((sketch) => {
7
30
  sketch.setup = () => {
8
- const canvas = sketch.createCanvas(width, height);
9
- canvas.parent(container);
31
+ sketch.createCanvas(width, height, canvas);
10
32
  };
11
- });
33
+ }, container);
12
34
 
13
- const preview = {
35
+ previews.push({
14
36
  id,
15
37
  p,
16
- };
17
-
18
- previews.push(preview);
38
+ });
19
39
 
20
40
  return {
21
- canvas: p.canvas,
41
+ canvas,
22
42
  p,
23
43
  };
24
44
  };
25
45
 
46
+ /**
47
+ * @param {MountParamsP5Renderer} params
48
+ * @param {number} params.id
49
+ * @param {HTMLCanvasElement} params.canvas
50
+ * @param {HTMLDivElement} params.container
51
+ */
26
52
  export let onBeforeUpdatePreview = ({ id }) => {
27
53
  const preview = previews.find((p) => p.id === id);
28
54
 
@@ -31,6 +57,14 @@ export let onBeforeUpdatePreview = ({ id }) => {
31
57
  }
32
58
  };
33
59
 
60
+ /**
61
+ * @param {MountParamsP5Renderer} params
62
+ * @param {number} params.id
63
+ * @param {HTMLCanvasElement} params.canvas
64
+ * @param {number} params.width
65
+ * @param {number} params.height
66
+ * @param {number} params.pixelRatio
67
+ */
34
68
  export let onResizePreview = ({ id, width, height, pixelRatio }) => {
35
69
  const preview = previews.find((p) => p.id === id);
36
70
 
@@ -40,6 +74,12 @@ export let onResizePreview = ({ id, width, height, pixelRatio }) => {
40
74
  }
41
75
  };
42
76
 
77
+ /**
78
+ * @param {MountParamsP5Renderer} params
79
+ * @param {number} params.id
80
+ * @param {HTMLCanvasElement} params.canvas
81
+ * @param {HTMLElement} params.container
82
+ */
43
83
  export let onDestroyPreview = ({ id }) => {
44
84
  const previewIndex = previews.findIndex((p) => p.id === id);
45
85
  const preview = previews[previewIndex];