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.
- package/.prettierignore +1 -2
- package/.prettierrc +23 -7
- package/README.md +28 -9
- package/bin/index.js +70 -10
- package/package.json +14 -6
- package/src/cli/build.js +125 -0
- package/src/cli/create.js +238 -0
- package/src/cli/createConfig.js +82 -0
- package/src/cli/createFragmentFile.js +70 -0
- package/src/cli/getEntries.js +85 -0
- package/src/cli/log.js +36 -24
- package/src/cli/plugins/check-dependencies.js +88 -42
- package/src/cli/plugins/hot-shader-replacement.js +408 -0
- package/src/cli/plugins/hot-sketch-reload.js +21 -25
- package/src/cli/plugins/save.js +101 -0
- package/src/cli/preview.js +55 -0
- package/src/cli/prompts.js +260 -0
- package/src/cli/run.js +131 -0
- package/src/cli/templates/blank/index.js +33 -0
- package/src/cli/templates/blank/meta.json +4 -0
- package/src/cli/templates/default/index.js +39 -0
- package/src/cli/templates/default/meta.json +5 -0
- package/src/cli/templates/fragment-gl/index.js +37 -0
- package/src/cli/templates/fragment-gl/meta.json +4 -0
- package/src/cli/templates/p5/index.js +32 -0
- package/src/cli/templates/p5/meta.json +5 -0
- package/src/cli/templates/p5-webgl/fragment.fs +14 -0
- package/src/cli/templates/p5-webgl/index.js +67 -0
- package/src/cli/templates/p5-webgl/meta.json +5 -0
- package/src/cli/templates/three-fragment/fragment.fs +10 -0
- package/src/cli/templates/three-fragment/index.js +95 -0
- package/src/cli/templates/three-fragment/meta.json +5 -0
- package/src/cli/templates/three-orthographic/index.js +55 -0
- package/src/cli/templates/three-orthographic/meta.json +5 -0
- package/src/cli/templates/three-perspective/index.js +52 -0
- package/src/cli/templates/three-perspective/meta.json +5 -0
- package/src/cli/utils.js +70 -0
- package/src/cli/ws.js +87 -78
- package/src/client/app/App.svelte +3 -3
- package/src/client/app/client.js +55 -39
- package/src/client/app/components/IconCross.svelte +18 -18
- package/src/client/app/components/Init.svelte +40 -8
- package/src/client/app/components/KeyBinding.svelte +22 -22
- package/src/client/app/helpers.js +42 -0
- package/src/client/app/hooks.js +20 -0
- package/src/client/app/inputs/Input.js +9 -9
- package/src/client/app/inputs/Keyboard.js +13 -15
- package/src/client/app/inputs/MIDI.js +14 -15
- package/src/client/app/inputs/Mouse.js +1 -1
- package/src/client/app/inputs/Webcam.js +89 -88
- package/src/client/app/lib/canvas-recorder/CanvasRecorder.js +41 -21
- package/src/client/app/lib/canvas-recorder/FrameRecorder.js +7 -6
- package/src/client/app/lib/canvas-recorder/H264Recorder.js +45 -0
- package/src/client/app/lib/canvas-recorder/MP4Recorder.js +7 -9
- package/src/client/app/lib/canvas-recorder/WebMRecorder.js +3 -4
- package/src/client/app/lib/canvas-recorder/mp4.js +1649 -15
- package/src/client/app/lib/canvas-recorder/utils.js +33 -17
- package/src/client/app/lib/gl/Geometry.js +11 -8
- package/src/client/app/lib/gl/Program.js +38 -19
- package/src/client/app/lib/gl/Renderer.js +163 -156
- package/src/client/app/lib/gl/Texture.js +113 -85
- package/src/client/app/lib/gl/index.js +12 -12
- package/src/client/app/lib/gl/utils.js +1 -3
- package/src/client/app/lib/helpers/frameDebounce.js +30 -30
- package/src/client/app/lib/loader/index.js +10 -10
- package/src/client/app/lib/loader/loadImage.js +15 -15
- package/src/client/app/lib/loader/loadScript.js +1 -1
- package/src/client/app/lib/paper-sizes.js +75 -76
- package/src/client/app/lib/presets.js +25 -5
- package/src/client/app/lib/tempo/Analyser.js +18 -17
- package/src/client/app/lib/tempo/Range.js +15 -12
- package/src/client/app/lib/tempo/index.js +34 -27
- package/src/client/app/modules/AudioAnalyser/Range.svelte +69 -72
- package/src/client/app/modules/AudioAnalyser/Spectrum.svelte +20 -19
- package/src/client/app/modules/AudioAnalyser.svelte +52 -35
- package/src/client/app/modules/Console/ConsoleLine.svelte +193 -172
- package/src/client/app/modules/Console.svelte +76 -74
- package/src/client/app/modules/Exports.svelte +62 -43
- package/src/client/app/modules/MidiPanel.svelte +100 -101
- package/src/client/app/modules/Monitor.svelte +57 -57
- package/src/client/app/modules/Params.svelte +128 -103
- package/src/client/app/renderers/2DRenderer.js +3 -3
- package/src/client/app/renderers/FragmentRenderer.js +30 -23
- package/src/client/app/renderers/P5GLRenderer.js +144 -0
- package/src/client/app/renderers/P5Renderer.js +10 -7
- package/src/client/app/renderers/THREERenderer.js +136 -94
- package/src/client/app/stores/audioAnalysis.js +3 -4
- package/src/client/app/stores/console.js +9 -10
- package/src/client/app/stores/errors.js +1 -1
- package/src/client/app/stores/exports.js +36 -20
- package/src/client/app/stores/index.js +2 -2
- package/src/client/app/stores/layout.js +143 -138
- package/src/client/app/stores/multisampling.js +4 -4
- package/src/client/app/stores/props.js +76 -13
- package/src/client/app/stores/renderers.js +26 -15
- package/src/client/app/stores/rendering.js +108 -89
- package/src/client/app/stores/sketches.js +7 -9
- package/src/client/app/stores/time.js +18 -18
- package/src/client/app/stores/utils.js +95 -38
- package/src/client/app/transitions/fade.js +3 -3
- package/src/client/app/transitions/index.js +6 -7
- package/src/client/app/transitions/splitX.js +2 -2
- package/src/client/app/transitions/splitY.js +2 -2
- package/src/client/app/triggers/Keyboard.js +88 -79
- package/src/client/app/triggers/MIDI.js +110 -84
- package/src/client/app/triggers/Mouse.js +73 -65
- package/src/client/app/triggers/Trigger.js +59 -58
- package/src/client/app/triggers/index.js +7 -7
- package/src/client/app/triggers/shared.js +5 -5
- package/src/client/app/ui/Build.svelte +70 -71
- package/src/client/app/ui/ErrorOverlay.svelte +118 -104
- package/src/client/app/ui/Field.svelte +393 -258
- package/src/client/app/ui/FieldGroup.svelte +106 -94
- package/src/client/app/ui/FieldSection.svelte +127 -116
- package/src/client/app/ui/FieldSpace.svelte +29 -30
- package/src/client/app/ui/FieldTrigger.svelte +256 -244
- package/src/client/app/ui/FieldTriggers.svelte +46 -46
- package/src/client/app/ui/FloatingParams.svelte +29 -30
- package/src/client/app/ui/Layout.svelte +31 -32
- package/src/client/app/ui/LayoutColumn.svelte +4 -4
- package/src/client/app/ui/LayoutComponent.svelte +239 -225
- package/src/client/app/ui/LayoutResizer.svelte +195 -176
- package/src/client/app/ui/LayoutRoot.svelte +6 -6
- package/src/client/app/ui/LayoutRow.svelte +4 -4
- package/src/client/app/ui/LayoutToolbar.svelte +191 -194
- package/src/client/app/ui/Module.svelte +134 -135
- package/src/client/app/ui/ModuleHeaderAction.svelte +81 -78
- package/src/client/app/ui/ModuleHeaderButton.svelte +12 -12
- package/src/client/app/ui/ModuleHeaderSelect.svelte +47 -37
- package/src/client/app/ui/ModuleRenderer.svelte +26 -27
- package/src/client/app/ui/OutputRenderer.svelte +112 -105
- package/src/client/app/ui/ParamsMultisampling.svelte +96 -95
- package/src/client/app/ui/ParamsOutput.svelte +130 -113
- package/src/client/app/ui/Preview.svelte +7 -8
- package/src/client/app/ui/SelectChevrons.svelte +27 -15
- package/src/client/app/ui/SketchRenderer.svelte +780 -667
- package/src/client/app/ui/SketchSelect.svelte +50 -44
- package/src/client/app/ui/fields/ButtonInput.svelte +61 -48
- package/src/client/app/ui/fields/CheckboxInput.svelte +67 -61
- package/src/client/app/ui/fields/ColorInput.svelte +294 -238
- package/src/client/app/ui/fields/FieldInputRow.svelte +8 -8
- package/src/client/app/ui/fields/ImageInput.svelte +123 -121
- package/src/client/app/ui/fields/Input.svelte +100 -111
- package/src/client/app/ui/fields/IntervalInput.svelte +268 -0
- package/src/client/app/ui/fields/ListInput.svelte +96 -96
- package/src/client/app/ui/fields/NumberInput.svelte +120 -116
- package/src/client/app/ui/fields/ProgressInput.svelte +99 -73
- package/src/client/app/ui/fields/Select.svelte +137 -124
- package/src/client/app/ui/fields/TextInput.svelte +10 -11
- package/src/client/app/ui/fields/VectorInput.svelte +86 -82
- package/src/client/app/utils/canvas.utils.js +189 -208
- package/src/client/app/utils/color.utils.js +138 -101
- package/src/client/app/utils/fields.utils.js +131 -0
- package/src/client/app/utils/file.utils.js +209 -37
- package/src/client/app/utils/glsl.utils.js +2 -2
- package/src/client/app/utils/glslErrors.js +49 -31
- package/src/client/app/utils/index.js +32 -29
- package/src/client/app/utils/math.utils.js +14 -10
- package/src/client/index.html +16 -16
- package/src/client/main.js +4 -4
- package/src/client/public/css/global.css +26 -16
- package/src/cli/db.js +0 -17
- package/src/cli/index.js +0 -198
- package/src/cli/plugins/db.js +0 -12
- package/src/cli/plugins/hot-shader-reload.js +0 -86
- package/src/cli/plugins/screenshot.js +0 -46
- package/src/cli/server.js +0 -153
- package/src/cli/templates/2d.js +0 -15
- package/src/cli/templates/blank.js +0 -13
- package/src/cli/templates/fragment.js +0 -18
- package/src/cli/templates/index.js +0 -27
- package/src/cli/templates/p5.js +0 -13
- package/src/cli/templates/three-fragment.js +0 -53
- package/src/cli/templates/three-orthographic.js +0 -23
- package/src/cli/templates/three-perspective.js +0 -20
- package/src/client/app/lib/canvas-recorder/FFMPEGRecorder.js +0 -56
- package/src/client/app/utils/props.utils.js +0 -51
- package/src/client/public/fonts/Inter-Bold.woff2 +0 -0
- package/src/client/public/fonts/Inter-Italic.woff2 +0 -0
- package/src/client/public/fonts/Inter-Regular.woff2 +0 -0
- package/src/client/public/fonts/Inter-SemiBold.woff2 +0 -0
- package/src/client/public/js/ffmpeg.min.js +0 -2
- package/src/client/public/js/ffmpeg.min.js.map +0 -1
- /package/src/cli/templates/{fragment.fs → fragment-gl/fragment.fs} +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
export const FORMATS = {
|
|
2
|
-
HEX_STRING:
|
|
3
|
-
RGB_STRING:
|
|
4
|
-
RGBA_STRING:
|
|
5
|
-
HSL_STRING:
|
|
6
|
-
HSLA_STRING:
|
|
7
|
-
RGB_OBJECT:
|
|
8
|
-
RGBA_OBJECT:
|
|
9
|
-
VEC3_STRING:
|
|
10
|
-
VEC4_STRING:
|
|
11
|
-
VEC3_ARRAY:
|
|
12
|
-
VEC4_ARRAY:
|
|
13
|
-
THREE:
|
|
14
|
-
CSS_COLOR:
|
|
2
|
+
HEX_STRING: 'hex-string',
|
|
3
|
+
RGB_STRING: 'rgb-string',
|
|
4
|
+
RGBA_STRING: 'rgba-string',
|
|
5
|
+
HSL_STRING: 'hsl-string',
|
|
6
|
+
HSLA_STRING: 'hsla-string',
|
|
7
|
+
RGB_OBJECT: 'rgb-object',
|
|
8
|
+
RGBA_OBJECT: 'rgba-object',
|
|
9
|
+
VEC3_STRING: 'vec3-string',
|
|
10
|
+
VEC4_STRING: 'vec4-string',
|
|
11
|
+
VEC3_ARRAY: 'vec3-array',
|
|
12
|
+
VEC4_ARRAY: 'vec4-array',
|
|
13
|
+
THREE: 'three',
|
|
14
|
+
CSS_COLOR: 'css-color',
|
|
15
15
|
};
|
|
16
16
|
|
|
17
17
|
export function toHex(color, format = getColorFormat(color)) {
|
|
@@ -21,11 +21,16 @@ export function toHex(color, format = getColorFormat(color)) {
|
|
|
21
21
|
|
|
22
22
|
if (format === FORMATS.THREE) return threeToHex(color);
|
|
23
23
|
if (format === FORMATS.HEX_STRING) return color;
|
|
24
|
-
if (format === FORMATS.HSL_STRING || format === FORMATS.HSLA_STRING)
|
|
25
|
-
|
|
26
|
-
if (format === FORMATS.
|
|
27
|
-
|
|
28
|
-
if (format === FORMATS.
|
|
24
|
+
if (format === FORMATS.HSL_STRING || format === FORMATS.HSLA_STRING)
|
|
25
|
+
return hslToHex(color);
|
|
26
|
+
if (format === FORMATS.RGB_STRING || format === FORMATS.RGBA_STRING)
|
|
27
|
+
return stringToHex(color);
|
|
28
|
+
if (format === FORMATS.RGB_OBJECT || format === FORMATS.RGBA_OBJECT)
|
|
29
|
+
return componentsToHex([color.r, color.g, color.b, color.a]);
|
|
30
|
+
if (format === FORMATS.VEC3_STRING || format === FORMATS.VEC4_STRING)
|
|
31
|
+
return vecStringToHex(color);
|
|
32
|
+
if (format === FORMATS.VEC3_ARRAY || format === FORMATS.VEC4_ARRAY)
|
|
33
|
+
return vecArrayToHex(color);
|
|
29
34
|
if (format === FORMATS.CSS_COLOR) return nameToHex(color);
|
|
30
35
|
}
|
|
31
36
|
|
|
@@ -36,10 +41,14 @@ export function toComponents(color, format = getColorFormat(color)) {
|
|
|
36
41
|
|
|
37
42
|
if (format === FORMATS.THREE) return [color.r, color.g, color.b, 1];
|
|
38
43
|
if (format === FORMATS.HEX_STRING) return hexToComponents(color);
|
|
39
|
-
if (format === FORMATS.HSL_STRING || format === FORMATS.HSLA_STRING)
|
|
40
|
-
|
|
41
|
-
if (format === FORMATS.
|
|
42
|
-
|
|
44
|
+
if (format === FORMATS.HSL_STRING || format === FORMATS.HSLA_STRING)
|
|
45
|
+
return hslToComponents(color);
|
|
46
|
+
if (format === FORMATS.RGB_STRING || format === FORMATS.RGBA_STRING)
|
|
47
|
+
return stringToComponents(color);
|
|
48
|
+
if (format === FORMATS.RGB_OBJECT || format === FORMATS.RGBA_OBJECT)
|
|
49
|
+
return [color.r, color.g, color.b, isFinite(color.a) ? color.a : 1];
|
|
50
|
+
if (format === FORMATS.VEC3_STRING || format === FORMATS.VEC4_STRING)
|
|
51
|
+
return vecStringToComponents(color);
|
|
43
52
|
if (format === FORMATS.CSS_COLOR) return nameToComponents(color);
|
|
44
53
|
}
|
|
45
54
|
|
|
@@ -57,20 +66,30 @@ export function toString(color, format = getColorFormat(color)) {
|
|
|
57
66
|
format === FORMATS.VEC3_STRING ||
|
|
58
67
|
format === FORMATS.VEC4_STRING ||
|
|
59
68
|
format === FORMATS.CSS_COLOR
|
|
60
|
-
)
|
|
61
|
-
|
|
62
|
-
if (format === FORMATS.
|
|
69
|
+
)
|
|
70
|
+
return color;
|
|
71
|
+
if (format === FORMATS.VEC3_ARRAY)
|
|
72
|
+
return componentsToRGBString(vecArrayToComponents(color));
|
|
73
|
+
if (format === FORMATS.VEC4_ARRAY)
|
|
74
|
+
return componentsToRGBAString(vecArrayToComponents(color));
|
|
63
75
|
if (format === FORMATS.THREE) return threeToHex(color);
|
|
64
|
-
if (format === FORMATS.RGB_OBJECT)
|
|
65
|
-
|
|
76
|
+
if (format === FORMATS.RGB_OBJECT)
|
|
77
|
+
return componentsToRGBString([color.r, color.g, color.b]);
|
|
78
|
+
if (format === FORMATS.RGBA_OBJECT)
|
|
79
|
+
return componentsToRGBAString([
|
|
80
|
+
color.r,
|
|
81
|
+
color.g,
|
|
82
|
+
color.b,
|
|
83
|
+
color.a ? color.a : 1,
|
|
84
|
+
]);
|
|
66
85
|
}
|
|
67
86
|
|
|
68
87
|
/**
|
|
69
|
-
*
|
|
70
|
-
* @param {string} colorName
|
|
88
|
+
*
|
|
89
|
+
* @param {string} colorName
|
|
71
90
|
*/
|
|
72
|
-
export function nameToComponents(colorName, element =
|
|
73
|
-
if (colorName.toLowerCase() ===
|
|
91
|
+
export function nameToComponents(colorName, element = 'temp') {
|
|
92
|
+
if (colorName.toLowerCase() === 'transparent') return [0, 0, 0, 0];
|
|
74
93
|
|
|
75
94
|
let temp = document.createElement(element);
|
|
76
95
|
document.body.appendChild(temp);
|
|
@@ -102,19 +121,22 @@ export function nameToHex(color) {
|
|
|
102
121
|
}
|
|
103
122
|
|
|
104
123
|
/**
|
|
105
|
-
*
|
|
124
|
+
*
|
|
106
125
|
* @param {string} value
|
|
107
126
|
* @return {array}
|
|
108
127
|
*/
|
|
109
128
|
export function stringToComponents(color) {
|
|
110
|
-
const match = color.match(
|
|
129
|
+
const match = color.match(
|
|
130
|
+
/rgba?\((\d{1,3}), ?(\d{1,3}), ?(\d{1,3})\)?(?:, ?(\d*(?:\.?\d*?))\))?/,
|
|
131
|
+
);
|
|
111
132
|
|
|
112
133
|
if (match) {
|
|
113
134
|
return [
|
|
114
135
|
parseInt(match[1]) / 255,
|
|
115
136
|
parseInt(match[2]) / 255,
|
|
116
137
|
parseInt(match[3]) / 255,
|
|
117
|
-
match[4] ? Number(match[4]) : 1
|
|
138
|
+
match[4] ? Number(match[4]) : 1,
|
|
139
|
+
];
|
|
118
140
|
}
|
|
119
141
|
|
|
120
142
|
return [];
|
|
@@ -125,14 +147,17 @@ export function stringToHex(color) {
|
|
|
125
147
|
}
|
|
126
148
|
|
|
127
149
|
export function vecStringToComponents(color) {
|
|
128
|
-
const match = color.match(
|
|
150
|
+
const match = color.match(
|
|
151
|
+
/vec[3-4]?\((\d*(?:\.\d*?)), ?(\d*(?:\.\d*?)), ?(\d*(?:\.\d*))?(?:, ?(\d*(?:\.?\d*?))\))?/,
|
|
152
|
+
);
|
|
129
153
|
|
|
130
154
|
if (match) {
|
|
131
155
|
return [
|
|
132
156
|
Math.min(1, Math.max(Number(match[1]), 0)),
|
|
133
157
|
Math.min(1, Math.max(Number(match[2]), 0)),
|
|
134
158
|
Math.min(1, Math.max(Number(match[3]), 0)),
|
|
135
|
-
match[4] ? Math.min(1, Math.max(Number(match[4]), 0)) : 1
|
|
159
|
+
match[4] ? Math.min(1, Math.max(Number(match[4]), 0)) : 1,
|
|
160
|
+
];
|
|
136
161
|
}
|
|
137
162
|
|
|
138
163
|
console.error(`color.vecStringToComponents :: cannot parse color`, color);
|
|
@@ -143,12 +168,7 @@ export function vecStringToComponents(color) {
|
|
|
143
168
|
export function vecArrayToComponents(color) {
|
|
144
169
|
if (color.every((c) => isFinite(c))) {
|
|
145
170
|
const [r, g, b, a = 1] = color;
|
|
146
|
-
return [
|
|
147
|
-
r,
|
|
148
|
-
g,
|
|
149
|
-
b,
|
|
150
|
-
a
|
|
151
|
-
];
|
|
171
|
+
return [r, g, b, a];
|
|
152
172
|
}
|
|
153
173
|
|
|
154
174
|
console.error(`color.vecArrayToComponents :: cannot parse color`, color);
|
|
@@ -165,12 +185,12 @@ export function vecArrayToHex(color) {
|
|
|
165
185
|
}
|
|
166
186
|
|
|
167
187
|
// https://stackoverflow.com/questions/39118528/rgb-to-hsl-conversion
|
|
168
|
-
export function rgbTohsl(r,g,b) {
|
|
169
|
-
|
|
170
|
-
}
|
|
188
|
+
export function rgbTohsl(r, g, b) {}
|
|
171
189
|
|
|
172
190
|
export function hslToHSLComponents(color) {
|
|
173
|
-
const match = color.match(
|
|
191
|
+
const match = color.match(
|
|
192
|
+
/hsla?\((\d{1,3}),?[\s]?(\d{1,3})\%,?[\s]?(\d{1,3})\%\)?(?:,?[\s]?(\d*(?:\.?\d*?))\))?/,
|
|
193
|
+
);
|
|
174
194
|
|
|
175
195
|
if (match) {
|
|
176
196
|
const h = Math.min(360, Math.max(Number(match[1]), 0));
|
|
@@ -198,7 +218,7 @@ export function hslToComponents(color) {
|
|
|
198
218
|
l /= 100;
|
|
199
219
|
|
|
200
220
|
function f(n) {
|
|
201
|
-
let k = (n + h/30) % 12;
|
|
221
|
+
let k = (n + h / 30) % 12;
|
|
202
222
|
let a = s * Math.min(l, 1 - l);
|
|
203
223
|
return l - a * Math.max(-1, Math.min(k - 3, 9 - k, 1));
|
|
204
224
|
}
|
|
@@ -208,10 +228,10 @@ export function hslToComponents(color) {
|
|
|
208
228
|
|
|
209
229
|
export function hslToHex(color) {
|
|
210
230
|
return componentsToHex(hslToComponents(color));
|
|
211
|
-
}
|
|
231
|
+
}
|
|
212
232
|
|
|
213
233
|
export function hexToComponents(color) {
|
|
214
|
-
if (color.length < 7){
|
|
234
|
+
if (color.length < 7) {
|
|
215
235
|
const R = color[1];
|
|
216
236
|
const G = color[2];
|
|
217
237
|
const B = color[3];
|
|
@@ -223,20 +243,20 @@ export function hexToComponents(color) {
|
|
|
223
243
|
} else {
|
|
224
244
|
color = `#${R}${R}${G}${G}${B}${B}`;
|
|
225
245
|
}
|
|
226
|
-
|
|
246
|
+
}
|
|
227
247
|
|
|
228
|
-
|
|
248
|
+
return [
|
|
229
249
|
parseInt(color.substr(1, 2), 16) / 255,
|
|
230
|
-
|
|
250
|
+
parseInt(color.substr(3, 2), 16) / 255,
|
|
231
251
|
parseInt(color.substr(5, 2), 16) / 255,
|
|
232
|
-
color.length > 7 ? parseInt(color.substr(7, 2), 16)/255 : 1
|
|
252
|
+
color.length > 7 ? parseInt(color.substr(7, 2), 16) / 255 : 1,
|
|
233
253
|
];
|
|
234
254
|
}
|
|
235
255
|
|
|
236
256
|
/**
|
|
237
|
-
* Convert a hexadecimal string to
|
|
238
|
-
* @param {string} color
|
|
239
|
-
* @returns
|
|
257
|
+
* Convert a hexadecimal string to
|
|
258
|
+
* @param {string} color
|
|
259
|
+
* @returns
|
|
240
260
|
*/
|
|
241
261
|
export function hexToVec3String(color) {
|
|
242
262
|
return componentsToVec3String(hexToComponents(color));
|
|
@@ -263,7 +283,7 @@ export function toVec4String(color) {
|
|
|
263
283
|
}
|
|
264
284
|
|
|
265
285
|
export function componentsToVec3String(components = []) {
|
|
266
|
-
const [
|
|
286
|
+
const [r = 0, g = 0, b = 0] = components;
|
|
267
287
|
|
|
268
288
|
let rn = `${Math.round(r * 1000) / 1000}`;
|
|
269
289
|
let gn = `${Math.round(g * 1000) / 1000}`;
|
|
@@ -285,7 +305,7 @@ export function componentsToVec3String(components = []) {
|
|
|
285
305
|
}
|
|
286
306
|
|
|
287
307
|
export function componentsToVec4String(components = []) {
|
|
288
|
-
const [
|
|
308
|
+
const [r = 0, g = 0, b = 0, a = 1] = components;
|
|
289
309
|
|
|
290
310
|
let rn = `${Math.round(r * 1000) / 1000}`;
|
|
291
311
|
let gn = `${Math.round(g * 1000) / 1000}`;
|
|
@@ -330,13 +350,13 @@ export function hexToRGBAString(color) {
|
|
|
330
350
|
}
|
|
331
351
|
|
|
332
352
|
export function componentsToRGBString(components) {
|
|
333
|
-
const [
|
|
353
|
+
const [r, g, b] = components;
|
|
334
354
|
|
|
335
355
|
return `rgb(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(b * 255)})`;
|
|
336
356
|
}
|
|
337
357
|
|
|
338
358
|
export function componentsToRGBAString(components = []) {
|
|
339
|
-
const [
|
|
359
|
+
const [r = 0, g = 0, b = 0, a = 1] = components;
|
|
340
360
|
|
|
341
361
|
return `rgba(${Math.round(r * 255)}, ${Math.round(g * 255)}, ${Math.round(b * 255)}, ${a})`;
|
|
342
362
|
}
|
|
@@ -345,16 +365,21 @@ export function componentsToHSLComponents(components = []) {
|
|
|
345
365
|
let [r, g, b] = components;
|
|
346
366
|
let max = Math.max(...components);
|
|
347
367
|
let min = Math.min(...components);
|
|
348
|
-
let [h, s, l] = [NaN, 0, (min + max)/2];
|
|
368
|
+
let [h, s, l] = [NaN, 0, (min + max) / 2];
|
|
349
369
|
let d = max - min;
|
|
350
370
|
|
|
351
371
|
if (d !== 0) {
|
|
352
|
-
s =
|
|
372
|
+
s = l === 0 || l === 1 ? 0 : (max - l) / Math.min(l, 1 - l);
|
|
353
373
|
|
|
354
374
|
switch (max) {
|
|
355
|
-
case r:
|
|
356
|
-
|
|
357
|
-
|
|
375
|
+
case r:
|
|
376
|
+
h = (g - b) / d + (g < b ? 6 : 0);
|
|
377
|
+
break;
|
|
378
|
+
case g:
|
|
379
|
+
h = (b - r) / d + 2;
|
|
380
|
+
break;
|
|
381
|
+
case b:
|
|
382
|
+
h = (r - g) / d + 4;
|
|
358
383
|
}
|
|
359
384
|
|
|
360
385
|
h = h * 60;
|
|
@@ -368,25 +393,25 @@ export function componentsToHSLComponents(components = []) {
|
|
|
368
393
|
}
|
|
369
394
|
|
|
370
395
|
export function hslToHSLString(components) {
|
|
371
|
-
const [
|
|
396
|
+
const [h = 0, s = 0, l = 0] = components;
|
|
372
397
|
|
|
373
398
|
return `hsl(${Math.round(h)}, ${Math.round(s)}%, ${Math.round(l)}%)`;
|
|
374
399
|
}
|
|
375
400
|
|
|
376
401
|
export function hslaToHSLAString(components) {
|
|
377
|
-
const [
|
|
402
|
+
const [h = 0, s = 0, l = 0, a = 1] = components;
|
|
378
403
|
|
|
379
404
|
return `hsla(${Math.round(h)}, ${Math.round(s)}%, ${Math.round(l)}%, ${a})`;
|
|
380
405
|
}
|
|
381
406
|
|
|
382
407
|
export function componentsToHSLString(components = []) {
|
|
383
|
-
const [
|
|
408
|
+
const [r = 0, g = 0, b = 0, a = 1] = components;
|
|
384
409
|
return hslToHSLString(componentsToHSLComponents([r, g, b]));
|
|
385
410
|
}
|
|
386
411
|
|
|
387
412
|
export function componentsToHSLAString(components = []) {
|
|
388
|
-
const [
|
|
389
|
-
const [
|
|
413
|
+
const [r = 0, g = 0, b = 0, a = 1] = components;
|
|
414
|
+
const [h, s, l] = componentsToHSLComponents([r, g, b]);
|
|
390
415
|
return hslaToHSLAString([h, s, l, a]);
|
|
391
416
|
}
|
|
392
417
|
|
|
@@ -395,76 +420,87 @@ export function componentToHex(c) {
|
|
|
395
420
|
}
|
|
396
421
|
|
|
397
422
|
export function componentsToHex(components = []) {
|
|
398
|
-
const [
|
|
423
|
+
const [r = 0, g = 0, b = 0] = components;
|
|
399
424
|
|
|
400
425
|
let hex = [r, g, b]
|
|
401
426
|
.map((c) => Math.round(c * 255))
|
|
402
|
-
.map(c => {
|
|
403
|
-
return c.toString(16).padStart(2,
|
|
404
|
-
})
|
|
427
|
+
.map((c) => {
|
|
428
|
+
return c.toString(16).padStart(2, '0');
|
|
429
|
+
})
|
|
430
|
+
.join('');
|
|
405
431
|
|
|
406
432
|
return `#${hex}`;
|
|
407
433
|
}
|
|
408
434
|
|
|
409
|
-
export function isHexString(value, isString = typeof value ===
|
|
435
|
+
export function isHexString(value, isString = typeof value === 'string') {
|
|
410
436
|
return isString && /^#([a-f0-9]{3,4}){1,2}$/i.test(value);
|
|
411
437
|
}
|
|
412
438
|
|
|
413
|
-
export function isRGBAString(value, isString = typeof value ===
|
|
414
|
-
return
|
|
439
|
+
export function isRGBAString(value, isString = typeof value === 'string') {
|
|
440
|
+
return (
|
|
441
|
+
isString &&
|
|
442
|
+
/rgba\((\d{1,3}),[\s]*(\d{1,3}),[\s]*(\d{1,3})\)?(?:,[\s]*(\d*(?:\.?\d*?))\))?/.test(
|
|
443
|
+
value,
|
|
444
|
+
)
|
|
445
|
+
);
|
|
415
446
|
}
|
|
416
447
|
|
|
417
|
-
export function isRGBString(value, isString = typeof value ===
|
|
418
|
-
return
|
|
448
|
+
export function isRGBString(value, isString = typeof value === 'string') {
|
|
449
|
+
return (
|
|
450
|
+
isString && /rgb\((\d{1,3}),[\s]*(\d{1,3}),[\s]*(\d{1,3})\)/.test(value)
|
|
451
|
+
);
|
|
419
452
|
}
|
|
420
453
|
|
|
421
|
-
export function isHSLAString(value, isString = typeof value ===
|
|
422
|
-
return isString && value.includes(
|
|
454
|
+
export function isHSLAString(value, isString = typeof value === 'string') {
|
|
455
|
+
return isString && value.includes('hsla');
|
|
423
456
|
}
|
|
424
457
|
|
|
425
|
-
export function isHSLString(value, isString = typeof value ===
|
|
426
|
-
return isString && value.includes(
|
|
458
|
+
export function isHSLString(value, isString = typeof value === 'string') {
|
|
459
|
+
return isString && value.includes('hsl');
|
|
427
460
|
}
|
|
428
461
|
|
|
429
|
-
export function isVec3String(value, isString = typeof value ===
|
|
430
|
-
return isString && value.includes(
|
|
462
|
+
export function isVec3String(value, isString = typeof value === 'string') {
|
|
463
|
+
return isString && value.includes('vec3(');
|
|
431
464
|
}
|
|
432
465
|
|
|
433
|
-
export function isVec4String(value, isString = typeof value ===
|
|
434
|
-
return isString && value.includes(
|
|
466
|
+
export function isVec4String(value, isString = typeof value === 'string') {
|
|
467
|
+
return isString && value.includes('vec4(');
|
|
435
468
|
}
|
|
436
469
|
|
|
437
470
|
export function isRGBAObject(value) {
|
|
438
|
-
if (typeof value ===
|
|
471
|
+
if (typeof value === 'object') {
|
|
439
472
|
const keys = Object.keys(value);
|
|
440
473
|
|
|
441
|
-
return
|
|
474
|
+
return (
|
|
475
|
+
keys.length === 4 &&
|
|
442
476
|
keys.includes('r') &&
|
|
443
477
|
keys.includes('g') &&
|
|
444
478
|
keys.includes('b') &&
|
|
445
|
-
keys.includes('a')
|
|
479
|
+
keys.includes('a')
|
|
480
|
+
);
|
|
446
481
|
}
|
|
447
482
|
|
|
448
483
|
return false;
|
|
449
484
|
}
|
|
450
485
|
|
|
451
486
|
export function isRGBObject(value) {
|
|
452
|
-
if (typeof value ===
|
|
487
|
+
if (typeof value === 'object') {
|
|
453
488
|
const keys = Object.keys(value);
|
|
454
489
|
|
|
455
|
-
return
|
|
490
|
+
return (
|
|
491
|
+
keys.length === 3 &&
|
|
456
492
|
keys.includes('r') &&
|
|
457
493
|
keys.includes('g') &&
|
|
458
|
-
keys.includes('b')
|
|
494
|
+
keys.includes('b')
|
|
495
|
+
);
|
|
459
496
|
}
|
|
460
497
|
|
|
461
498
|
return false;
|
|
462
499
|
}
|
|
463
500
|
|
|
464
|
-
|
|
465
501
|
export function isVec3Array(value) {
|
|
466
502
|
if (Array.isArray(value)) {
|
|
467
|
-
return value.length == 3 && value.every(c => c >= 0 && c <= 1);
|
|
503
|
+
return value.length == 3 && value.every((c) => c >= 0 && c <= 1);
|
|
468
504
|
}
|
|
469
505
|
|
|
470
506
|
return false;
|
|
@@ -472,13 +508,13 @@ export function isVec3Array(value) {
|
|
|
472
508
|
|
|
473
509
|
export function isVec4Array(value) {
|
|
474
510
|
if (Array.isArray(value)) {
|
|
475
|
-
return value.length == 4 && value.every(c => c >= 0 && c <= 1);
|
|
511
|
+
return value.length == 4 && value.every((c) => c >= 0 && c <= 1);
|
|
476
512
|
}
|
|
477
513
|
|
|
478
514
|
return false;
|
|
479
515
|
}
|
|
480
516
|
|
|
481
|
-
export function isCSSColor(value, isString = typeof value ===
|
|
517
|
+
export function isCSSColor(value, isString = typeof value === 'string') {
|
|
482
518
|
const components = isString && nameToComponents(value);
|
|
483
519
|
|
|
484
520
|
return components && components.length > 0;
|
|
@@ -490,14 +526,16 @@ export function isTHREE(value) {
|
|
|
490
526
|
|
|
491
527
|
export function threeToHex(value) {
|
|
492
528
|
if (!isTHREE(value)) {
|
|
493
|
-
console.error(
|
|
529
|
+
console.error(
|
|
530
|
+
`color.threeToHex() : value is not an instance of THREE.Color`,
|
|
531
|
+
);
|
|
494
532
|
}
|
|
495
533
|
|
|
496
534
|
return `#${value.getHexString()}`;
|
|
497
535
|
}
|
|
498
536
|
|
|
499
537
|
export function isColor(value) {
|
|
500
|
-
let isString = typeof value ===
|
|
538
|
+
let isString = typeof value === 'string';
|
|
501
539
|
|
|
502
540
|
if (isTHREE(value)) return true;
|
|
503
541
|
if (isHexString(value, isString)) return true;
|
|
@@ -512,7 +550,6 @@ export function isColor(value) {
|
|
|
512
550
|
return false;
|
|
513
551
|
}
|
|
514
552
|
|
|
515
|
-
|
|
516
553
|
export function getColorFormat(value) {
|
|
517
554
|
if (isTHREE(value)) return FORMATS.THREE;
|
|
518
555
|
if (isHexString(value)) return FORMATS.HEX_STRING;
|
|
@@ -527,4 +564,4 @@ export function getColorFormat(value) {
|
|
|
527
564
|
if (isHSLAString(value)) return FORMATS.HSLA_STRING;
|
|
528
565
|
if (isHSLString(value)) return FORMATS.HSL_STRING;
|
|
529
566
|
if (isCSSColor(value)) return FORMATS.CSS_COLOR;
|
|
530
|
-
}
|
|
567
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { isColor } from './color.utils';
|
|
2
|
+
|
|
3
|
+
export const fieldTypes = {
|
|
4
|
+
SELECT: 'select',
|
|
5
|
+
NUMBER: 'number',
|
|
6
|
+
VEC: 'vec',
|
|
7
|
+
CHECKBOX: 'checkbox',
|
|
8
|
+
TEXT: 'text',
|
|
9
|
+
LIST: 'list',
|
|
10
|
+
COLOR: 'color',
|
|
11
|
+
BUTTON: 'button',
|
|
12
|
+
DOWNLOAD: 'download',
|
|
13
|
+
IMAGE: 'image',
|
|
14
|
+
INTERVAL: 'interval',
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
/** @type string[] */
|
|
18
|
+
const types = Object.values(fieldTypes);
|
|
19
|
+
|
|
20
|
+
function isImageURL(url) {
|
|
21
|
+
return url.match(/\.(jpeg|jpg|gif|png|webp)$/) !== null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function isImage(value) {
|
|
25
|
+
return typeof value === HTMLImageElement || isImageURL(value);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function inferFieldType({ type, value, params, key }) {
|
|
29
|
+
if (type) {
|
|
30
|
+
if (types.includes(type)) {
|
|
31
|
+
return type;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.warn(`Field: type ${type} is invalid for ${key}`);
|
|
35
|
+
} else if (params.options && Array.isArray(params.options)) {
|
|
36
|
+
return 'select';
|
|
37
|
+
} else {
|
|
38
|
+
if (value === undefined || value === null) {
|
|
39
|
+
console.warn(`Field: value ${value} for ${key}`);
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const isArray = Array.isArray(value);
|
|
44
|
+
const isObject = !isArray && typeof value === 'object';
|
|
45
|
+
const values = isObject ? Object.values(value) : value;
|
|
46
|
+
|
|
47
|
+
if (
|
|
48
|
+
isArray &&
|
|
49
|
+
value.length === 2 &&
|
|
50
|
+
typeof params.min === 'number' &&
|
|
51
|
+
typeof params.max === 'number'
|
|
52
|
+
) {
|
|
53
|
+
return fieldTypes.INTERVAL;
|
|
54
|
+
} else if (isColor(value)) {
|
|
55
|
+
return fieldTypes.COLOR;
|
|
56
|
+
} else if (typeof value === 'number') {
|
|
57
|
+
return fieldTypes.NUMBER;
|
|
58
|
+
} else if (typeof value === 'function') {
|
|
59
|
+
return fieldTypes.BUTTON;
|
|
60
|
+
} else if (typeof value === 'boolean') {
|
|
61
|
+
return fieldTypes.CHECKBOX;
|
|
62
|
+
} else if (typeof value === 'string') {
|
|
63
|
+
if (isImage(value)) {
|
|
64
|
+
return fieldTypes.IMAGE;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return fieldTypes.TEXT;
|
|
68
|
+
} else {
|
|
69
|
+
if (
|
|
70
|
+
(isArray || isObject) &&
|
|
71
|
+
values.every((v) => typeof v === 'number') &&
|
|
72
|
+
values.length <= 4
|
|
73
|
+
) {
|
|
74
|
+
return fieldTypes.VEC;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
console.warn(`Field: cannot find field type for ${key}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export function hasChanged(initialValue, currentValue) {
|
|
83
|
+
const initialType = typeof initialValue;
|
|
84
|
+
const currentType = typeof currentValue;
|
|
85
|
+
|
|
86
|
+
if (initialType !== currentType) return true;
|
|
87
|
+
|
|
88
|
+
if (Array.isArray(currentValue)) {
|
|
89
|
+
if (initialValue.length !== currentValue.length) {
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
for (let i = 0; i < currentValue.length; i++) {
|
|
94
|
+
if (currentValue[i] !== initialValue[i]) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (initialType === 'object') {
|
|
102
|
+
const keys1 = Object.keys(initialValue);
|
|
103
|
+
const keys2 = Object.keys(currentValue);
|
|
104
|
+
|
|
105
|
+
if (
|
|
106
|
+
keys1.length !== keys2.length ||
|
|
107
|
+
!keys1.every((key) => keys2.includes(key))
|
|
108
|
+
) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
for (const key of keys1) {
|
|
113
|
+
const value1 = initialValue[key];
|
|
114
|
+
const value2 = currentValue[key];
|
|
115
|
+
|
|
116
|
+
if (typeof value1 === 'object' && typeof value2 === 'object') {
|
|
117
|
+
// If both values are objects, recursively compare them
|
|
118
|
+
if (hasChanged(value1, value2)) {
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
} else if (value1 !== value2) {
|
|
122
|
+
// If values are not objects, directly compare them
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return initialValue !== currentValue;
|
|
131
|
+
}
|