fragment-tools 0.2.8 → 0.2.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -10
- package/bin/index.js +4 -0
- package/package.json +11 -4
- package/src/cli/build.js +1 -3
- package/src/cli/create.js +55 -6
- package/src/cli/createConfig.js +9 -24
- package/src/cli/createFragmentFile.js +44 -46
- package/src/cli/getEntries.js +13 -5
- package/src/cli/plugins/check-dependencies.js +1 -1
- package/src/cli/plugins/save.js +7 -2
- package/src/cli/run.js +12 -3
- package/src/cli/templates/blank/index.js +4 -4
- package/src/cli/templates/blank/index.ts +15 -0
- package/src/cli/templates/default/index.js +7 -6
- package/src/cli/templates/default/index.ts +20 -0
- package/src/cli/templates/fragment-gl/fragment.fs +1 -1
- package/src/cli/templates/fragment-gl/index.js +3 -3
- package/src/cli/templates/fragment-gl/index.ts +20 -0
- package/src/cli/templates/p5/index.js +6 -6
- package/src/cli/templates/p5/index.ts +14 -0
- package/src/cli/templates/p5-webgl/fragment.fs +2 -4
- package/src/cli/templates/p5-webgl/index.js +9 -15
- package/src/cli/templates/p5-webgl/index.ts +43 -0
- package/src/cli/templates/three-fragment/fragment.fs +1 -1
- package/src/cli/templates/three-fragment/index.js +10 -4
- package/src/cli/templates/three-fragment/index.ts +68 -0
- package/src/cli/templates/three-orthographic/index.js +10 -4
- package/src/cli/templates/three-orthographic/index.ts +29 -0
- package/src/cli/templates/three-perspective/index.js +10 -4
- package/src/cli/templates/three-perspective/index.ts +26 -0
- package/src/cli/utils.js +3 -0
- package/src/client/app/components/HintRecord.svelte +3 -3
- package/src/client/app/hooks.js +5 -5
- package/src/client/app/lib/canvas-recorder/CanvasRecorder.js +3 -1
- package/src/client/app/lib/canvas-recorder/GIFRecorder.js +11 -1
- package/src/client/app/lib/canvas-recorder/MediaBunnyRecorder.js +97 -0
- package/src/client/app/lib/gl/Renderer.js +1 -1
- package/src/client/app/lib/gl/Texture.js +1 -1
- package/src/client/app/lib/gl/index.js +2 -2
- package/src/client/app/modules/AudioAnalyser/Range.svelte +2 -2
- package/src/client/app/modules/AudioAnalyser/Spectrum.svelte +3 -3
- package/src/client/app/modules/Console/ConsoleLine.svelte +13 -13
- package/src/client/app/modules/Console.svelte +6 -4
- package/src/client/app/modules/Exports.svelte +28 -4
- package/src/client/app/renderers/2DRenderer.js +6 -3
- package/src/client/app/renderers/FragmentRenderer.js +39 -2
- package/src/client/app/renderers/P5GLRenderer.js +28 -26
- package/src/client/app/renderers/P5Renderer.js +49 -9
- package/src/client/app/renderers/THREERenderer.js +64 -12
- package/src/client/app/state/exports.svelte.js +40 -2
- package/src/client/app/state/rendering.svelte.js +2 -2
- package/src/client/app/state/utils.svelte.js +9 -2
- package/src/client/app/stores/sketches.js +2 -1
- package/src/client/app/ui/ErrorOverlay.svelte +5 -5
- package/src/client/app/ui/Field.svelte +12 -8
- package/src/client/app/ui/FieldGroup.svelte +5 -5
- package/src/client/app/ui/FieldSection.svelte +8 -8
- package/src/client/app/ui/FieldSpace.svelte +2 -2
- package/src/client/app/ui/FieldTrigger.svelte +6 -6
- package/src/client/app/ui/FloatingParams.svelte +1 -1
- package/src/client/app/ui/LayoutBuild.svelte +1 -1
- package/src/client/app/ui/LayoutComponent.svelte +7 -7
- package/src/client/app/ui/LayoutResizer.svelte +1 -1
- package/src/client/app/ui/LayoutToolbar.svelte +6 -6
- package/src/client/app/ui/Module.svelte +6 -4
- package/src/client/app/ui/ModuleRenderer.svelte +3 -3
- package/src/client/app/ui/OutputRenderer.svelte +4 -1
- package/src/client/app/ui/SketchRenderer.svelte +9 -2
- package/src/client/app/ui/fields/ButtonInput.svelte +11 -11
- package/src/client/app/ui/fields/CheckboxInput.svelte +27 -19
- package/src/client/app/ui/fields/ColorInput.svelte +9 -7
- package/src/client/app/ui/fields/ImageInput.svelte +43 -23
- package/src/client/app/ui/fields/Input.svelte +13 -13
- package/src/client/app/ui/fields/IntervalInput.svelte +11 -14
- package/src/client/app/ui/fields/ListInput.svelte +9 -8
- package/src/client/app/ui/fields/ProgressInput.svelte +9 -9
- package/src/client/app/ui/fields/Select.svelte +13 -12
- package/src/client/app/ui/fields/VectorInput.svelte +1 -1
- package/src/client/app/utils/canvas.utils.js +21 -19
- package/src/client/public/css/global.css +26 -27
- package/src/types/client.d.ts +36 -0
- package/src/types/gl.d.ts +130 -0
- package/src/types/helpers.d.ts +5 -0
- package/src/types/hooks.d.ts +14 -0
- package/src/types/index.d.ts +8 -0
- package/src/types/midi.d.ts +176 -0
- package/src/types/props.d.ts +72 -0
- package/src/types/renderers.d.ts +100 -0
- package/src/types/sketch.d.ts +45 -0
- package/src/types/triggers.d.ts +45 -0
- package/src/types/utils.ts +11 -0
- package/tsconfig.json +38 -0
- package/.prettierignore +0 -4
- package/.prettierrc +0 -25
- package/src/client/app/lib/canvas-recorder/MP4Recorder.js +0 -44
- package/src/client/app/lib/canvas-recorder/WebMRecorder.js +0 -29
- package/src/client/app/lib/canvas-recorder/mp4.js +0 -1654
- package/src/client/app/lib/canvas-recorder/mp4.wasm +0 -0
|
@@ -3,10 +3,9 @@ https://github.com/mattdesl/canvas-sketch/blob/24f6bb2bbdfdfd72a698a0b8a0962ad84
|
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import { VIDEO_FORMATS } from '../state/exports.svelte';
|
|
6
|
-
import WebMRecorder from '../lib/canvas-recorder/WebMRecorder';
|
|
7
|
-
import MP4Recorder from '../lib/canvas-recorder/MP4Recorder';
|
|
8
6
|
import GIFRecorder from '../lib/canvas-recorder/GIFRecorder';
|
|
9
7
|
import FrameRecorder from '../lib/canvas-recorder/FrameRecorder';
|
|
8
|
+
import MediaBunnyRecorder from '../lib/canvas-recorder/MediaBunnyRecorder';
|
|
10
9
|
import { exportCanvas } from '../lib/canvas-recorder/utils';
|
|
11
10
|
import { map } from './math.utils';
|
|
12
11
|
import { createDataURLFromBlob, saveFiles } from './file.utils';
|
|
@@ -101,28 +100,21 @@ export async function screenshotCanvas(
|
|
|
101
100
|
}
|
|
102
101
|
}
|
|
103
102
|
|
|
104
|
-
function
|
|
105
|
-
let recorder = new
|
|
103
|
+
function record(canvas, options) {
|
|
104
|
+
let recorder = new MediaBunnyRecorder(canvas, options);
|
|
106
105
|
recorder.start();
|
|
107
106
|
|
|
108
107
|
return recorder;
|
|
109
108
|
}
|
|
110
109
|
|
|
111
|
-
function
|
|
112
|
-
let recorder = new MP4Recorder(canvas, options);
|
|
113
|
-
recorder.start();
|
|
114
|
-
|
|
115
|
-
return recorder;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function recordCanvasGIF(canvas, options) {
|
|
110
|
+
function recordGIF(canvas, options) {
|
|
119
111
|
let recorder = new GIFRecorder(canvas, options);
|
|
120
112
|
recorder.start();
|
|
121
113
|
|
|
122
114
|
return recorder;
|
|
123
115
|
}
|
|
124
116
|
|
|
125
|
-
function
|
|
117
|
+
function recordFrames(canvas, options) {
|
|
126
118
|
let recorder = new FrameRecorder(canvas, options);
|
|
127
119
|
recorder.start();
|
|
128
120
|
|
|
@@ -138,6 +130,7 @@ export function recordCanvas(
|
|
|
138
130
|
duration = Infinity,
|
|
139
131
|
quality = 100,
|
|
140
132
|
pattern = defaultFilenamePattern,
|
|
133
|
+
codec,
|
|
141
134
|
exportDir,
|
|
142
135
|
imageEncoding,
|
|
143
136
|
onStart = () => {},
|
|
@@ -189,6 +182,7 @@ export function recordCanvas(
|
|
|
189
182
|
|
|
190
183
|
const options = {
|
|
191
184
|
framerate,
|
|
185
|
+
format,
|
|
192
186
|
duration,
|
|
193
187
|
quality,
|
|
194
188
|
onStart,
|
|
@@ -198,14 +192,22 @@ export function recordCanvas(
|
|
|
198
192
|
|
|
199
193
|
let recorder;
|
|
200
194
|
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
195
|
+
if (
|
|
196
|
+
[
|
|
197
|
+
VIDEO_FORMATS.MKV,
|
|
198
|
+
VIDEO_FORMATS.MOV,
|
|
199
|
+
VIDEO_FORMATS.MP4,
|
|
200
|
+
VIDEO_FORMATS.WEBM,
|
|
201
|
+
].includes(format)
|
|
202
|
+
) {
|
|
203
|
+
recorder = record(canvas, {
|
|
204
|
+
...options,
|
|
205
|
+
codec,
|
|
206
|
+
});
|
|
205
207
|
} else if (format === VIDEO_FORMATS.GIF) {
|
|
206
|
-
recorder =
|
|
208
|
+
recorder = recordGIF(canvas, options);
|
|
207
209
|
} else if (format === VIDEO_FORMATS.FRAMES) {
|
|
208
|
-
recorder =
|
|
210
|
+
recorder = recordFrames(canvas, {
|
|
209
211
|
...options,
|
|
210
212
|
imageEncoding,
|
|
211
213
|
});
|
|
@@ -12,28 +12,27 @@
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
:root {
|
|
15
|
-
--font-
|
|
16
|
-
|
|
17
|
-
--color-lightred: #ffaeae;
|
|
18
|
-
--color-red: #ff4444;
|
|
19
|
-
--color-green: #9af49f;
|
|
20
|
-
--color-lightblack: #0e0e0e;
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
--color
|
|
24
|
-
--
|
|
25
|
-
--color-
|
|
26
|
-
--color
|
|
27
|
-
--
|
|
28
|
-
|
|
29
|
-
--
|
|
30
|
-
--
|
|
31
|
-
--color
|
|
32
|
-
|
|
33
|
-
--
|
|
34
|
-
--
|
|
35
|
-
--
|
|
36
|
-
--font-size-input: 11px;
|
|
15
|
+
--fragment-font-family: 'Jetbrains Mono', monospace;
|
|
16
|
+
|
|
17
|
+
--fragment-color-lightred: #ffaeae;
|
|
18
|
+
--fragment-color-red: #ff4444;
|
|
19
|
+
--fragment-color-green: #9af49f;
|
|
20
|
+
--fragment-color-lightblack: #0e0e0e;
|
|
21
|
+
--fragment-color-white: #f0f0f0;
|
|
22
|
+
|
|
23
|
+
--fragment-background-color: #242425;
|
|
24
|
+
--fragment-accent-color: #177bd0;
|
|
25
|
+
--fragment-color-disabled: #214366;
|
|
26
|
+
--fragment-text-color: var(--fragment-color-white);
|
|
27
|
+
--fragment-spacing-color: #323233;
|
|
28
|
+
|
|
29
|
+
--fragment-input-border-color: #000000;
|
|
30
|
+
--fragment-input-text-color: #989899;
|
|
31
|
+
--fragment-input-disabled-text-color: #535354;
|
|
32
|
+
--fragment-input-height: 20px;
|
|
33
|
+
--fragment-input-border-radius: 3px;
|
|
34
|
+
--fragment-input-font-size: 11px;
|
|
35
|
+
--fragment-input-background-color: #1d1d1e;
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
html {
|
|
@@ -48,9 +47,9 @@ body {
|
|
|
48
47
|
|
|
49
48
|
margin: 0;
|
|
50
49
|
padding: 0;
|
|
51
|
-
font-family: var(--font-
|
|
50
|
+
font-family: var(--fragment-font-family);
|
|
52
51
|
|
|
53
|
-
background-color: var(--color-lightblack);
|
|
52
|
+
background-color: var(--fragment-color-lightblack);
|
|
54
53
|
overscroll-behavior: none;
|
|
55
54
|
}
|
|
56
55
|
|
|
@@ -90,7 +89,7 @@ ol {
|
|
|
90
89
|
* {
|
|
91
90
|
box-sizing: border-box;
|
|
92
91
|
scrollbar-width: thin;
|
|
93
|
-
scrollbar-color: var(--color
|
|
92
|
+
scrollbar-color: var(--fragment-accent-color) transparent;
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
input,
|
|
@@ -100,7 +99,7 @@ button {
|
|
|
100
99
|
padding: 0;
|
|
101
100
|
margin: 0;
|
|
102
101
|
border: none;
|
|
103
|
-
font-family: var(--font-
|
|
102
|
+
font-family: var(--fragment-font-family);
|
|
104
103
|
}
|
|
105
104
|
|
|
106
105
|
h1,
|
|
@@ -123,7 +122,7 @@ h5 {
|
|
|
123
122
|
}
|
|
124
123
|
|
|
125
124
|
.loading {
|
|
126
|
-
color:
|
|
125
|
+
color: var(--fragment-text-color);
|
|
127
126
|
padding: 18px;
|
|
128
127
|
}
|
|
129
128
|
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
declare const __CWD__: string | undefined;
|
|
2
|
+
declare const __FRAGMENT_PORT__: string | number | undefined;
|
|
3
|
+
declare const __START_TIME__: string | number | undefined;
|
|
4
|
+
declare const __SEED__: string | number | undefined;
|
|
5
|
+
declare const __BUILD__: boolean | undefined;
|
|
6
|
+
|
|
7
|
+
declare const __THREE_RENDERER__: string | undefined;
|
|
8
|
+
declare const __FRAGMENT_RENDERER__: string | undefined;
|
|
9
|
+
declare const __P5_RENDERER__: string | undefined;
|
|
10
|
+
declare const __P5_WEBGL_RENDERER__: string | undefined;
|
|
11
|
+
declare const __2D_RENDERER__: string | undefined;
|
|
12
|
+
|
|
13
|
+
declare module '*.glsl' {
|
|
14
|
+
const value: string;
|
|
15
|
+
export default value;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare module '*.vs' {
|
|
19
|
+
const value: string;
|
|
20
|
+
export default value;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare module '*.vert' {
|
|
24
|
+
const value: string;
|
|
25
|
+
export default value;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
declare module '*.fs' {
|
|
29
|
+
const value: string;
|
|
30
|
+
export default value;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
declare module '*.frag' {
|
|
34
|
+
const value: string;
|
|
35
|
+
export default value;
|
|
36
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
declare module '@fragment/lib/gl' {
|
|
2
|
+
type Gl = WebGLRenderingContext | WebGL2RenderingContext;
|
|
3
|
+
|
|
4
|
+
type UniformValue = number | number[] | Texture | null;
|
|
5
|
+
type Uniform = { type?: string; value?: UniformValue };
|
|
6
|
+
type Uniforms = Record<string, Uniform>;
|
|
7
|
+
|
|
8
|
+
type Attributes = Record<string, { data: number[] }>;
|
|
9
|
+
|
|
10
|
+
class Geometry {
|
|
11
|
+
constructor(gl: Gl, attributes?: Attributes);
|
|
12
|
+
gl: Gl;
|
|
13
|
+
attributes: Attributes | null;
|
|
14
|
+
buffers: Record<string, WebGLBuffer> | null;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
class Texture {
|
|
18
|
+
constructor(
|
|
19
|
+
gl: Gl,
|
|
20
|
+
params?: {
|
|
21
|
+
image?: TexImageSource | null;
|
|
22
|
+
name?: string;
|
|
23
|
+
target?: number;
|
|
24
|
+
type?: number;
|
|
25
|
+
wrapS?: number;
|
|
26
|
+
wrapT?: number;
|
|
27
|
+
generateMipmaps?: boolean;
|
|
28
|
+
format?: number;
|
|
29
|
+
internalFormat?: number;
|
|
30
|
+
minFilter?: number;
|
|
31
|
+
magFilter?: number;
|
|
32
|
+
flipY?: boolean;
|
|
33
|
+
},
|
|
34
|
+
);
|
|
35
|
+
id: number;
|
|
36
|
+
gl: Gl;
|
|
37
|
+
image: TexImageSource | null;
|
|
38
|
+
name: string;
|
|
39
|
+
target: number;
|
|
40
|
+
type: number;
|
|
41
|
+
wrapS: number;
|
|
42
|
+
wrapT: number;
|
|
43
|
+
generateMipmaps: boolean;
|
|
44
|
+
format: number;
|
|
45
|
+
internalFormat: number;
|
|
46
|
+
minFilter: number;
|
|
47
|
+
magFilter: number;
|
|
48
|
+
flipY: boolean;
|
|
49
|
+
needsUpdate: boolean;
|
|
50
|
+
glTexture: WebGLTexture | null;
|
|
51
|
+
bind(): void;
|
|
52
|
+
update(textureUnit?: number): void;
|
|
53
|
+
destroy(): void;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
class Program {
|
|
57
|
+
constructor(
|
|
58
|
+
gl: Gl,
|
|
59
|
+
params?: {
|
|
60
|
+
vertex?: string;
|
|
61
|
+
fragment?: string;
|
|
62
|
+
uniforms?: Uniforms;
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
id: number;
|
|
66
|
+
gl: Gl;
|
|
67
|
+
vertexShader: string;
|
|
68
|
+
fragmentShader: string;
|
|
69
|
+
uniforms: Uniforms;
|
|
70
|
+
needsUpdate: boolean;
|
|
71
|
+
attributesLocations: Record<
|
|
72
|
+
string,
|
|
73
|
+
ReturnType<WebGLRenderingContext['getAttribLocation']>
|
|
74
|
+
>;
|
|
75
|
+
uniformsLocations: Record<
|
|
76
|
+
string,
|
|
77
|
+
ReturnType<WebGLRenderingContext['getUniformLocation']>
|
|
78
|
+
>;
|
|
79
|
+
compile(): void;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
class Renderer {
|
|
83
|
+
constructor(params?: {
|
|
84
|
+
canvas?: HTMLCanvasElement;
|
|
85
|
+
antialias?: boolean;
|
|
86
|
+
alpha?: boolean;
|
|
87
|
+
depth?: boolean;
|
|
88
|
+
stencil?: boolean;
|
|
89
|
+
premultipliedAlpha?: boolean;
|
|
90
|
+
pixelRatio?: number;
|
|
91
|
+
webgl?: 1 | 2;
|
|
92
|
+
});
|
|
93
|
+
gl: Gl;
|
|
94
|
+
canvas: HTMLCanvasElement;
|
|
95
|
+
render(params: {
|
|
96
|
+
geometry: Geometry;
|
|
97
|
+
program: Program;
|
|
98
|
+
primitiveType?: GLenum;
|
|
99
|
+
offset?: number;
|
|
100
|
+
count?: number;
|
|
101
|
+
}): void;
|
|
102
|
+
setPixelRatio(pixelRatio?: number): void;
|
|
103
|
+
setSize(params?: { width?: number; height?: number }): void;
|
|
104
|
+
setViewport(params?: { width?: number; height?: number }): void;
|
|
105
|
+
destroy(): void;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
interface Frag {
|
|
109
|
+
gl: Gl;
|
|
110
|
+
program: Program;
|
|
111
|
+
texture: (params?: {}) => Texture;
|
|
112
|
+
shader: string;
|
|
113
|
+
fragmentShader: string;
|
|
114
|
+
vertexShader: string;
|
|
115
|
+
uniforms: Uniforms;
|
|
116
|
+
resize: (params?: {
|
|
117
|
+
width?: number;
|
|
118
|
+
height?: number;
|
|
119
|
+
pixelRatio?: number;
|
|
120
|
+
}) => void;
|
|
121
|
+
render: () => void;
|
|
122
|
+
destroy: () => void;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function fragment(params?: {
|
|
126
|
+
canvas?: HTMLCanvasElement;
|
|
127
|
+
shader?: string;
|
|
128
|
+
uniforms?: Uniforms;
|
|
129
|
+
}): Frag;
|
|
130
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
declare module '@fragment/hooks' {
|
|
2
|
+
type Listener = (params: {
|
|
3
|
+
encoding: string;
|
|
4
|
+
quality: number;
|
|
5
|
+
count: number;
|
|
6
|
+
index: number;
|
|
7
|
+
pixelsPerInch: number;
|
|
8
|
+
}) => Function | void;
|
|
9
|
+
|
|
10
|
+
function onBeforeCapture(listener: Listener, context?: string): void;
|
|
11
|
+
function onAfterCapture(listener: Listener, context?: string): void;
|
|
12
|
+
function onBeforeRecord(listener: Listener, context?: string): void;
|
|
13
|
+
function onAfterRecord(listener: Listener, context?: string): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
export declare global {
|
|
2
|
+
namespace MIDI {
|
|
3
|
+
/**
|
|
4
|
+
* All the posible notes.
|
|
5
|
+
*/
|
|
6
|
+
type MIDINote =
|
|
7
|
+
| 'C'
|
|
8
|
+
| 'C#'
|
|
9
|
+
| 'D'
|
|
10
|
+
| 'D#'
|
|
11
|
+
| 'E'
|
|
12
|
+
| 'F'
|
|
13
|
+
| 'F#'
|
|
14
|
+
| 'G'
|
|
15
|
+
| 'G#'
|
|
16
|
+
| 'A'
|
|
17
|
+
| 'A#'
|
|
18
|
+
| 'B';
|
|
19
|
+
|
|
20
|
+
interface MIDIPort extends EventTarget {
|
|
21
|
+
/**
|
|
22
|
+
* A unique ID of the port. This can be used by developers to remember ports the
|
|
23
|
+
* user has chosen for their application.
|
|
24
|
+
*/
|
|
25
|
+
id: string;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The manufacturer of the port.
|
|
29
|
+
*/
|
|
30
|
+
manufacturer?: string | undefined;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The system name of the port.
|
|
34
|
+
*/
|
|
35
|
+
name?: string | undefined;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* A descriptor property to distinguish whether the port is an input or an output
|
|
39
|
+
* port.
|
|
40
|
+
*/
|
|
41
|
+
type: MIDIPortType;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The version of the port.
|
|
45
|
+
*/
|
|
46
|
+
version?: string | undefined;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The state of the device.
|
|
50
|
+
*/
|
|
51
|
+
state: MIDIPortDeviceState;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The state of the connection to the device.
|
|
55
|
+
*/
|
|
56
|
+
connection: MIDIPortConnectionState;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The handler called when an existing port changes its state or connection
|
|
60
|
+
* attributes.
|
|
61
|
+
*/
|
|
62
|
+
onstatechange(event: MIDIConnectionEvent): void;
|
|
63
|
+
|
|
64
|
+
addEventListener(
|
|
65
|
+
type: 'statechange',
|
|
66
|
+
listener: (this: this, event: MIDIConnectionEvent) => any,
|
|
67
|
+
options?: boolean | AddEventListenerOptions,
|
|
68
|
+
): void;
|
|
69
|
+
addEventListener(
|
|
70
|
+
type: string,
|
|
71
|
+
listener: EventListenerOrEventListenerObject,
|
|
72
|
+
options?: boolean | AddEventListenerOptions,
|
|
73
|
+
): void;
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Makes the MIDI device corresponding to the MIDIPort explicitly available. Note
|
|
77
|
+
* that this call is NOT required in order to use the MIDIPort - calling send() on
|
|
78
|
+
* a MIDIOutput or attaching a MIDIMessageEvent handler on a MIDIInputPort will
|
|
79
|
+
* cause an implicit open().
|
|
80
|
+
*
|
|
81
|
+
* When invoked, this method returns a Promise object representing a request for
|
|
82
|
+
* access to the given MIDI port on the user's system.
|
|
83
|
+
*/
|
|
84
|
+
open(): Promise<MIDIPort>;
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Makes the MIDI device corresponding to the MIDIPort
|
|
88
|
+
* explicitly unavailable (subsequently changing the state from "open" to
|
|
89
|
+
* "connected"). Note that successful invocation of this method will result in MIDI
|
|
90
|
+
* messages no longer being delivered to MIDIMessageEvent handlers on a
|
|
91
|
+
* MIDIInputPort (although setting a new handler will cause an implicit open()).
|
|
92
|
+
*
|
|
93
|
+
* When invoked, this method returns a Promise object representing a request for
|
|
94
|
+
* access to the given MIDI port on the user's system. When the port has been
|
|
95
|
+
* closed (and therefore, in exclusive access systems, the port is available to
|
|
96
|
+
* other applications), the vended Promise is resolved. If the port is
|
|
97
|
+
* disconnected, the Promise is rejected.
|
|
98
|
+
*/
|
|
99
|
+
close(): Promise<MIDIPort>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
interface MIDIInput extends MIDIPort {
|
|
103
|
+
type: 'input';
|
|
104
|
+
|
|
105
|
+
onmidimessage(e: MIDIMessageEvent): void;
|
|
106
|
+
|
|
107
|
+
addEventListener(
|
|
108
|
+
type: 'midimessage',
|
|
109
|
+
listener: (this: this, event: MIDIMessageEvent) => any,
|
|
110
|
+
options?: boolean | AddEventListenerOptions,
|
|
111
|
+
): void;
|
|
112
|
+
addEventListener(
|
|
113
|
+
type: 'statechange',
|
|
114
|
+
listener: (this: this, event: MIDIConnectionEvent) => any,
|
|
115
|
+
options?: boolean | AddEventListenerOptions,
|
|
116
|
+
): void;
|
|
117
|
+
addEventListener(
|
|
118
|
+
type: string,
|
|
119
|
+
listener: EventListenerOrEventListenerObject,
|
|
120
|
+
options?: boolean | AddEventListenerOptions,
|
|
121
|
+
): void;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
type MIDIMessageEvent = {
|
|
125
|
+
/**
|
|
126
|
+
* The type of the message event.
|
|
127
|
+
*/
|
|
128
|
+
type: 'noteon' | 'noteoff' | 'controlchange';
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The triggered note.
|
|
132
|
+
*/
|
|
133
|
+
note: { number: number; name: MIDINote };
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* The channel the message was sent to.
|
|
137
|
+
*/
|
|
138
|
+
channel: number;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* The normalized velocity of the note expressed as a float between 0 and 1.
|
|
142
|
+
*/
|
|
143
|
+
velocity: number;
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* The raw velocity of the note expressed as an integer between 0 and 127.
|
|
147
|
+
*/
|
|
148
|
+
rawVelocity: number;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* The normalized value expressed as a float between 0 and 1.
|
|
152
|
+
*/
|
|
153
|
+
value: number;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* The raw value expressed as an integer between 0 and 127.
|
|
157
|
+
*/
|
|
158
|
+
rawValue: number;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* The object that dispatched the event.
|
|
162
|
+
*/
|
|
163
|
+
currentTarget: MIDIInput;
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* The object that dispatched the event.
|
|
167
|
+
*/
|
|
168
|
+
target: MIDIInput;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* The object that dispatched the event.
|
|
172
|
+
*/
|
|
173
|
+
srcElement: MIDIInput;
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
type BaseProp<Value, Params, Type> = {
|
|
2
|
+
value: Value;
|
|
3
|
+
params?: Params;
|
|
4
|
+
type?: Type;
|
|
5
|
+
hidden?: boolean;
|
|
6
|
+
displayName?: string;
|
|
7
|
+
folder?: string;
|
|
8
|
+
group?: string;
|
|
9
|
+
onChange?: PropOnChange<Value, Params>;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
type SelectProp = BaseProp<
|
|
13
|
+
number | string,
|
|
14
|
+
{
|
|
15
|
+
options?:
|
|
16
|
+
| number[]
|
|
17
|
+
| string[]
|
|
18
|
+
| Array<{ label?: string; value: number }>
|
|
19
|
+
| Array<{ label?: string; value: string }>;
|
|
20
|
+
},
|
|
21
|
+
'select'
|
|
22
|
+
>;
|
|
23
|
+
type NumberProp = BaseProp<
|
|
24
|
+
number,
|
|
25
|
+
{ disabled?: boolean; step?: number } | { min: number; max: number },
|
|
26
|
+
'number'
|
|
27
|
+
>;
|
|
28
|
+
type VecProp = BaseProp<
|
|
29
|
+
| [number, number]
|
|
30
|
+
| [number, number, number]
|
|
31
|
+
| [number, number, number, number],
|
|
32
|
+
{ locked?: boolean },
|
|
33
|
+
'vec'
|
|
34
|
+
>;
|
|
35
|
+
type CheckboxProp = BaseProp<boolean, never, 'checkbox'>;
|
|
36
|
+
type TextProp = BaseProp<string, { disabled?: boolean }, 'text'>;
|
|
37
|
+
type ListProp = BaseProp<any[], { disabled?: boolean }, 'list'>;
|
|
38
|
+
type ColorProp = BaseProp<
|
|
39
|
+
string | THREE.Color | { r: number; g: number; b: string; a?: number },
|
|
40
|
+
never,
|
|
41
|
+
'color'
|
|
42
|
+
>;
|
|
43
|
+
type ButtonProp = BaseProp<
|
|
44
|
+
() => void,
|
|
45
|
+
{ disabled?: boolean; label?: string },
|
|
46
|
+
'button' | 'download'
|
|
47
|
+
>;
|
|
48
|
+
type ImageProp = BaseProp<string, never, 'image'>;
|
|
49
|
+
|
|
50
|
+
type Prop =
|
|
51
|
+
| SelectProp
|
|
52
|
+
| NumberProp
|
|
53
|
+
| VecProp
|
|
54
|
+
| CheckboxProp
|
|
55
|
+
| TextProp
|
|
56
|
+
| ListProp
|
|
57
|
+
| ColorProp
|
|
58
|
+
| ButtonProp
|
|
59
|
+
| ImageProp;
|
|
60
|
+
|
|
61
|
+
export type Props = Record<string, Prop>;
|
|
62
|
+
|
|
63
|
+
export type PropOnChangeOptions<Value, Params> = {
|
|
64
|
+
value: Value;
|
|
65
|
+
_initialValue: Value;
|
|
66
|
+
params: Params;
|
|
67
|
+
onChange: PropOnChange<Value, Params>;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type PropOnChange<Value, Params> = (
|
|
71
|
+
options: PropOnChangeOptions<Value, Params>,
|
|
72
|
+
) => void;
|