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,146 +1,159 @@
1
1
  <script>
2
- import { createEventDispatcher } from "svelte";
3
- import SelectChevrons from "../SelectChevrons.svelte";
4
-
5
- export let options = [];
6
- export let name = "";
7
- export let value;
8
- export let disabled = false;
9
- export let title = "";
10
- export let context = null;
11
- export let key = "";
12
-
13
- let node;
14
- let sanitizedValue, sanitizedOptions = [];
15
-
16
- const dispatch = createEventDispatcher();
17
-
18
- function toStringifiedValue(option, optionType = typeof option) {
19
- if (option === null) {
20
- return `null`;
21
- } else if (option === undefined) {
22
- return `undefined`;
23
- } else if (optionType === "object") {
24
- return toStringifiedValue(option.value);
25
- } else if (optionType === "function") {
26
- return option.name;
27
- }
28
-
29
- return option.toString();
30
- }
31
-
32
- $: {
33
- sanitizedOptions = [];
34
-
35
- for (let i = 0; i < options.length; i++) {
36
- let option = options[i];
37
- let optionType = typeof option;
38
- let disabled = (optionType === "object" && typeof option.disabled === "boolean") ? option.disabled : false;
39
- let _value = optionType === "object" ? option.value : option;
40
-
41
- let stringifiedValue = toStringifiedValue(option);
42
- let label;
43
-
44
- if (_value === value) {
45
- sanitizedValue = stringifiedValue;
46
- }
47
-
48
- if (option.label) {
49
- label = option.label;
50
- } else {
51
- label = stringifiedValue;
52
- }
53
-
54
- sanitizedOptions[i] = {
55
- label,
56
- value: stringifiedValue,
57
- disabled
58
- };
59
- }
60
- }
61
-
62
- function handleChange(event) {
63
- const index = sanitizedOptions.findIndex((opt) => opt.value === event.currentTarget.value);
64
- const option = options[index]
65
- const newValue = typeof option === "object" ? option.value : option;
66
-
67
- value = newValue;
68
-
69
- dispatch("change", newValue);
70
- }
71
-
2
+ import { createEventDispatcher } from 'svelte';
3
+ import SelectChevrons from '../SelectChevrons.svelte';
4
+
5
+ export let options = [];
6
+ export let name = '';
7
+ export let value;
8
+ export let disabled = false;
9
+ export let title = '';
10
+ export let context = null;
11
+ export let key = '';
12
+
13
+ let node;
14
+ let sanitizedValue,
15
+ sanitizedOptions = [];
16
+
17
+ const dispatch = createEventDispatcher();
18
+
19
+ function toStringifiedValue(option, optionType = typeof option) {
20
+ if (option === null) {
21
+ return `null`;
22
+ } else if (option === undefined) {
23
+ return `undefined`;
24
+ } else if (optionType === 'object') {
25
+ return toStringifiedValue(option.value);
26
+ } else if (optionType === 'function') {
27
+ return option.name;
28
+ }
29
+
30
+ return option.toString();
31
+ }
32
+
33
+ $: {
34
+ sanitizedOptions = [];
35
+
36
+ for (let i = 0; i < options.length; i++) {
37
+ let option = options[i];
38
+ let optionType = typeof option;
39
+ let disabled =
40
+ optionType === 'object' && typeof option.disabled === 'boolean'
41
+ ? option.disabled
42
+ : false;
43
+ let _value = optionType === 'object' ? option.value : option;
44
+
45
+ let stringifiedValue = toStringifiedValue(option);
46
+ let label;
47
+
48
+ if (_value === value) {
49
+ sanitizedValue = stringifiedValue;
50
+ }
51
+
52
+ if (option.label) {
53
+ label = option.label;
54
+ } else {
55
+ label = stringifiedValue;
56
+ }
57
+
58
+ sanitizedOptions[i] = {
59
+ label,
60
+ value: stringifiedValue,
61
+ disabled,
62
+ };
63
+ }
64
+ }
65
+
66
+ function handleChange(event) {
67
+ const index = sanitizedOptions.findIndex(
68
+ (opt) => opt.value === event.currentTarget.value,
69
+ );
70
+ const option = options[index];
71
+ const newValue = typeof option === 'object' ? option.value : option;
72
+
73
+ value = newValue;
74
+
75
+ dispatch('change', newValue);
76
+ }
72
77
  </script>
73
78
 
74
79
  <div
75
- class="select-input"
76
- class:disabled={disabled}
77
- class:single={sanitizedOptions.length === 1}
80
+ class="select-input"
81
+ class:disabled
82
+ class:single={sanitizedOptions.length === 1}
78
83
  >
79
- <div class="container">
80
- <select class="select" bind:this={node} on:change={handleChange} {name} {disabled} {title} bind:value={sanitizedValue}>
81
- {#each sanitizedOptions as option}
82
- <option value={option.value} selected={sanitizedValue === option.value} disabled={option.disabled}>{option.label}</option>
83
- {/each}
84
- </select>
85
- {#if sanitizedOptions.length > 1 }
86
- <SelectChevrons />
87
- {/if}
88
- </div>
84
+ <div class="container">
85
+ <select
86
+ class="select"
87
+ bind:this={node}
88
+ on:change={handleChange}
89
+ {name}
90
+ {disabled}
91
+ {title}
92
+ bind:value={sanitizedValue}
93
+ >
94
+ {#each sanitizedOptions as option}
95
+ <option
96
+ value={option.value}
97
+ selected={sanitizedValue === option.value}
98
+ disabled={option.disabled}>{option.label}</option
99
+ >
100
+ {/each}
101
+ </select>
102
+ {#if sanitizedOptions.length > 1}
103
+ <SelectChevrons />
104
+ {/if}
105
+ </div>
89
106
  </div>
90
107
 
91
108
  <style>
92
- .select-input {
93
- width: 100%;
94
- }
95
-
96
- .container {
97
- position: relative;
109
+ .select-input {
110
+ width: 100%;
98
111
 
99
- display: flex;
100
- height: var(--height-input);
101
- margin: 2px 0;
112
+ color: var(--color-text-input);
113
+ }
102
114
 
103
- color: rgba(255, 255, 255, 0.5);
115
+ .select-input.disabled {
116
+ color: var(--color-text-input-disabled);
117
+ }
104
118
 
105
- box-shadow: inset 0 0 0 1px var(--color-border-input);
106
- border-radius: var(--border-radius-input);
107
- background-color: var(--color-background-input);
108
- }
119
+ .container {
120
+ position: relative;
109
121
 
110
- .select-input:not(.disabled) .container:hover {
111
- box-shadow: inset 0 0 0 1px var(--color-active);
112
- }
122
+ display: flex;
123
+ height: var(--height-input);
124
+ margin: 2px 0;
113
125
 
114
- .container:focus-within {
115
- box-shadow: 0 0 0 2px var(--color-active);
116
- }
126
+ box-shadow: inset 0 0 0 1px var(--color-border-input);
127
+ border-radius: var(--border-radius-input);
128
+ background-color: var(--color-background-input);
129
+ }
117
130
 
118
- .select {
119
- padding: 0 var(--padding, 6px) 0 var(--padding, 6px);
131
+ .select-input:not(.disabled) .container:hover {
132
+ box-shadow: inset 0 0 0 1px var(--color-active);
133
+ }
120
134
 
121
- width: 100%;
122
-
123
- color: inherit;
124
- font-size: var(--font-size-input);
135
+ .container:focus-within {
136
+ box-shadow: 0 0 0 2px var(--color-active);
137
+ }
125
138
 
126
- outline: 0;
127
- background-color: transparent;
128
- }
139
+ .select {
140
+ padding: 0 var(--padding, 6px) 0 var(--padding, 6px);
129
141
 
130
- .select-input:not(.disabled) .select {
131
- cursor: pointer;
132
- }
142
+ width: 100%;
133
143
 
134
- :global(.field__section:hover .select-input:not(.disabled) .container) {
135
- color: var(--color-text);
136
- }
144
+ color: inherit;
145
+ font-size: var(--font-size-input);
137
146
 
138
- .select-input:not(.disabled) .select:focus {
139
- color: var(--color-text);
140
- }
147
+ outline: 0;
148
+ background-color: transparent;
149
+ opacity: 1;
150
+ }
141
151
 
142
- .select-input:not(.disabled) .select:hover {
143
- color: var(--color-text);
144
- }
152
+ .select-input:not(.disabled) .select {
153
+ cursor: pointer;
154
+ }
145
155
 
156
+ .select-input:not(.disabled) .select:focus {
157
+ color: var(--color-text);
158
+ }
146
159
  </style>
@@ -1,20 +1,19 @@
1
1
  <script>
2
- import Input from "./Input.svelte";
3
-
4
- export let value;
5
- export let label = "";
6
- export let disabled = false;
7
- export let context = null;
8
- export let key = "";
2
+ import Input from './Input.svelte';
9
3
 
4
+ export let value;
5
+ export let label = '';
6
+ export let disabled = false;
7
+ export let context = null;
8
+ export let key = '';
10
9
  </script>
11
10
 
12
11
  <div class="text-input">
13
- <Input {context} {key} bind:value={value} {label} {disabled} on:change on:input />
12
+ <Input {context} {key} bind:value {label} {disabled} on:change on:input />
14
13
  </div>
15
14
 
16
15
  <style>
17
- .text-input {
18
- width: 100%;
19
- }
16
+ .text-input {
17
+ width: 100%;
18
+ }
20
19
  </style>
@@ -1,92 +1,96 @@
1
1
  <script>
2
- import { createEventDispatcher } from "svelte";
3
- import FieldInputRow from "./FieldInputRow.svelte";
4
- import NumberInput from "./NumberInput.svelte";
5
-
6
- export let value;
7
- export let suffix = "";
8
- export let min = -Infinity;
9
- export let max = Infinity;
10
- export let step = 0.1;
11
- export let locked = false;
12
- export let disabled = false;
13
- export let context = null;
14
- export let key = "";
15
-
16
- const dispatch = createEventDispatcher();
17
-
18
- $: isArray = Array.isArray(value);
19
- $: isObject = !isArray && typeof value === "object";
20
- $: components = isObject ? Object.values(value) : value;
21
- $: keys = isObject ? Object.keys(value) : value.map(() => undefined);
22
-
23
- function dispatchChange() {
24
- let needsUpdate = false;
25
- for (let i = 0; i < components.length; i++) {
26
- const key = isArray ? i : keys[i];
27
-
28
- if (value[key] !== components[i]) {
29
- value[key] = components[i];
30
- needsUpdate = true;
31
- }
32
- }
33
-
34
- if (needsUpdate) {
35
- dispatch('change', value);
36
- }
37
- }
38
-
39
- function handleComponentChange(newValue, componentIndex) {
40
- let ratio = newValue / components[componentIndex];
41
-
42
- if (!isFinite(ratio)) {
43
- ratio = 1;
44
- }
45
-
46
- components = components.map((component, index) => {
47
- return index === componentIndex ? newValue :
48
- locked ? (Math.round(component * ratio * (1/step)) / (1/step)) : component;
49
- });
50
-
51
- dispatchChange();
52
- }
53
-
2
+ import { createEventDispatcher } from 'svelte';
3
+ import FieldInputRow from './FieldInputRow.svelte';
4
+ import NumberInput from './NumberInput.svelte';
5
+
6
+ export let value;
7
+ export let suffix = '';
8
+ export let min = -Infinity;
9
+ export let max = Infinity;
10
+ export let step = 0.1;
11
+ export let locked = false;
12
+ export let disabled = false;
13
+ export let context = null;
14
+ export let key = '';
15
+
16
+ const dispatch = createEventDispatcher();
17
+
18
+ $: isArray = Array.isArray(value);
19
+ $: isObject = !isArray && typeof value === 'object';
20
+ $: components = isObject ? Object.values(value) : value;
21
+ $: keys = isObject ? Object.keys(value) : value.map(() => undefined);
22
+
23
+ function dispatchChange() {
24
+ let needsUpdate = false;
25
+ for (let i = 0; i < components.length; i++) {
26
+ const key = isArray ? i : keys[i];
27
+
28
+ if (value[key] !== components[i]) {
29
+ value[key] = components[i];
30
+ needsUpdate = true;
31
+ }
32
+ }
33
+
34
+ if (needsUpdate) {
35
+ dispatch('change', value);
36
+ }
37
+ }
38
+
39
+ function handleComponentChange(newValue, componentIndex) {
40
+ let ratio = newValue / components[componentIndex];
41
+
42
+ if (!isFinite(ratio)) {
43
+ ratio = 1;
44
+ }
45
+
46
+ components = components.map((component, index) => {
47
+ return index === componentIndex
48
+ ? newValue
49
+ : locked
50
+ ? Math.round(component * ratio * (1 / step)) / (1 / step)
51
+ : component;
52
+ });
53
+
54
+ dispatchChange();
55
+ }
54
56
  </script>
55
57
 
56
- <div class="vector-container vec{components.length}" class:locked={locked}>
57
- <FieldInputRow --grid-template-columns={components.map(() => "1fr").join(" ")}>
58
- {#each components as component, index}
59
- <NumberInput
60
- {min}
61
- {max}
62
- {step}
63
- {suffix}
64
- {disabled}
65
- {context}
66
- {key}
67
- label={keys[index]}
68
- value={component}
69
- on:change={(event) => handleComponentChange(event.detail, index)}
70
- />
71
- {/each}
72
- </FieldInputRow>
58
+ <div class="vector-container vec{components.length}" class:locked>
59
+ <FieldInputRow
60
+ --grid-template-columns={components.map(() => '1fr').join(' ')}
61
+ >
62
+ {#each components as component, index}
63
+ <NumberInput
64
+ {min}
65
+ {max}
66
+ {step}
67
+ {suffix}
68
+ {disabled}
69
+ {context}
70
+ {key}
71
+ label={keys[index]}
72
+ value={component}
73
+ on:change={(event) =>
74
+ handleComponentChange(event.detail, index)}
75
+ />
76
+ {/each}
77
+ </FieldInputRow>
73
78
  </div>
74
79
 
75
80
  <style>
76
- .vector-container {
77
- width: 100%;
78
- }
79
-
80
- :global(.vector-container.locked .number-input:not(:last-child):after) {
81
- content: '';
81
+ .vector-container {
82
+ width: 100%;
83
+ }
82
84
 
83
- position: absolute;
84
- top: 50%;
85
- right: calc(var(--column-gap) * -1);
86
- width: var(--column-gap);
87
- height: 1px;
85
+ :global(.vector-container.locked .number-input:not(:last-child):after) {
86
+ content: '';
88
87
 
89
- background-color: var(--color-border-input);
90
- }
88
+ position: absolute;
89
+ top: 50%;
90
+ right: calc(var(--column-gap) * -1);
91
+ width: var(--column-gap);
92
+ height: 1px;
91
93
 
94
+ background-color: var(--color-border-input);
95
+ }
92
96
  </style>