fragment-tools 0.1.1 → 0.1.12
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 +37 -16
- package/bin/index.js +1 -0
- package/package.json +1 -1
- package/src/cli/plugins/screenshot.js +25 -10
- package/src/cli/server.js +5 -14
- package/src/cli/templates/blank.js +13 -0
- package/src/cli/templates/index.js +3 -0
- package/src/client/app/lib/canvas-recorder/CanvasRecorder.js +4 -4
- package/src/client/app/modules/Params.svelte +1 -1
- package/src/client/app/stores/exports.js +1 -1
- package/src/client/app/stores/layout.js +1 -1
- package/src/client/app/stores/multisampling.js +3 -3
- package/src/client/app/stores/props.js +24 -22
- package/src/client/app/stores/renderers.js +24 -22
- package/src/client/app/stores/rendering.js +1 -1
- package/src/client/app/stores/sketches.js +1 -1
- package/src/client/app/triggers/Keyboard.js +1 -1
- package/src/client/app/triggers/MIDI.js +5 -1
- package/src/client/app/ui/Build.svelte +24 -21
- package/src/client/app/ui/Field.svelte +11 -7
- package/src/client/app/ui/FieldTrigger.svelte +12 -7
- package/src/client/app/ui/Layout.svelte +2 -2
- package/src/client/app/ui/LayoutComponent.svelte +1 -1
- package/src/client/app/ui/SketchRenderer.svelte +35 -24
- package/src/client/app/ui/fields/ButtonInput.svelte +2 -0
- package/src/client/app/ui/fields/CheckboxInput.svelte +2 -0
- package/src/client/app/ui/fields/ColorInput.svelte +138 -80
- package/src/client/app/ui/fields/ImageInput.svelte +2 -0
- package/src/client/app/ui/fields/Input.svelte +7 -1
- package/src/client/app/ui/fields/ListInput.svelte +2 -0
- package/src/client/app/ui/fields/NumberInput.svelte +9 -0
- package/src/client/app/ui/fields/ProgressInput.svelte +5 -1
- package/src/client/app/ui/fields/Select.svelte +47 -17
- package/src/client/app/ui/fields/TextInput.svelte +3 -1
- package/src/client/app/ui/fields/VectorInput.svelte +37 -47
- package/src/client/app/utils/canvas.utils.js +29 -21
- package/src/client/app/utils/color.utils.js +239 -136
- package/src/client/app/utils/file.utils.js +1 -1
- package/src/client/app/utils/props.utils.js +11 -13
- package/. npmignore +0 -4
- package/docs/README.md +0 -18
- package/docs/api/CLI.md +0 -44
- package/docs/api/renderers.md +0 -80
- package/docs/api/sketch.md +0 -216
- package/docs/api/triggers.md +0 -101
- package/docs/guide/about.md +0 -16
- package/docs/guide/exports.md +0 -86
- package/docs/guide/external-dependencies.md +0 -22
- package/docs/guide/getting-started.md +0 -113
- package/docs/guide/hot-shader-reloading.md +0 -20
- package/docs/guide/shortcuts.md +0 -12
- package/docs/guide/triggers.png +0 -0
- package/docs/guide/using-triggers.md +0 -39
- package/examples/cube-three.js +0 -34
- package/examples/ellipse-p5.js +0 -26
- package/examples/icon.fs +0 -96
- package/examples/icon.js +0 -63
- package/examples/icon.png +0 -0
- package/examples/icon.transparent.png +0 -0
- package/examples/package-lock.json +0 -40
- package/examples/package.json +0 -14
- package/examples/shape-2d.js +0 -50
- package/examples/shape-three.js +0 -49
- package/examples/shape-tree.fs +0 -3
- package/src/client/app/ui/fields/Vec2Input.svelte +0 -5
- package/src/client/app/ui/fields/Vec3Input.svelte +0 -6
package/README.md
CHANGED
|
@@ -17,33 +17,21 @@
|
|
|
17
17
|
|
|
18
18
|
## Installation
|
|
19
19
|
|
|
20
|
-
`fragment` is not yet available on [npmjs.com](npmjs.com) so you need to clone and link the project in order to use it. It's only a few steps.
|
|
21
|
-
|
|
22
20
|
```
|
|
23
|
-
|
|
24
|
-
git clone https://github.com/raphaelameaume/fragment
|
|
25
|
-
|
|
26
|
-
# move to the project directory
|
|
27
|
-
cd fragment
|
|
28
|
-
|
|
29
|
-
# link the project
|
|
30
|
-
npm link
|
|
21
|
+
npm install fragment-tools -g
|
|
31
22
|
```
|
|
32
23
|
|
|
33
|
-
You should now be able to run `fragment` from your command line.
|
|
24
|
+
You should now be able to run `fragment` from your command line.
|
|
34
25
|
|
|
35
26
|
## Usage
|
|
36
27
|
|
|
37
28
|
```
|
|
38
29
|
# create a new directory for your sketches
|
|
39
|
-
mkdir
|
|
30
|
+
mkdir sketches
|
|
40
31
|
|
|
41
32
|
# move into that folder
|
|
42
33
|
cd sketches
|
|
43
34
|
|
|
44
|
-
# initialize npm for linking to work
|
|
45
|
-
npm init
|
|
46
|
-
|
|
47
35
|
# create a sketch from a template
|
|
48
36
|
fragment ./sketch.js --new --template=2d
|
|
49
37
|
```
|
|
@@ -80,7 +68,7 @@ export let update = ({ context, width, height }) => {
|
|
|
80
68
|
};
|
|
81
69
|
```
|
|
82
70
|
|
|
83
|
-
Learn how to write your own sketch
|
|
71
|
+
Learn how to write your own sketch by following the [Getting started](./docs//guide/getting-started.md) guide, reading the [API docs](./docs/api/sketch.md) or the [examples](./examples/).
|
|
84
72
|
|
|
85
73
|
## Contributing
|
|
86
74
|
|
|
@@ -88,6 +76,39 @@ If you find issues, please [file one](https://github.com/raphaelameaume/fragment
|
|
|
88
76
|
|
|
89
77
|
Feel free to reach out on [Twitter](https://twitter.com/raphaelameaume) if you want to discuss the project.
|
|
90
78
|
|
|
79
|
+
## Running it locally
|
|
80
|
+
|
|
81
|
+
```
|
|
82
|
+
# clone or fork the project
|
|
83
|
+
git clone https://github.com/raphaelameaume/fragment.git
|
|
84
|
+
|
|
85
|
+
# move to the root of the repository
|
|
86
|
+
cd fragment
|
|
87
|
+
|
|
88
|
+
# run the command line locally
|
|
89
|
+
node ./bin/index.js examples/shape-2d.js --dev
|
|
90
|
+
|
|
91
|
+
# or from your sketch folder
|
|
92
|
+
node [path-to-root]/bin/index.js sketch.js --dev
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
> The `--dev` flag only enables Vite `info` logLevel, helpful for development. Otherwise it will work the same as when you're running from the npm package.
|
|
96
|
+
|
|
97
|
+
Alternatively, you can tell npm to point the `fragment` command to the newly cloned folder.
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
# at the root of the repo
|
|
101
|
+
npm link
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
You should be able the command as before, only this time it will point to the repository instead of the globally installed package.
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
fragment sketch.js
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If that's not the case, try to uninstall `fragment-tools` globally first, make sure the `fragment` command is not found anymore, then retry to link the project from the root of the repo.
|
|
111
|
+
|
|
91
112
|
## Credits
|
|
92
113
|
|
|
93
114
|
- [Vite](https://vitejs.dev/)
|
package/bin/index.js
CHANGED
|
@@ -11,6 +11,7 @@ sade('fragment [entry]')
|
|
|
11
11
|
.option('-p, --port', 'Port to bind', 3000)
|
|
12
12
|
.option('-dev, --development', 'Enable development mode', false)
|
|
13
13
|
.option('-b, --build', 'Build sketch for production', false)
|
|
14
|
+
.option('--exportDir', 'Directory used for exports', process.cwd())
|
|
14
15
|
.option('--outDir', 'Directory used for static build', null)
|
|
15
16
|
.option('--emptyOutDir', "Empty outDir before static build", false)
|
|
16
17
|
.action((entry, options) => {
|
package/package.json
CHANGED
|
@@ -1,26 +1,41 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import fs from "fs";
|
|
2
|
+
import fs from "fs/promises";
|
|
3
|
+
import fsSync from "fs";
|
|
3
4
|
import bodyParser from "body-parser";
|
|
5
|
+
import log from "../log.js";
|
|
6
|
+
|
|
7
|
+
export default function screenshot({ cwd, exportDir = cwd }) {
|
|
8
|
+
let dir = (path.isAbsolute(exportDir) ? exportDir : path.join(cwd, exportDir));
|
|
4
9
|
|
|
5
|
-
export default function screenshot({ cwd }) {
|
|
6
10
|
return {
|
|
7
11
|
name: 'screenshot',
|
|
8
12
|
configureServer(server){
|
|
9
13
|
server.middlewares.use(bodyParser.json({ limit: '100mb'}))
|
|
10
|
-
server.middlewares.use('/save', (req, res, next) => {
|
|
14
|
+
server.middlewares.use('/save', async (req, res, next) => {
|
|
11
15
|
if (req.method === "POST") {
|
|
12
16
|
const { filename, dataURL } = req.body;
|
|
13
17
|
|
|
14
|
-
const filepath = path.join(
|
|
18
|
+
const filepath = path.join(dir, filename);
|
|
15
19
|
const buffer = Buffer.from(dataURL, 'base64');
|
|
16
20
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
21
|
+
if (!fsSync.existsSync(dir)) {
|
|
22
|
+
try {
|
|
23
|
+
await fs.mkdir(dir, { recursive: true });
|
|
24
|
+
} catch(error) {
|
|
25
|
+
log.error('Cannot create directory for exports');
|
|
26
|
+
console.log(error);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
try {
|
|
31
|
+
await fs.writeFile(filepath, buffer);
|
|
20
32
|
|
|
21
|
-
res.writeHead(
|
|
22
|
-
res.end(JSON.stringify(
|
|
23
|
-
})
|
|
33
|
+
res.writeHead(200, {'Content-Type': 'application/json'});
|
|
34
|
+
res.end(JSON.stringify({ filepath }));
|
|
35
|
+
} catch(error) {
|
|
36
|
+
res.writeHead(500, {'Content-Type': 'application/json'});
|
|
37
|
+
res.end(JSON.stringify({ error }));
|
|
38
|
+
}
|
|
24
39
|
} else {
|
|
25
40
|
next();
|
|
26
41
|
}
|
package/src/cli/server.js
CHANGED
|
@@ -62,7 +62,7 @@ export async function start({ options, filepaths, entries, fragment }) {
|
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
64
|
dbPlugin(),
|
|
65
|
-
screenshotPlugin({ cwd }),
|
|
65
|
+
screenshotPlugin({ cwd, exportDir: options.exportDir }),
|
|
66
66
|
checkDependencies({
|
|
67
67
|
cwd,
|
|
68
68
|
app,
|
|
@@ -83,7 +83,9 @@ export async function start({ options, filepaths, entries, fragment }) {
|
|
|
83
83
|
'__FRAGMENT_PORT__': fragment.server ? fragment.server.port : undefined,
|
|
84
84
|
'__START_TIME__': Date.now(),
|
|
85
85
|
'__SEED__': Date.now(),
|
|
86
|
-
'
|
|
86
|
+
'__BUILD__': options.build,
|
|
87
|
+
'__DEV__': !options.build,
|
|
88
|
+
|
|
87
89
|
},
|
|
88
90
|
optimizeDeps: {
|
|
89
91
|
include: ['convert-length', 'webm-writer', 'changedpi'],
|
|
@@ -128,18 +130,7 @@ export async function start({ options, filepaths, entries, fragment }) {
|
|
|
128
130
|
|
|
129
131
|
await server.listen();
|
|
130
132
|
log.success(`Server started at:`);
|
|
131
|
-
|
|
132
|
-
Object.values(os.networkInterfaces())
|
|
133
|
-
.flatMap((nInterface) => nInterface ?? [])
|
|
134
|
-
.filter((detail) => detail && detail.address && (detail.family === 'IPv4' || detail.family === 4 ))
|
|
135
|
-
.forEach((detail) => {
|
|
136
|
-
const type = detail.address.includes('127.0.0.1')
|
|
137
|
-
? 'Local: '
|
|
138
|
-
: 'Network: '
|
|
139
|
-
const host = detail.address.replace('127.0.0.1', 'localhost');
|
|
140
|
-
const url = `http://${host}:${server.config.server.port}`;
|
|
141
|
-
console.log(` ${type} ${url}`);
|
|
142
|
-
})
|
|
133
|
+
server.printUrls();
|
|
143
134
|
|
|
144
135
|
return server;
|
|
145
136
|
}
|
|
@@ -49,7 +49,7 @@ class CanvasRecorder {
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
async _tick() {
|
|
52
|
-
console.log(`CanvasRecorder - render frame ${this.frameCount}`);
|
|
52
|
+
console.log(`CanvasRecorder - render frame ${this.frameCount + 1}`);
|
|
53
53
|
this.onTick({
|
|
54
54
|
time: this.time,
|
|
55
55
|
deltaTime: this.deltaTime,
|
|
@@ -61,14 +61,14 @@ class CanvasRecorder {
|
|
|
61
61
|
frameCount: this.frameCount,
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
if (this.started && !this.stopped && (!isFinite(this.frameTotal) || (isFinite(this.frameTotal) && this.frameCount < this.frameTotal))) {
|
|
64
|
+
if (this.started && !this.stopped && (!isFinite(this.frameTotal) || (isFinite(this.frameTotal) && this.frameCount < this.frameTotal - 1))) {
|
|
65
65
|
this.time += this.deltaTime;
|
|
66
66
|
this.frameCount++;
|
|
67
67
|
requestAnimationFrame(() => {
|
|
68
68
|
this._tick()
|
|
69
69
|
});
|
|
70
70
|
} else {
|
|
71
|
-
console.log(`CanvasRecorder - compiling ${this.frameCount} frames...`);
|
|
71
|
+
console.log(`CanvasRecorder - compiling ${this.frameCount + 1} frames...`);
|
|
72
72
|
this.end();
|
|
73
73
|
}
|
|
74
74
|
}
|
|
@@ -76,7 +76,7 @@ class CanvasRecorder {
|
|
|
76
76
|
tick() {}
|
|
77
77
|
|
|
78
78
|
end() {
|
|
79
|
-
console.log(`CanvasRecorder - compiled ${this.frameCount} frames`);
|
|
79
|
+
console.log(`CanvasRecorder - compiled ${this.frameCount + 1} frames`);
|
|
80
80
|
this.onComplete(this.result);
|
|
81
81
|
}
|
|
82
82
|
|
|
@@ -92,8 +92,8 @@ $: showOutputParams = (monitor && monitor.selected === "output") ||
|
|
|
92
92
|
context={sketchKey}
|
|
93
93
|
key={key}
|
|
94
94
|
value={sketchProps[key].value}
|
|
95
|
-
params={sketchProps[key].params || {}}
|
|
96
95
|
type={sketchProps[key].type}
|
|
96
|
+
bind:params={sketchProps[key].params}
|
|
97
97
|
on:click={() => {
|
|
98
98
|
$props[sketchKey][key].value._refresh = true;
|
|
99
99
|
}}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { createStore } from "./utils";
|
|
2
2
|
|
|
3
3
|
export const multisampling = createStore("multisampling", [], {
|
|
4
|
-
persist: !
|
|
4
|
+
persist: !__BUILD__,
|
|
5
5
|
reset: true,
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
export const threshold = createStore("threshold", 0, {
|
|
9
|
-
persist: !
|
|
9
|
+
persist: !__BUILD__,
|
|
10
10
|
reset: false,
|
|
11
11
|
});
|
|
12
12
|
|
|
13
13
|
export const transition = createStore("transition", false, {
|
|
14
|
-
persist: !
|
|
14
|
+
persist: !__BUILD__,
|
|
15
15
|
reset: false,
|
|
16
16
|
});
|
|
@@ -4,41 +4,43 @@ import { sketches } from "./sketches";
|
|
|
4
4
|
export const props = writable({});
|
|
5
5
|
|
|
6
6
|
sketches.subscribe((sketches) => {
|
|
7
|
-
|
|
7
|
+
props.update((currentProps) => {
|
|
8
|
+
Object.keys(sketches).forEach((key) => {
|
|
9
|
+
const sketch = sketches[key];
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
$props[key] = reconcile(sketch.props, $props[key]);
|
|
14
|
-
}
|
|
11
|
+
if (sketch) { // sketch can be undefined if failed to load
|
|
12
|
+
currentProps[key] = reconcile(sketch.props, currentProps[key]);
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
15
|
|
|
16
|
+
return currentProps;
|
|
16
17
|
});
|
|
17
|
-
|
|
18
|
-
props.set($props);
|
|
19
18
|
});
|
|
20
19
|
|
|
21
|
-
function reconcile(newProps = {},
|
|
22
|
-
Object.keys(newProps).forEach(propKey => {
|
|
23
|
-
|
|
20
|
+
function reconcile(newProps = {}, prevProps = {}) {
|
|
21
|
+
Object.keys(newProps).forEach((propKey) => {
|
|
22
|
+
let newProp = newProps[propKey];
|
|
23
|
+
|
|
24
|
+
if (!newProp.params) {
|
|
25
|
+
newProp.params = {};
|
|
26
|
+
}
|
|
24
27
|
});
|
|
25
28
|
|
|
26
|
-
if (
|
|
27
|
-
Object.keys(
|
|
29
|
+
if (prevProps) {
|
|
30
|
+
Object.keys(prevProps).forEach((propKey) => {
|
|
31
|
+
let prevProp = prevProps[propKey];
|
|
28
32
|
let newProp = newProps[propKey];
|
|
29
33
|
|
|
30
34
|
if (newProp) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (overrideValue) {
|
|
37
|
-
newProp.value = prevProp.value;
|
|
35
|
+
if (prevProp.params) {
|
|
36
|
+
// reconcile locked VectorInput from UI
|
|
37
|
+
if (prevProp.params.locked !== undefined) {
|
|
38
|
+
newProp.params.locked = prevProp.params.locked;
|
|
39
|
+
}
|
|
38
40
|
}
|
|
39
41
|
}
|
|
40
42
|
});
|
|
41
|
-
}
|
|
43
|
+
}
|
|
42
44
|
|
|
43
45
|
return newProps;
|
|
44
46
|
}
|
|
@@ -2,7 +2,7 @@ import { rendering } from "./rendering";
|
|
|
2
2
|
|
|
3
3
|
export let renderers = {};
|
|
4
4
|
|
|
5
|
-
function loadRenderer(renderingMode
|
|
5
|
+
function loadRenderer(renderingMode) {
|
|
6
6
|
if (__THREE_RENDERER__ && renderingMode === "three") {
|
|
7
7
|
return import("../renderers/THREERenderer.js");
|
|
8
8
|
}
|
|
@@ -20,7 +20,7 @@ function loadRenderer(renderingMode = "2d") {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
export async function findRenderer(renderingMode
|
|
23
|
+
export async function findRenderer(renderingMode) {
|
|
24
24
|
if (renderers[renderingMode]) return renderers[renderingMode];
|
|
25
25
|
|
|
26
26
|
// load and save
|
|
@@ -30,31 +30,33 @@ export async function findRenderer(renderingMode = "2d") {
|
|
|
30
30
|
let renderer = renderers[renderingMode];
|
|
31
31
|
let initialized = false;
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
if (renderer) {
|
|
34
|
+
rendering.subscribe((current) => {
|
|
35
|
+
let r;
|
|
36
|
+
|
|
37
|
+
if (!initialized) {
|
|
38
|
+
if (typeof renderer.init === "function") {
|
|
39
|
+
r = renderer.init({
|
|
40
|
+
canvas: document.createElement('canvas'),
|
|
41
|
+
pixelRatio: current.pixelRatio,
|
|
42
|
+
width: current.width,
|
|
43
|
+
height: current.height,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
35
47
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
pixelRatio: current.pixelRatio,
|
|
48
|
+
initialized = true;
|
|
49
|
+
|
|
50
|
+
if (typeof renderer.resize === "function") {
|
|
51
|
+
renderer.resize({
|
|
41
52
|
width: current.width,
|
|
42
53
|
height: current.height,
|
|
54
|
+
pixelRatio: current.pixelRatio,
|
|
55
|
+
...r,
|
|
43
56
|
});
|
|
44
57
|
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
initialized = true;
|
|
48
|
-
|
|
49
|
-
if (typeof renderer.resize === "function") {
|
|
50
|
-
renderer.resize({
|
|
51
|
-
width: current.width,
|
|
52
|
-
height: current.height,
|
|
53
|
-
pixelRatio: current.pixelRatio,
|
|
54
|
-
...r,
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
58
60
|
|
|
59
61
|
return renderer;
|
|
60
62
|
}
|
|
@@ -3,7 +3,7 @@ import { displayError } from "../stores/errors";
|
|
|
3
3
|
import { sketches as all, onSketchReload } from "@fragment/sketches";
|
|
4
4
|
|
|
5
5
|
export const sketches = createStore('sketches', {});
|
|
6
|
-
export const sketchesKeys = createStore('sketchesKeys',
|
|
6
|
+
export const sketchesKeys = createStore('sketchesKeys', Object.keys(all));
|
|
7
7
|
export const sketchesCount = createStore('sketchesCount', 0);
|
|
8
8
|
|
|
9
9
|
async function loadSketch(collection, key) {
|
|
@@ -61,7 +61,7 @@ function createTrigger(eventName, collection) {
|
|
|
61
61
|
const { hot, enabled, ...params } = options;
|
|
62
62
|
const context = getContext();
|
|
63
63
|
|
|
64
|
-
const keys = Array.isArray(key) ? key : [key];
|
|
64
|
+
const keys = Array.isArray(key) ? key : [...key.split(',').map(k => k !== " " ? k.trim() : k)];
|
|
65
65
|
|
|
66
66
|
const trigger = new Trigger({
|
|
67
67
|
inputType: 'Keyboard',
|
|
@@ -78,7 +78,11 @@ function createTrigger(eventName, collection) {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
const { hot, enabled, ...params } = options;
|
|
81
|
-
|
|
81
|
+
let keys = Array.isArray(key) ? key : [...key.split(',').map(k => k.trim())];
|
|
82
|
+
|
|
83
|
+
if (["onControlChange", "onNumberOn", "onNumberOff"].includes(eventName)) {
|
|
84
|
+
keys = keys.map((k) => Number(k));
|
|
85
|
+
}
|
|
82
86
|
|
|
83
87
|
if (!MIDI.enabled) {
|
|
84
88
|
MIDI.request();
|
|
@@ -22,37 +22,40 @@ let defaultGUIConfig = {
|
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
let guiConfig = defaultGUIConfig;
|
|
25
|
-
$: sketchKey = ($layout.previewing && $preview) ? $preview : sketchesKeys[0];
|
|
25
|
+
$: sketchKey = ($layout.previewing && $preview) ? $preview : $sketchesKeys[0];
|
|
26
26
|
$: sketch = $sketches[sketchKey];
|
|
27
27
|
|
|
28
28
|
$: {
|
|
29
|
-
if (sketch
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
if (sketch) {
|
|
30
|
+
if (sketch.buildConfig) {
|
|
31
|
+
override(sketch.buildConfig);
|
|
32
|
+
}
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
const config = sketch.buildConfig ? sketch.buildConfig : {};
|
|
35
|
+
gui = config.gui;
|
|
35
36
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
if (gui && typeof gui === "object") {
|
|
38
|
+
guiConfig = {
|
|
39
|
+
...defaultGUIConfig,
|
|
40
|
+
...gui,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const { styles = "" } = config;
|
|
42
45
|
|
|
43
|
-
|
|
46
|
+
if (styles !== "") {
|
|
47
|
+
head = document.getElementsByTagName('head')[0];
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
if (style) {
|
|
50
|
+
head.removeChild(style);
|
|
51
|
+
}
|
|
47
52
|
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
style = document.createElement('style');
|
|
54
|
+
style.setAttribute('type', 'text/css');
|
|
55
|
+
style.appendChild(document.createTextNode(styles));
|
|
56
|
+
head.appendChild(style);
|
|
50
57
|
}
|
|
51
58
|
|
|
52
|
-
style = document.createElement('style');
|
|
53
|
-
style.setAttribute('type', 'text/css');
|
|
54
|
-
style.appendChild(document.createTextNode(styles));
|
|
55
|
-
head.appendChild(style);
|
|
56
59
|
}
|
|
57
60
|
}
|
|
58
61
|
|
|
@@ -4,8 +4,7 @@ import { createEventDispatcher } from "svelte";
|
|
|
4
4
|
import Select from "./fields/Select.svelte";
|
|
5
5
|
import NumberInput from "./fields/NumberInput.svelte";
|
|
6
6
|
import CheckboxInput from "./fields/CheckboxInput.svelte";
|
|
7
|
-
import
|
|
8
|
-
import Vec3Input from "./fields/Vec3Input.svelte";
|
|
7
|
+
import VectorInput from "./fields/VectorInput.svelte";
|
|
9
8
|
import TextInput from "./fields/TextInput.svelte";
|
|
10
9
|
import ColorInput from "./fields/ColorInput.svelte";
|
|
11
10
|
import ListInput from "./fields/ListInput.svelte";
|
|
@@ -20,7 +19,7 @@ import frameDebounce from "../lib/helpers/frameDebounce.js";
|
|
|
20
19
|
import { getStore } from "../stores/utils";
|
|
21
20
|
import { writable } from "svelte/store";
|
|
22
21
|
|
|
23
|
-
export let key =
|
|
22
|
+
export let key = "";
|
|
24
23
|
export let value = null;
|
|
25
24
|
export let context = null;
|
|
26
25
|
export let params = {};
|
|
@@ -50,8 +49,7 @@ const dispatch = createEventDispatcher();
|
|
|
50
49
|
const fields = {
|
|
51
50
|
"select": Select,
|
|
52
51
|
"number": NumberInput,
|
|
53
|
-
"
|
|
54
|
-
"vec3": Vec3Input,
|
|
52
|
+
"vec": VectorInput,
|
|
55
53
|
"checkbox": CheckboxInput,
|
|
56
54
|
"text": TextInput,
|
|
57
55
|
"list": ListInput,
|
|
@@ -120,7 +118,11 @@ function toggleTriggers(event) {
|
|
|
120
118
|
function composeFieldProps(params) {
|
|
121
119
|
const { triggerable, controllable, ...rest } = params;
|
|
122
120
|
|
|
123
|
-
return
|
|
121
|
+
return {
|
|
122
|
+
...rest,
|
|
123
|
+
key,
|
|
124
|
+
context,
|
|
125
|
+
};
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
</script>
|
|
@@ -149,7 +151,7 @@ function composeFieldProps(params) {
|
|
|
149
151
|
</svg>
|
|
150
152
|
</button>
|
|
151
153
|
{/if}
|
|
152
|
-
{#if (fieldType === "
|
|
154
|
+
{#if (fieldType === "vec") && !disabled }
|
|
153
155
|
<button class="field__action field__action--lock" on:click={() => params.locked = !params.locked}>
|
|
154
156
|
{#if params.locked}
|
|
155
157
|
<svg class="action__icon" width="16" height="16" fill="none" viewBox="0 0 24 24">
|
|
@@ -200,11 +202,13 @@ function composeFieldProps(params) {
|
|
|
200
202
|
|
|
201
203
|
:global(.field__input .field) {
|
|
202
204
|
padding-left: 0px !important;
|
|
205
|
+
padding-right: 0px !important;
|
|
203
206
|
}
|
|
204
207
|
|
|
205
208
|
:global(.field__input .field:last-child) {
|
|
206
209
|
border-bottom: 0px solid #323233 !important;
|
|
207
210
|
padding-bottom: 0px !important;
|
|
211
|
+
|
|
208
212
|
}
|
|
209
213
|
|
|
210
214
|
.field.disabled {
|
|
@@ -72,7 +72,7 @@ function onTypeChange(event) {
|
|
|
72
72
|
|
|
73
73
|
if (!eventOptions.includes(eventName)) {
|
|
74
74
|
eventName = undefined;
|
|
75
|
-
key = null;
|
|
75
|
+
params.key = null;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
if (trigger) {
|
|
@@ -82,19 +82,24 @@ function onTypeChange(event) {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function onEventChange(event) {
|
|
85
|
+
const clearParams = (inputType === "MIDI" && eventName !== undefined &&
|
|
86
|
+
((eventName.includes("Number") && event.detail.includes("Note")) ||
|
|
87
|
+
(eventName.includes("Note") && event.detail.includes("Number")))
|
|
88
|
+
);
|
|
89
|
+
|
|
85
90
|
eventName = event.detail;
|
|
86
91
|
|
|
92
|
+
if (clearParams) {
|
|
93
|
+
params.key = "";
|
|
94
|
+
}
|
|
95
|
+
|
|
87
96
|
if (inputType === "Mouse") {
|
|
88
97
|
registerTrigger();
|
|
89
98
|
}
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
function onTextChange(e) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
params.key = e.detail.split(',').map((value) => {
|
|
96
|
-
return castToNumber ? Number(value) : value;
|
|
97
|
-
});
|
|
102
|
+
params.key = e.detail;
|
|
98
103
|
|
|
99
104
|
registerTrigger();
|
|
100
105
|
}
|
|
@@ -153,7 +158,7 @@ $: eventOptions = inputType ? [
|
|
|
153
158
|
] : [];
|
|
154
159
|
|
|
155
160
|
$: isValid = inputType && eventName;
|
|
156
|
-
$: key = params.key
|
|
161
|
+
$: key = params.key;
|
|
157
162
|
|
|
158
163
|
</script>
|
|
159
164
|
|