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,266 +1,401 @@
1
- <script>
2
- import { createEventDispatcher } from "svelte";
3
-
4
- import Select from "./fields/Select.svelte";
5
- import NumberInput from "./fields/NumberInput.svelte";
6
- import CheckboxInput from "./fields/CheckboxInput.svelte";
7
- import VectorInput from "./fields/VectorInput.svelte";
8
- import TextInput from "./fields/TextInput.svelte";
9
- import ColorInput from "./fields/ColorInput.svelte";
10
- import ListInput from "./fields/ListInput.svelte";
11
- import ButtonInput from "./fields/ButtonInput.svelte";
12
- import ImageInput from "./fields/ImageInput.svelte";
13
- import FieldSection from "./FieldSection.svelte";
14
- import FieldTriggers from "./FieldTriggers.svelte";
15
- import { inferFromParams, inferFromValue } from "../utils/props.utils.js";
16
- import { download } from "../utils/file.utils.js";
17
- import { map } from "../utils/math.utils";
18
- import frameDebounce from "../lib/helpers/frameDebounce.js";
19
- import { getStore } from "../stores/utils";
20
- import { writable } from "svelte/store";
21
-
22
- export let key = "";
23
- export let value = null;
24
- export let context = null;
25
- export let params = {};
26
- export let type = null;
27
-
28
- let offsetWidth;
29
- let showTriggers = false;
30
-
31
- const store = getStore(context, { props: {}}, {
32
- persist: context !== null,
33
- });
34
-
35
- if (!$store.props[key]) {
36
- $store.props[key] = { triggers: [] };
37
- }
38
-
39
- let triggers = writable($store.props[key].triggers.filter((trigger) => trigger.inputType !== undefined));
40
- triggers.subscribe((all) => {
41
- store.update((curr) => {
42
- curr.props[key].triggers = all;
43
-
44
- return curr;
45
- });
46
- })
47
-
48
- const dispatch = createEventDispatcher();
49
- const fields = {
50
- "select": Select,
51
- "number": NumberInput,
52
- "vec": VectorInput,
53
- "checkbox": CheckboxInput,
54
- "text": TextInput,
55
- "list": ListInput,
56
- "color": ColorInput,
57
- "button": ButtonInput,
58
- "download": ButtonInput,
59
- "image": ImageInput,
60
- };
61
-
62
- const onTriggers = {
63
- 'checkbox': () => {
64
- value = !value;
65
-
66
- dispatch('change', value);
67
- },
68
- 'button': (event) => {
69
- value(event);
70
- dispatch('click', event);
71
- },
72
- 'download': (event) => {
73
- let [data, filename] = value(event);
74
-
75
- download(data, filename);
76
- },
77
- 'number': (event = {}) => {
78
- const isValueInRange = event.value >= 0 && event.value <= 1;
79
-
80
- if (isValueInRange && isFinite(params.min) && isFinite(params.max)) {
81
- let v = map(event.value, 0, 1, params.min, params.max);
82
- let step = params.step ? params.step : 1;
83
- let value = Math.round(v * (1 / step)) / (1 / step);
84
-
85
- dispatch('change', value);
86
- }
87
- },
88
- };
89
-
90
- $: fieldType = type ? type : (inferFromParams(params) || inferFromValue(value));
91
- $: fieldProps = composeFieldProps(params);
92
- $: onTrigger = frameDebounce(onTriggers[fieldType]);
93
- $: input = fields[fieldType];
94
- $: label = params.label !== undefined && typeof value !== "function" ? params.label : key;
95
- $: disabled = params.disabled;
96
- $: triggerable = params.triggerable !== false && (
97
- (fieldType === "number" && isFinite(params.min) && isFinite(params.max)) ||
98
- (fieldType === "button")
99
- );
100
- $: {
101
- if (fieldType === "download" || fieldType === "button") {
102
- if (params.label === undefined) {
103
- fieldProps.label = fieldType === "download" ? "download" : "run";
104
- }
105
- }
106
- }
107
- $: xxsmall = offsetWidth < 200;
108
- $: xsmall = !xxsmall && offsetWidth < 260;
109
- $: small = !xxsmall && !xsmall && offsetWidth < 320;
110
- $: triggersActive = $triggers.length > 0;
111
-
112
- function toggleTriggers(event) {
113
- event.preventDefault();
114
-
115
- showTriggers = !showTriggers;
116
- }
117
-
118
- function composeFieldProps(params) {
119
- const { triggerable, controllable, ...rest } = params;
120
-
121
- return {
122
- ...rest,
123
- key,
124
- context,
125
- };
126
- }
1
+ <script context="module">
2
+ import Select from './fields/Select.svelte';
3
+ import NumberInput from './fields/NumberInput.svelte';
4
+ import CheckboxInput from './fields/CheckboxInput.svelte';
5
+ import VectorInput from './fields/VectorInput.svelte';
6
+ import TextInput from './fields/TextInput.svelte';
7
+ import ColorInput from './fields/ColorInput.svelte';
8
+ import ListInput from './fields/ListInput.svelte';
9
+ import ButtonInput from './fields/ButtonInput.svelte';
10
+ import ImageInput from './fields/ImageInput.svelte';
11
+ import IntervalInput from './fields/IntervalInput.svelte';
12
+ import { fieldTypes, hasChanged } from '../utils/fields.utils.js';
13
+
14
+ const fields = {
15
+ [`${fieldTypes.SELECT}`]: Select,
16
+ [`${fieldTypes.NUMBER}`]: NumberInput,
17
+ [`${fieldTypes.VEC}`]: VectorInput,
18
+ [`${fieldTypes.CHECKBOX}`]: CheckboxInput,
19
+ [`${fieldTypes.TEXT}`]: TextInput,
20
+ [`${fieldTypes.LIST}`]: ListInput,
21
+ [`${fieldTypes.COLOR}`]: ColorInput,
22
+ [`${fieldTypes.BUTTON}`]: ButtonInput,
23
+ [`${fieldTypes.DOWNLOAD}`]: ButtonInput,
24
+ [`${fieldTypes.IMAGE}`]: ImageInput,
25
+ [`${fieldTypes.INTERVAL}`]: IntervalInput,
26
+ };
27
+ </script>
127
28
 
29
+ <script>
30
+ import { createEventDispatcher } from 'svelte';
31
+
32
+ import FieldSection from './FieldSection.svelte';
33
+ import FieldTriggers from './FieldTriggers.svelte';
34
+ import { download } from '../utils/file.utils.js';
35
+ import { map } from '../utils/math.utils';
36
+ import frameDebounce from '../lib/helpers/frameDebounce.js';
37
+ import { getStore } from '../stores/utils';
38
+ import { writable } from 'svelte/store';
39
+ import { inferFieldType } from '../utils/fields.utils.js';
40
+
41
+ export let key = '';
42
+ export let value = null;
43
+ export let initialValue = value;
44
+ export let context = null;
45
+ export let params = {};
46
+ export let type = null;
47
+ export let disabled = false;
48
+ export let displayName = undefined;
49
+ export let index = null;
50
+
51
+ let offsetWidth;
52
+ let showTriggers = false;
53
+
54
+ const store = getStore(
55
+ context,
56
+ { props: {} },
57
+ {
58
+ persist: context !== null,
59
+ },
60
+ );
61
+
62
+ if (!$store.props[key]) {
63
+ $store.props[key] = { triggers: [] };
64
+ }
65
+
66
+ let triggers = writable(
67
+ $store.props[key].triggers.filter(
68
+ (trigger) => trigger.inputType !== undefined,
69
+ ),
70
+ );
71
+ triggers.subscribe((all) => {
72
+ store.update((curr) => {
73
+ curr.props[key].triggers = all;
74
+
75
+ return curr;
76
+ });
77
+ });
78
+
79
+ const dispatch = createEventDispatcher();
80
+
81
+ const onTriggers = {
82
+ checkbox: () => {
83
+ value = !value;
84
+
85
+ dispatch('change', value);
86
+ },
87
+ button: (event) => {
88
+ value(event);
89
+ dispatch('click', event);
90
+ },
91
+ download: (event) => {
92
+ let [data, filename] = value(event);
93
+
94
+ download(data, filename);
95
+ },
96
+ number: (event = {}) => {
97
+ const isValueInRange = event.value >= 0 && event.value <= 1;
98
+
99
+ if (
100
+ isValueInRange &&
101
+ isFinite(params.min) &&
102
+ isFinite(params.max)
103
+ ) {
104
+ let v = map(event.value, 0, 1, params.min, params.max);
105
+ let step = params.step ? params.step : 1;
106
+ let value = Math.round(v * (1 / step)) / (1 / step);
107
+
108
+ dispatch('change', value);
109
+ }
110
+ },
111
+ };
112
+
113
+ $: fieldType = inferFieldType({ type, value, params, key });
114
+ $: fieldProps = composeFieldProps(params, disabled);
115
+ $: onTrigger = frameDebounce(onTriggers[fieldType]);
116
+ $: input = fields[fieldType];
117
+ $: triggerable =
118
+ params.triggerable !== false &&
119
+ ((fieldType === fieldTypes.NUMBER &&
120
+ isFinite(params.min) &&
121
+ isFinite(params.max)) ||
122
+ fieldType === fieldTypes.BUTTON);
123
+ $: {
124
+ const isDownload = fieldType === fieldTypes.DOWNLOAD;
125
+ const isButton = fieldType === fieldTypes.BUTTON;
126
+ if ((isDownload || isButton) && params.label == undefined) {
127
+ fieldProps.label = isDownload ? 'download' : 'run';
128
+ }
129
+ }
130
+ $: xxsmall = offsetWidth < 200;
131
+ $: xsmall = !xxsmall && offsetWidth < 260;
132
+ $: small = !xxsmall && !xsmall && offsetWidth < 320;
133
+ $: triggersActive = $triggers.length > 0;
134
+
135
+ function toggleTriggers(event) {
136
+ event.preventDefault();
137
+
138
+ showTriggers = !showTriggers;
139
+ }
140
+
141
+ function composeFieldProps(params, disabled) {
142
+ const { triggerable, controllable, ...rest } = params;
143
+
144
+ return {
145
+ ...rest,
146
+ disabled,
147
+ key,
148
+ context,
149
+ };
150
+ }
128
151
  </script>
129
152
 
130
- <div class="field"
131
- class:disabled={disabled}
132
- class:xxsmall={xxsmall}
133
- class:xsmall={xsmall}
134
- class:small={small}
135
- bind:offsetWidth={offsetWidth}
153
+ <div
154
+ class="field"
155
+ class:disabled
156
+ class:xxsmall
157
+ class:xsmall
158
+ class:small
159
+ class:changed={!disabled && hasChanged(initialValue, value)}
160
+ bind:offsetWidth
161
+ style="--index: {index};"
136
162
  >
137
- <FieldSection name={key} label={label} interactive={triggerable} on:click={toggleTriggers}>
138
- <div slot="infos" class="field__actions">
139
- {#if triggerable && !disabled }
140
- <button
141
- on:click={toggleTriggers}
142
- class="field__action field__action--triggers"
143
- class:active={triggersActive}>
144
- <svg width="16" height="16" fill="none" viewBox="0 0 24 24">
145
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4.75 8H7.25"/>
146
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M12.75 8H19.25"/>
147
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4.75 16H12.25"/>
148
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M17.75 16H19.25"/>
149
- <circle cx="10" cy="8" r="2.25" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
150
- <circle cx="15" cy="16" r="2.25" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
151
- </svg>
152
- </button>
153
- {/if}
154
- {#if (fieldType === "vec") && !disabled }
155
- <button class="field__action field__action--lock" on:click={() => params.locked = !params.locked}>
156
- {#if params.locked}
157
- <svg class="action__icon" width="16" height="16" fill="none" viewBox="0 0 24 24">
158
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M5.75 11.75C5.75 11.1977 6.19772 10.75 6.75 10.75H17.25C17.8023 10.75 18.25 11.1977 18.25 11.75V17.25C18.25 18.3546 17.3546 19.25 16.25 19.25H7.75C6.64543 19.25 5.75 18.3546 5.75 17.25V11.75Z"></path>
159
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M7.75 10.5V10.3427C7.75 8.78147 7.65607 7.04125 8.74646 5.9239C9.36829 5.2867 10.3745 4.75 12 4.75C13.6255 4.75 14.6317 5.2867 15.2535 5.9239C16.3439 7.04125 16.25 8.78147 16.25 10.3427V10.5"></path>
160
- </svg>
161
- {:else}
162
- <svg class="action__icon" width="16" height="16" fill="none" viewBox="0 0 24 24">
163
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M5.75 11.75C5.75 11.1977 6.19772 10.75 6.75 10.75H17.25C17.8023 10.75 18.25 11.1977 18.25 11.75V17.25C18.25 18.3546 17.3546 19.25 16.25 19.25H7.75C6.64543 19.25 5.75 18.3546 5.75 17.25V11.75Z"></path>
164
- <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M7.75 10.5V9.84343C7.75 8.61493 7.70093 7.29883 8.42416 6.30578C8.99862 5.51699 10.0568 4.75 12 4.75C14 4.75 15.25 6.25 15.25 6.25"></path>
165
- </svg>
166
- {/if}
167
- </button>
168
- {/if}
169
- </div>
170
- <svelte:component
171
- this={input}
172
- {value}
173
- {...fieldProps}
174
- on:change
175
- on:click={onTrigger}
176
- />
177
- <slot></slot>
178
- </FieldSection>
179
- {#if triggerable }
180
- <FieldSection visible={showTriggers} secondary>
181
- <FieldTriggers
182
- {triggers}
183
- {onTrigger}
184
- {context}
185
- triggerable={fieldType === "button"}
186
- controllable={fieldType === "number"}
187
- />
188
- </FieldSection>
189
- {/if}
163
+ <FieldSection
164
+ {key}
165
+ {displayName}
166
+ interactive={triggerable}
167
+ on:click={toggleTriggers}
168
+ {disabled}
169
+ >
170
+ <div slot="infos" class="field__actions">
171
+ {#if triggerable && !disabled}
172
+ <button
173
+ on:click={toggleTriggers}
174
+ class="field__action field__action--triggers"
175
+ class:active={triggersActive}
176
+ >
177
+ <svg width="16" height="16" fill="none" viewBox="0 0 24 24">
178
+ <path
179
+ stroke="currentColor"
180
+ stroke-linecap="round"
181
+ stroke-linejoin="round"
182
+ stroke-width="1.5"
183
+ d="M4.75 8H7.25"
184
+ />
185
+ <path
186
+ stroke="currentColor"
187
+ stroke-linecap="round"
188
+ stroke-linejoin="round"
189
+ stroke-width="1.5"
190
+ d="M12.75 8H19.25"
191
+ />
192
+ <path
193
+ stroke="currentColor"
194
+ stroke-linecap="round"
195
+ stroke-linejoin="round"
196
+ stroke-width="1.5"
197
+ d="M4.75 16H12.25"
198
+ />
199
+ <path
200
+ stroke="currentColor"
201
+ stroke-linecap="round"
202
+ stroke-linejoin="round"
203
+ stroke-width="1.5"
204
+ d="M17.75 16H19.25"
205
+ />
206
+ <circle
207
+ cx="10"
208
+ cy="8"
209
+ r="2.25"
210
+ stroke="currentColor"
211
+ stroke-linecap="round"
212
+ stroke-linejoin="round"
213
+ stroke-width="1.5"
214
+ />
215
+ <circle
216
+ cx="15"
217
+ cy="16"
218
+ r="2.25"
219
+ stroke="currentColor"
220
+ stroke-linecap="round"
221
+ stroke-linejoin="round"
222
+ stroke-width="1.5"
223
+ />
224
+ </svg>
225
+ </button>
226
+ {/if}
227
+ {#if fieldType === 'vec' && !disabled}
228
+ <button
229
+ class="field__action field__action--lock"
230
+ on:click={() => (params.locked = !params.locked)}
231
+ >
232
+ {#if params.locked}
233
+ <svg
234
+ class="action__icon"
235
+ width="16"
236
+ height="16"
237
+ fill="none"
238
+ viewBox="0 0 24 24"
239
+ >
240
+ <path
241
+ stroke="currentColor"
242
+ stroke-linecap="round"
243
+ stroke-linejoin="round"
244
+ stroke-width="1.5"
245
+ d="M5.75 11.75C5.75 11.1977 6.19772 10.75 6.75 10.75H17.25C17.8023 10.75 18.25 11.1977 18.25 11.75V17.25C18.25 18.3546 17.3546 19.25 16.25 19.25H7.75C6.64543 19.25 5.75 18.3546 5.75 17.25V11.75Z"
246
+ />
247
+ <path
248
+ stroke="currentColor"
249
+ stroke-linecap="round"
250
+ stroke-linejoin="round"
251
+ stroke-width="1.5"
252
+ d="M7.75 10.5V10.3427C7.75 8.78147 7.65607 7.04125 8.74646 5.9239C9.36829 5.2867 10.3745 4.75 12 4.75C13.6255 4.75 14.6317 5.2867 15.2535 5.9239C16.3439 7.04125 16.25 8.78147 16.25 10.3427V10.5"
253
+ />
254
+ </svg>
255
+ {:else}
256
+ <svg
257
+ class="action__icon"
258
+ width="16"
259
+ height="16"
260
+ fill="none"
261
+ viewBox="0 0 24 24"
262
+ >
263
+ <path
264
+ stroke="currentColor"
265
+ stroke-linecap="round"
266
+ stroke-linejoin="round"
267
+ stroke-width="1.5"
268
+ d="M5.75 11.75C5.75 11.1977 6.19772 10.75 6.75 10.75H17.25C17.8023 10.75 18.25 11.1977 18.25 11.75V17.25C18.25 18.3546 17.3546 19.25 16.25 19.25H7.75C6.64543 19.25 5.75 18.3546 5.75 17.25V11.75Z"
269
+ />
270
+ <path
271
+ stroke="currentColor"
272
+ stroke-linecap="round"
273
+ stroke-linejoin="round"
274
+ stroke-width="1.5"
275
+ d="M7.75 10.5V9.84343C7.75 8.61493 7.70093 7.29883 8.42416 6.30578C8.99862 5.51699 10.0568 4.75 12 4.75C14 4.75 15.25 6.25 15.25 6.25"
276
+ />
277
+ </svg>
278
+ {/if}
279
+ </button>
280
+ {/if}
281
+ </div>
282
+ <svelte:component
283
+ this={input}
284
+ {value}
285
+ {...fieldProps}
286
+ on:change
287
+ on:click={onTrigger}
288
+ />
289
+ <slot />
290
+ </FieldSection>
291
+ {#if triggerable}
292
+ <FieldSection {key} visible={showTriggers} secondary>
293
+ <FieldTriggers
294
+ {triggers}
295
+ {onTrigger}
296
+ {context}
297
+ triggerable={fieldType === 'button'}
298
+ controllable={fieldType === 'number'}
299
+ />
300
+ </FieldSection>
301
+ {/if}
190
302
  </div>
191
303
 
192
304
  <style>
193
- .field {
194
- --column-gap: 3px;
195
- --padding: 6px;
196
-
197
- width: 100%;
198
-
199
- padding: 3px 6px 3px 12px;
200
- border-bottom: 1px solid var(--color-spacing);
201
- }
202
-
203
- :global(.field__input .field) {
204
- padding-left: 0px !important;
205
- padding-right: 0px !important;
206
- }
207
-
208
- :global(.field__input .field:last-child) {
209
- border-bottom: 0px solid #323233 !important;
210
- padding-bottom: 0px !important;
211
-
212
- }
213
-
214
- .field.disabled {
215
- pointer-events: none;
216
- }
217
-
218
- .field__actions {
219
- display: flex;
220
- align-items: center;
221
- }
222
-
223
- .field__action {
224
- display: flex;
225
- align-items: center;
226
-
227
- background: transparent;
228
- transition: opacity 0.1s ease;
229
- }
230
-
231
- .field__action:hover {
232
- opacity: 1;
233
- }
234
-
235
- .field__action--triggers {
236
- --background-color: rgba(255, 255, 255, 0.5);
237
-
238
- position: relative;
239
-
240
- width: 16px;
241
- height: 16px;
242
-
243
- background-color: transparent;
244
- cursor: pointer;
245
- }
246
-
247
- .field__action--triggers:not(.active) {
248
- display: none;
249
- }
250
-
251
- .field__action {
252
- color: var(--color-text);
253
-
254
- opacity: 0.6;
255
- background-color: transparent;
256
- transition: opacity 0.1s ease;
257
- }
258
-
259
- .field__action--triggers svg {
260
- transform: rotate(90deg);
261
- }
262
-
263
- .field__action:hover {
264
- opacity: 1;
265
- }
305
+ .field {
306
+ --column-gap: 3px;
307
+ --padding: 6px;
308
+
309
+ width: 100%;
310
+
311
+ padding: 3px 6px 3px 12px;
312
+ border-bottom: 1px solid var(--color-spacing);
313
+ }
314
+
315
+ .field.changed:before {
316
+ content: '';
317
+
318
+ position: absolute;
319
+ top: 0px;
320
+ left: 0px;
321
+ bottom: 0px;
322
+ z-index: 1;
323
+
324
+ width: 4px;
325
+ /* height: 4px; */
326
+ /* border-radius: 2px; */
327
+
328
+ --stripes-offset: calc(var(--index) * 1.9px);
329
+
330
+ background: repeating-linear-gradient(
331
+ 45deg,
332
+ var(--color-active) calc(0px + var(--stripes-offset)),
333
+ var(--color-active) calc(2px + var(--stripes-offset)),
334
+ transparent calc(2px + var(--stripes-offset)),
335
+ transparent calc(4px + var(--stripes-offset))
336
+ );
337
+ }
338
+
339
+ :global(.field__input .field) {
340
+ padding-left: 0px !important;
341
+ padding-right: 0px !important;
342
+ }
343
+
344
+ :global(.field__input .field:last-child) {
345
+ border-bottom: 0px solid #323233 !important;
346
+ padding-bottom: 0px !important;
347
+ }
348
+
349
+ .field.disabled {
350
+ pointer-events: none;
351
+ }
352
+
353
+ .field__actions {
354
+ display: flex;
355
+ align-items: center;
356
+ }
357
+
358
+ .field__action {
359
+ display: flex;
360
+ align-items: center;
361
+
362
+ background: transparent;
363
+ transition: opacity 0.1s ease;
364
+ }
365
+
366
+ .field__action:hover {
367
+ opacity: 1;
368
+ }
369
+
370
+ .field__action--triggers {
371
+ --background-color: rgba(255, 255, 255, 0.5);
372
+
373
+ position: relative;
374
+
375
+ width: 16px;
376
+ height: 16px;
377
+
378
+ background-color: transparent;
379
+ cursor: pointer;
380
+ }
381
+
382
+ .field__action--triggers:not(.active) {
383
+ display: none;
384
+ }
385
+
386
+ .field__action {
387
+ color: var(--color-text);
388
+
389
+ opacity: 0.6;
390
+ background-color: transparent;
391
+ transition: opacity 0.1s ease;
392
+ }
393
+
394
+ .field__action--triggers svg {
395
+ transform: rotate(90deg);
396
+ }
397
+
398
+ .field__action:hover {
399
+ opacity: 1;
400
+ }
266
401
  </style>