fragment-tools 0.1.13 → 0.1.14

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 (52) hide show
  1. package/bin/index.js +2 -2
  2. package/package.json +4 -5
  3. package/src/cli/log.js +31 -21
  4. package/src/cli/plugins/check-dependencies.js +47 -30
  5. package/src/cli/plugins/hot-shader-replacement.js +384 -0
  6. package/src/cli/plugins/hot-sketch-reload.js +3 -13
  7. package/src/cli/plugins/screenshot.js +57 -20
  8. package/src/cli/server.js +144 -133
  9. package/src/client/app/App.svelte +3 -3
  10. package/src/client/app/client.js +55 -39
  11. package/src/client/app/components/Init.svelte +12 -9
  12. package/src/client/app/helpers.js +42 -0
  13. package/src/client/app/hooks.js +20 -0
  14. package/src/client/app/inputs/Keyboard.js +13 -15
  15. package/src/client/app/inputs/MIDI.js +14 -15
  16. package/src/client/app/lib/canvas-recorder/CanvasRecorder.js +41 -21
  17. package/src/client/app/lib/gl/Renderer.js +127 -139
  18. package/src/client/app/modules/Exports.svelte +62 -43
  19. package/src/client/app/modules/MidiPanel.svelte +100 -101
  20. package/src/client/app/modules/Params.svelte +116 -103
  21. package/src/client/app/renderers/2DRenderer.js +3 -3
  22. package/src/client/app/renderers/FragmentRenderer.js +30 -23
  23. package/src/client/app/renderers/P5Renderer.js +10 -7
  24. package/src/client/app/renderers/THREERenderer.js +136 -94
  25. package/src/client/app/stores/exports.js +36 -20
  26. package/src/client/app/stores/props.js +28 -5
  27. package/src/client/app/stores/renderers.js +22 -15
  28. package/src/client/app/stores/sketches.js +7 -9
  29. package/src/client/app/stores/utils.js +95 -38
  30. package/src/client/app/triggers/Keyboard.js +88 -79
  31. package/src/client/app/triggers/MIDI.js +110 -84
  32. package/src/client/app/ui/Field.svelte +343 -240
  33. package/src/client/app/ui/FieldGroup.svelte +106 -94
  34. package/src/client/app/ui/FieldSection.svelte +125 -116
  35. package/src/client/app/ui/ParamsMultisampling.svelte +96 -95
  36. package/src/client/app/ui/ParamsOutput.svelte +113 -113
  37. package/src/client/app/ui/SelectChevrons.svelte +27 -15
  38. package/src/client/app/ui/SketchRenderer.svelte +761 -667
  39. package/src/client/app/ui/fields/ButtonInput.svelte +61 -48
  40. package/src/client/app/ui/fields/CheckboxInput.svelte +67 -61
  41. package/src/client/app/ui/fields/ColorInput.svelte +294 -238
  42. package/src/client/app/ui/fields/ImageInput.svelte +123 -121
  43. package/src/client/app/ui/fields/Input.svelte +100 -111
  44. package/src/client/app/ui/fields/ListInput.svelte +96 -96
  45. package/src/client/app/ui/fields/NumberInput.svelte +121 -116
  46. package/src/client/app/ui/fields/ProgressInput.svelte +80 -73
  47. package/src/client/app/ui/fields/Select.svelte +137 -124
  48. package/src/client/app/ui/fields/VectorInput.svelte +86 -82
  49. package/src/client/app/utils/canvas.utils.js +228 -201
  50. package/src/client/app/utils/file.utils.js +38 -34
  51. package/src/client/public/css/global.css +27 -21
  52. package/src/cli/plugins/hot-shader-reload.js +0 -86
@@ -1,95 +1,104 @@
1
- import Trigger from "./Trigger";
2
- import Keyboard from "../inputs/Keyboard";
3
- import { wildcard, getContext } from "./shared";
4
- import { addToMapArray, removeFromMapArray } from "../utils";
1
+ import Trigger from './Trigger';
2
+ import Keyboard from '../inputs/Keyboard';
3
+ import { wildcard, getContext } from './shared';
4
+ import { addToMapArray, removeFromMapArray } from '../utils';
5
5
 
6
6
  const pressedKeys = new Map();
7
7
  const upKeys = new Map();
8
8
  const downKeys = new Map();
9
9
 
10
10
  export const removeHotListeners = (context) => {
11
- function removeHotFrom(collection) {
12
- for (let trigger of collection) {
13
- const [key, triggers] = trigger;
14
-
15
- collection.set(key, triggers.filter((trigger) => trigger.context !== context));
16
- }
17
- }
18
-
19
- removeHotFrom(pressedKeys);
20
- removeHotFrom(upKeys);
21
- removeHotFrom(downKeys);
11
+ function removeHotFrom(collection) {
12
+ for (let trigger of collection) {
13
+ const [key, triggers] = trigger;
14
+
15
+ collection.set(
16
+ key,
17
+ triggers.filter((trigger) => trigger.context !== context),
18
+ );
19
+ }
20
+ }
21
+
22
+ removeHotFrom(pressedKeys);
23
+ removeHotFrom(upKeys);
24
+ removeHotFrom(downKeys);
22
25
  };
23
26
 
24
27
  function createEventListener(collection) {
25
- return (event) => {
26
- const { key, target } = event;
27
-
28
- if (!target.classList.contains('input')) {
29
- const triggers = [
30
- ...(collection.has(key) ? collection.get(key) : []),
31
- ...(collection.has(wildcard) ? collection.get(wildcard) : []),
32
- ];
33
-
34
- triggers.forEach(trigger => {
35
- if (!Keyboard.enabled) return;
36
-
37
- trigger.run(event);
38
- });
39
- }
40
- };
28
+ return (event) => {
29
+ const { key, target } = event;
30
+
31
+ if (!target.classList.contains('input')) {
32
+ const triggers = [
33
+ ...(collection.has(key) ? collection.get(key) : []),
34
+ ...(collection.has(wildcard) ? collection.get(wildcard) : []),
35
+ ];
36
+
37
+ triggers.forEach((trigger) => {
38
+ if (!Keyboard.enabled) return;
39
+
40
+ trigger.run(event);
41
+ });
42
+ }
43
+ };
41
44
  }
42
45
 
43
46
  function createTrigger(eventName, collection) {
44
- return (key, fn, options = {}) => {
45
- if (typeof key === "function") {
46
- if (typeof fn === "object") {
47
- options = {
48
- ...options,
49
- ...fn,
50
- };
51
- }
52
-
53
- fn = key;
54
- key = "*";
55
-
56
- if (options.key) {
57
- key = options.key;
58
- }
59
- }
60
-
61
- const { hot, enabled, ...params } = options;
62
- const context = getContext();
63
-
64
- const keys = Array.isArray(key) ? key : [...key.split(',').map(k => k !== " " ? k.trim() : k)];
65
-
66
- const trigger = new Trigger({
67
- inputType: 'Keyboard',
68
- eventName,
69
- fn,
70
- context,
71
- params: {...params, key: keys },
72
- hot,
73
- enabled,
74
- destroy: () => {
75
- keys.forEach((key) => {
76
- removeFromMapArray(collection, key, (item) => item.id === trigger.id);
77
- });
78
- }
79
- });
80
-
81
- keys.forEach(key => {
82
- addToMapArray(collection, key, trigger);
83
- });
84
-
85
- return trigger;
86
- };
87
- };
47
+ return (key, fn, options = {}) => {
48
+ if (typeof key === 'function') {
49
+ if (typeof fn === 'object') {
50
+ options = {
51
+ ...options,
52
+ ...fn,
53
+ };
54
+ }
55
+
56
+ fn = key;
57
+ key = '*';
58
+
59
+ if (options.key) {
60
+ key = options.key;
61
+ }
62
+ }
63
+
64
+ const { hot, enabled, ...params } = options;
65
+ const context = getContext();
66
+
67
+ const keys = Array.isArray(key)
68
+ ? key
69
+ : [...`${key}`.split(',').map((k) => (k !== ' ' ? k.trim() : k))];
70
+
71
+ const trigger = new Trigger({
72
+ inputType: 'Keyboard',
73
+ eventName,
74
+ fn,
75
+ context,
76
+ params: { ...params, key: keys },
77
+ hot,
78
+ enabled,
79
+ destroy: () => {
80
+ keys.forEach((key) => {
81
+ removeFromMapArray(
82
+ collection,
83
+ key,
84
+ (item) => item.id === trigger.id,
85
+ );
86
+ });
87
+ },
88
+ });
89
+
90
+ keys.forEach((key) => {
91
+ addToMapArray(collection, key, trigger);
92
+ });
93
+
94
+ return trigger;
95
+ };
96
+ }
88
97
 
89
- window.addEventListener("keypress", createEventListener(pressedKeys));
90
- window.addEventListener("keyup", createEventListener(upKeys));
91
- window.addEventListener("keydown", createEventListener(downKeys));
98
+ window.addEventListener('keypress', createEventListener(pressedKeys));
99
+ window.addEventListener('keyup', createEventListener(upKeys));
100
+ window.addEventListener('keydown', createEventListener(downKeys));
92
101
 
93
102
  export const onKeyPress = createTrigger('onKeyPress', pressedKeys);
94
- export const onKeyDown = createTrigger('onKeyDown', downKeys);
103
+ export const onKeyDown = createTrigger('onKeyDown', downKeys);
95
104
  export const onKeyUp = createTrigger('onKeyUp', upKeys);
@@ -1,7 +1,7 @@
1
- import Trigger from "./Trigger";
2
- import MIDI from "../inputs/MIDI.js";
3
- import { addToMapArray, removeFromMapArray } from "../utils";
4
- import { wildcard, getContext } from "./shared";
1
+ import Trigger from './Trigger';
2
+ import MIDI from '../inputs/MIDI.js';
3
+ import { addToMapArray, removeFromMapArray } from '../utils';
4
+ import { wildcard, getContext } from './shared';
5
5
 
6
6
  const noteons = new Map();
7
7
  const noteoffs = new Map();
@@ -11,33 +11,36 @@ const controlchanges = new Map();
11
11
 
12
12
  /**
13
13
  * Remove listeners from a specific context
14
- * @param {string} context
14
+ * @param {string} context
15
15
  */
16
16
  export const removeHotListeners = (context) => {
17
- function removeHotFrom(collection) {
18
- for (let trigger of collection) {
19
- const [key, triggers] = trigger;
20
-
21
- collection.set(key, triggers.filter((trigger) => trigger.context !== context));
22
- }
23
- }
24
-
25
- removeHotFrom(noteons);
26
- removeHotFrom(noteoffs);
27
- removeHotFrom(numberons);
28
- removeHotFrom(numberoffs);
29
- removeHotFrom(controlchanges);
17
+ function removeHotFrom(collection) {
18
+ for (let trigger of collection) {
19
+ const [key, triggers] = trigger;
20
+
21
+ collection.set(
22
+ key,
23
+ triggers.filter((trigger) => trigger.context !== context),
24
+ );
25
+ }
26
+ }
27
+
28
+ removeHotFrom(noteons);
29
+ removeHotFrom(noteoffs);
30
+ removeHotFrom(numberons);
31
+ removeHotFrom(numberoffs);
32
+ removeHotFrom(controlchanges);
30
33
  };
31
34
 
32
35
  /**
33
36
  * Check all registered listeners for a specific key
34
- * @param {Map} collection
35
- * @param {function} getKey
37
+ * @param {Map} collection
38
+ * @param {function} getKey
36
39
  * @returns {function} listener
37
40
  */
38
41
  function createEventListener(collection, getKey = (event) => event.key) {
39
- return (event) => {
40
- const key = getKey(event);
42
+ return (event) => {
43
+ const key = getKey(event);
41
44
  const { id } = event.srcElement;
42
45
 
43
46
  const triggers = [
@@ -46,78 +49,101 @@ function createEventListener(collection, getKey = (event) => event.key) {
46
49
  ];
47
50
 
48
51
  if (MIDI.enabled && id === MIDI.selectedInputID) {
49
- triggers.forEach(trigger => {
52
+ triggers.forEach((trigger) => {
50
53
  trigger.run(event);
51
54
  });
52
55
  }
53
- };
56
+ };
54
57
  }
55
58
 
56
59
  /**
57
60
  * Create a registering function for a specific event
58
- * @param {string} eventName
59
- * @param {Map} collection
60
- * @returns {function} createListener
61
+ * @param {string} eventName
62
+ * @param {Map} collection
63
+ * @returns {function} createListener
61
64
  */
62
65
  function createTrigger(eventName, collection) {
63
- return (key, fn, options = {}) => {
64
- if (typeof key === "function") {
65
- if (typeof fn === "object") {
66
- options = {
67
- ...options,
68
- ...fn,
69
- };
70
- }
71
-
72
- fn = key;
73
- key = "*";
74
-
75
- if (options.key) {
76
- key = options.key;
77
- }
78
- }
79
-
80
- const { hot, enabled, ...params } = options;
81
- let keys = Array.isArray(key) ? key : [...key.split(',').map(k => k.trim())];
82
-
83
- if (["onControlChange", "onNumberOn", "onNumberOff"].includes(eventName)) {
84
- keys = keys.map((k) => Number(k));
85
- }
86
-
87
- if (!MIDI.enabled) {
88
- MIDI.request();
89
- }
90
-
91
- const context = getContext();
92
-
93
- const trigger = new Trigger({
94
- inputType: 'MIDI',
95
- eventName,
96
- fn,
97
- params: {...params, key: keys },
98
- hot,
99
- context,
100
- enabled,
101
- destroy : () => {
102
- keys.forEach((key) => {
103
- removeFromMapArray(collection, key, (item) => item.id === trigger.id);
104
- });
105
- }
106
- });
107
-
108
- keys.forEach(k => {
109
- addToMapArray(collection, k, trigger);
110
- });
111
-
112
- return trigger;
113
- };
114
- };
66
+ return (key, fn, options = {}) => {
67
+ if (typeof key === 'function') {
68
+ if (typeof fn === 'object') {
69
+ options = {
70
+ ...options,
71
+ ...fn,
72
+ };
73
+ }
74
+
75
+ fn = key;
76
+ key = '*';
77
+
78
+ if (options.key) {
79
+ key = options.key;
80
+ }
81
+ }
82
+
83
+ const { hot, enabled, ...params } = options;
84
+ let keys = Array.isArray(key)
85
+ ? key
86
+ : [...`${key}`.split(',').map((k) => k.trim())];
87
+
88
+ if (
89
+ ['onControlChange', 'onNumberOn', 'onNumberOff'].includes(eventName)
90
+ ) {
91
+ keys = keys.map((k) => (!isNaN(Number(k)) ? Number(k) : k));
92
+ }
93
+
94
+ if (!MIDI.enabled) {
95
+ MIDI.request();
96
+ }
97
+
98
+ const context = getContext();
99
+
100
+ const trigger = new Trigger({
101
+ inputType: 'MIDI',
102
+ eventName,
103
+ fn,
104
+ params: { ...params, key: keys },
105
+ hot,
106
+ context,
107
+ enabled,
108
+ destroy: () => {
109
+ keys.forEach((key) => {
110
+ removeFromMapArray(
111
+ collection,
112
+ key,
113
+ (item) => item.id === trigger.id,
114
+ );
115
+ });
116
+ },
117
+ });
118
+
119
+ keys.forEach((k) => {
120
+ addToMapArray(collection, k, trigger);
121
+ });
122
+
123
+ return trigger;
124
+ };
125
+ }
115
126
 
116
- MIDI.addEventListener("noteon", createEventListener(noteons, (event) => event.note.name));
117
- MIDI.addEventListener("noteoff", createEventListener(noteoffs, (event) => event.note.name));
118
- MIDI.addEventListener("noteon", createEventListener(numberons, (event) => event.note.number));
119
- MIDI.addEventListener("noteoff", createEventListener(numberoffs, (event) => event.note.number));
120
- MIDI.addEventListener("controlchange", createEventListener(controlchanges, (event) => event.note.number));
127
+ MIDI.addEventListener(
128
+ 'noteon',
129
+ createEventListener(noteons, (event) => event.note.name),
130
+ );
131
+ MIDI.addEventListener(
132
+ 'noteoff',
133
+ createEventListener(noteoffs, (event) => event.note.name),
134
+ );
135
+ MIDI.addEventListener(
136
+ 'noteon',
137
+ createEventListener(numberons, (event) => event.note.number),
138
+ );
139
+ MIDI.addEventListener(
140
+ 'noteoff',
141
+ createEventListener(numberoffs, (event) => event.note.number),
142
+ );
143
+ MIDI.addEventListener(
144
+ 'controlchange',
145
+ createEventListener(controlchanges, (event) => event.note.number),
146
+ );
121
147
 
122
148
  export const onNoteOn = createTrigger('onNoteOn', noteons);
123
149
  export const onNoteOff = createTrigger('onNoteOff', noteoffs);