fragment-tools 0.1.13 → 0.1.14
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/bin/index.js +2 -2
- package/package.json +4 -5
- package/src/cli/log.js +31 -21
- package/src/cli/plugins/check-dependencies.js +47 -30
- package/src/cli/plugins/hot-shader-replacement.js +384 -0
- package/src/cli/plugins/hot-sketch-reload.js +3 -13
- package/src/cli/plugins/screenshot.js +57 -20
- package/src/cli/server.js +144 -133
- package/src/client/app/App.svelte +3 -3
- package/src/client/app/client.js +55 -39
- package/src/client/app/components/Init.svelte +12 -9
- package/src/client/app/helpers.js +42 -0
- package/src/client/app/hooks.js +20 -0
- package/src/client/app/inputs/Keyboard.js +13 -15
- package/src/client/app/inputs/MIDI.js +14 -15
- package/src/client/app/lib/canvas-recorder/CanvasRecorder.js +41 -21
- package/src/client/app/lib/gl/Renderer.js +127 -139
- package/src/client/app/modules/Exports.svelte +62 -43
- package/src/client/app/modules/MidiPanel.svelte +100 -101
- package/src/client/app/modules/Params.svelte +116 -103
- package/src/client/app/renderers/2DRenderer.js +3 -3
- package/src/client/app/renderers/FragmentRenderer.js +30 -23
- package/src/client/app/renderers/P5Renderer.js +10 -7
- package/src/client/app/renderers/THREERenderer.js +136 -94
- package/src/client/app/stores/exports.js +36 -20
- package/src/client/app/stores/props.js +28 -5
- package/src/client/app/stores/renderers.js +22 -15
- package/src/client/app/stores/sketches.js +7 -9
- package/src/client/app/stores/utils.js +95 -38
- package/src/client/app/triggers/Keyboard.js +88 -79
- package/src/client/app/triggers/MIDI.js +110 -84
- package/src/client/app/ui/Field.svelte +343 -240
- package/src/client/app/ui/FieldGroup.svelte +106 -94
- package/src/client/app/ui/FieldSection.svelte +125 -116
- package/src/client/app/ui/ParamsMultisampling.svelte +96 -95
- package/src/client/app/ui/ParamsOutput.svelte +113 -113
- package/src/client/app/ui/SelectChevrons.svelte +27 -15
- package/src/client/app/ui/SketchRenderer.svelte +761 -667
- 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/ImageInput.svelte +123 -121
- package/src/client/app/ui/fields/Input.svelte +100 -111
- package/src/client/app/ui/fields/ListInput.svelte +96 -96
- package/src/client/app/ui/fields/NumberInput.svelte +121 -116
- package/src/client/app/ui/fields/ProgressInput.svelte +80 -73
- package/src/client/app/ui/fields/Select.svelte +137 -124
- package/src/client/app/ui/fields/VectorInput.svelte +86 -82
- package/src/client/app/utils/canvas.utils.js +228 -201
- package/src/client/app/utils/file.utils.js +38 -34
- package/src/client/public/css/global.css +27 -21
- package/src/cli/plugins/hot-shader-reload.js +0 -86
|
@@ -1,27 +1,59 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import fs from
|
|
3
|
-
import fsSync from
|
|
4
|
-
import bodyParser from
|
|
5
|
-
import log from
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import fsSync from 'fs';
|
|
4
|
+
import bodyParser from 'body-parser';
|
|
5
|
+
import log from '../log.js';
|
|
6
6
|
|
|
7
|
-
export default function screenshot({ cwd,
|
|
8
|
-
|
|
7
|
+
export default function screenshot({ cwd, inlineExportDir }) {
|
|
8
|
+
function resolveDirectory(directoryPath) {
|
|
9
|
+
return path.isAbsolute(directoryPath)
|
|
10
|
+
? directoryPath
|
|
11
|
+
: path.join(cwd, directoryPath);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function resolveExportDirectory({ exportDir }) {
|
|
15
|
+
let directory;
|
|
16
|
+
|
|
17
|
+
if (inlineExportDir) {
|
|
18
|
+
if (!inlineExportDirPath) {
|
|
19
|
+
inlineExportDirPath = resolveDirectory(inlineExportDir);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
directory = inlineExportDirPath;
|
|
23
|
+
|
|
24
|
+
if (exportDir) {
|
|
25
|
+
log.warning(
|
|
26
|
+
`'exportDir' configuration from sketch has been overridden by --exportDir.`,
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
} else if (exportDir) {
|
|
30
|
+
directory = resolveDirectory(exportDir);
|
|
31
|
+
} else {
|
|
32
|
+
directory = cwd;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return directory;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let inlineExportDirPath;
|
|
9
39
|
|
|
10
40
|
return {
|
|
11
41
|
name: 'screenshot',
|
|
12
|
-
configureServer(server){
|
|
13
|
-
server.middlewares.use(bodyParser.json({ limit: '100mb'}))
|
|
42
|
+
configureServer(server) {
|
|
43
|
+
server.middlewares.use(bodyParser.json({ limit: '100mb' }));
|
|
14
44
|
server.middlewares.use('/save', async (req, res, next) => {
|
|
15
|
-
if (req.method ===
|
|
45
|
+
if (req.method === 'POST') {
|
|
16
46
|
const { filename, dataURL } = req.body;
|
|
17
47
|
|
|
18
|
-
|
|
48
|
+
let directory = resolveExportDirectory(req.body);
|
|
49
|
+
|
|
50
|
+
const filepath = path.join(directory, filename);
|
|
19
51
|
const buffer = Buffer.from(dataURL, 'base64');
|
|
20
52
|
|
|
21
|
-
if (!fsSync.existsSync(
|
|
53
|
+
if (!fsSync.existsSync(directory)) {
|
|
22
54
|
try {
|
|
23
|
-
await fs.mkdir(
|
|
24
|
-
} catch(error) {
|
|
55
|
+
await fs.mkdir(directory, { recursive: true });
|
|
56
|
+
} catch (error) {
|
|
25
57
|
log.error('Cannot create directory for exports');
|
|
26
58
|
console.log(error);
|
|
27
59
|
}
|
|
@@ -30,17 +62,22 @@ export default function screenshot({ cwd, exportDir = cwd }) {
|
|
|
30
62
|
try {
|
|
31
63
|
await fs.writeFile(filepath, buffer);
|
|
32
64
|
|
|
33
|
-
|
|
65
|
+
log.success(`Saved ${filepath}`);
|
|
66
|
+
|
|
67
|
+
res.writeHead(200, {
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
});
|
|
34
70
|
res.end(JSON.stringify({ filepath }));
|
|
35
|
-
} catch(error) {
|
|
36
|
-
res.writeHead(500, {
|
|
71
|
+
} catch (error) {
|
|
72
|
+
res.writeHead(500, {
|
|
73
|
+
'Content-Type': 'application/json',
|
|
74
|
+
});
|
|
37
75
|
res.end(JSON.stringify({ error }));
|
|
38
76
|
}
|
|
39
77
|
} else {
|
|
40
78
|
next();
|
|
41
79
|
}
|
|
42
80
|
});
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
81
|
+
},
|
|
82
|
+
};
|
|
46
83
|
}
|
package/src/cli/server.js
CHANGED
|
@@ -1,153 +1,164 @@
|
|
|
1
|
-
import path from
|
|
2
|
-
import kleur from
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import kleur from 'kleur';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
-
import { createServer, defineConfig, build } from
|
|
5
|
-
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
|
6
|
-
import
|
|
7
|
-
import hotSketchReload from
|
|
8
|
-
import dbPlugin from
|
|
4
|
+
import { createServer, defineConfig, build } from 'vite';
|
|
5
|
+
import { svelte } from '@sveltejs/vite-plugin-svelte';
|
|
6
|
+
import hotShaderReplacement from './plugins/hot-shader-replacement.js';
|
|
7
|
+
import hotSketchReload from './plugins/hot-sketch-reload.js';
|
|
8
|
+
import dbPlugin from './plugins/db.js';
|
|
9
9
|
|
|
10
|
-
import log from
|
|
11
|
-
import
|
|
12
|
-
import
|
|
13
|
-
import checkDependencies from "./plugins/check-dependencies.js";
|
|
10
|
+
import log from './log.js';
|
|
11
|
+
import screenshotPlugin from './plugins/screenshot.js';
|
|
12
|
+
import checkDependencies from './plugins/check-dependencies.js';
|
|
14
13
|
|
|
15
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
16
15
|
const __dirname = path.dirname(__filename);
|
|
17
16
|
|
|
18
17
|
export async function start({ options, filepaths, entries, fragment }) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
const root = path.join(__dirname, '/../client');
|
|
19
|
+
const cwd = process.cwd();
|
|
20
|
+
const app = path.join(root, 'app');
|
|
22
21
|
|
|
23
|
-
|
|
22
|
+
const entriesPaths = entries.map((entry) => path.join(cwd, entry));
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
24
|
+
const config = defineConfig({
|
|
25
|
+
configFile: false,
|
|
26
|
+
root,
|
|
27
|
+
logLevel: options.development ? 'info' : 'silent',
|
|
28
|
+
resolve: {
|
|
29
|
+
alias: [
|
|
30
|
+
{ find: '@fragment/sketches', replacement: filepaths[0] },
|
|
31
|
+
{ find: '@fragment', replacement: app },
|
|
32
|
+
{
|
|
33
|
+
find: 'three',
|
|
34
|
+
replacement: path.join(cwd, 'node_modules/three'),
|
|
35
|
+
},
|
|
36
|
+
{ find: 'p5', replacement: path.join(cwd, 'node_modules/p5') },
|
|
37
|
+
{
|
|
38
|
+
find: 'ogl',
|
|
39
|
+
replacement: path.join(cwd, 'node_modules/ogl'),
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
plugins: [
|
|
44
|
+
svelte({
|
|
45
|
+
configFile: false,
|
|
46
|
+
onwarn: (warning, handler) => {
|
|
47
|
+
if (options.development) {
|
|
48
|
+
handler(warning);
|
|
49
|
+
} else {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
}),
|
|
54
|
+
hotSketchReload({
|
|
55
|
+
cwd,
|
|
56
|
+
}),
|
|
57
|
+
hotShaderReplacement({ cwd, wss: fragment.server }),
|
|
58
|
+
{
|
|
59
|
+
name: 'configure-response-headers',
|
|
60
|
+
configureServer: (server) => {
|
|
61
|
+
server.middlewares.use((_req, res, next) => {
|
|
62
|
+
res.setHeader(
|
|
63
|
+
'Cross-Origin-Opener-Policy',
|
|
64
|
+
'same-origin',
|
|
65
|
+
);
|
|
66
|
+
res.setHeader(
|
|
67
|
+
'Cross-Origin-Embedder-Policy',
|
|
68
|
+
'require-corp',
|
|
69
|
+
);
|
|
70
|
+
next();
|
|
71
|
+
});
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
dbPlugin(),
|
|
75
|
+
screenshotPlugin({ cwd, inlineExportDir: options.exportDir }),
|
|
76
|
+
checkDependencies({
|
|
77
|
+
cwd,
|
|
78
|
+
app,
|
|
79
|
+
entriesPaths,
|
|
80
|
+
build: options.build,
|
|
81
|
+
}),
|
|
82
|
+
],
|
|
83
|
+
server: {
|
|
84
|
+
port: options.port,
|
|
85
|
+
host: true,
|
|
86
|
+
fs: {
|
|
87
|
+
strict: false,
|
|
88
|
+
allow: ['..'],
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
define: {
|
|
92
|
+
__CWD__: `${JSON.stringify(cwd)}`,
|
|
93
|
+
__FRAGMENT_PORT__: fragment.server
|
|
94
|
+
? fragment.server.port
|
|
95
|
+
: undefined,
|
|
96
|
+
__START_TIME__: Date.now(),
|
|
97
|
+
__SEED__: Date.now(),
|
|
98
|
+
__BUILD__: options.build,
|
|
99
|
+
__DEV__: !options.build,
|
|
100
|
+
},
|
|
101
|
+
optimizeDeps: {
|
|
102
|
+
include: ['convert-length', 'webm-writer', 'changedpi'],
|
|
103
|
+
exclude: ['@fragment/sketches', ...entriesPaths],
|
|
104
|
+
},
|
|
105
|
+
build: {
|
|
106
|
+
commonjsOptions: {
|
|
107
|
+
include: ['convert-length', 'webm-writer', 'changedpi'],
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
});
|
|
87
111
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
...entriesPaths,
|
|
94
|
-
]
|
|
95
|
-
},
|
|
96
|
-
build: {
|
|
97
|
-
commonjsOptions: {
|
|
98
|
-
include: ['convert-length', 'webm-writer', 'changedpi'],
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
});
|
|
112
|
+
if (options.build) {
|
|
113
|
+
if (entries.length > 1) {
|
|
114
|
+
log.error(`fragment can only build one sketch at a time.`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
102
117
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
118
|
+
const outDir = options.outDir
|
|
119
|
+
? options.outDir
|
|
120
|
+
: entries[0].split('.js')[0];
|
|
108
121
|
|
|
109
|
-
|
|
122
|
+
await build({
|
|
123
|
+
...config,
|
|
124
|
+
logLevel: 'info',
|
|
125
|
+
build: {
|
|
126
|
+
outDir: path.join(process.cwd(), outDir),
|
|
127
|
+
emptyOutDir: options.emptyOutDir,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
110
130
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
emptyOutDir: options.emptyOutDir,
|
|
117
|
-
},
|
|
118
|
-
});
|
|
131
|
+
log.success(`Built files for:`);
|
|
132
|
+
entries.forEach((entry) => console.log(`- ${entry}`));
|
|
133
|
+
} else {
|
|
134
|
+
log.warning(`Starting server...`);
|
|
135
|
+
const server = await createServer(config);
|
|
119
136
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
log.warning(`Starting server...`);
|
|
124
|
-
const server = await createServer(config);
|
|
137
|
+
server.middlewares.use('/db', (req, res, next) => {
|
|
138
|
+
next();
|
|
139
|
+
});
|
|
125
140
|
|
|
126
|
-
|
|
127
|
-
next();
|
|
128
|
-
});
|
|
141
|
+
await server.listen();
|
|
129
142
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
log.success(`Server started at:`);
|
|
143
|
+
log.success(`Server started at:`);
|
|
133
144
|
|
|
134
|
-
|
|
145
|
+
const { resolvedUrls } = server;
|
|
135
146
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
for (const url of resolvedUrls.local) {
|
|
148
|
+
console.log(
|
|
149
|
+
` ${kleur.green('➜')} ${kleur.bold('Local')}: ${kleur.cyan(
|
|
150
|
+
url,
|
|
151
|
+
)}`,
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
for (const url of resolvedUrls.network) {
|
|
155
|
+
console.log(
|
|
156
|
+
` ${kleur.green('➜')} ${kleur.bold('Network')}: ${kleur.cyan(
|
|
157
|
+
url,
|
|
158
|
+
)}`,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
150
161
|
|
|
151
|
-
|
|
152
|
-
|
|
162
|
+
return server;
|
|
163
|
+
}
|
|
153
164
|
}
|
package/src/client/app/client.js
CHANGED
|
@@ -1,68 +1,84 @@
|
|
|
1
|
-
const socketProtocol =
|
|
1
|
+
const socketProtocol = location.protocol === 'https:' ? 'wss' : 'ws';
|
|
2
2
|
const socketHost = `${location.hostname}:${__FRAGMENT_PORT__}`;
|
|
3
3
|
|
|
4
|
-
let socket,
|
|
4
|
+
let socket,
|
|
5
|
+
listeners = {};
|
|
5
6
|
|
|
6
7
|
function handleMessage(payload) {
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
const { event, data = {} } = payload;
|
|
9
|
+
const callbacks = listeners[event];
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
if (callbacks && callbacks.length) {
|
|
12
|
+
callbacks.forEach((cb) => cb(data));
|
|
13
|
+
}
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
function on(event, cb) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
if (!listeners[event]) {
|
|
18
|
+
listeners[event] = [];
|
|
19
|
+
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
listeners[event].push(cb);
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
return () => {
|
|
24
|
+
off(event, cb);
|
|
25
|
+
};
|
|
25
26
|
}
|
|
26
27
|
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
function off(event, cb) {
|
|
29
|
+
const callbacks = listeners[event];
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
if (callbacks && callbacks.length) {
|
|
32
|
+
const filtered = callbacks.filter((callback) => callback !== cb);
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
listeners[event] = filtered;
|
|
35
|
+
}
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
let opened = false;
|
|
38
39
|
function emit(event, data) {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
if (opened) {
|
|
41
|
+
socket.send(
|
|
42
|
+
JSON.stringify({
|
|
43
|
+
event,
|
|
44
|
+
data,
|
|
45
|
+
}),
|
|
46
|
+
);
|
|
47
|
+
}
|
|
45
48
|
}
|
|
46
49
|
|
|
47
50
|
if (import.meta.hot) {
|
|
48
|
-
|
|
51
|
+
console.log('[fragment] connecting...');
|
|
49
52
|
|
|
50
|
-
|
|
53
|
+
socket = new WebSocket(`${socketProtocol}://${socketHost}`);
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
55
|
+
socket.addEventListener('message', async (message) => {
|
|
56
|
+
const { data } = message;
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
58
|
+
handleMessage(JSON.parse(data));
|
|
59
|
+
});
|
|
57
60
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
socket.addEventListener('open', () => {
|
|
62
|
+
console.log('[fragment] connected.');
|
|
63
|
+
opened = true;
|
|
64
|
+
});
|
|
62
65
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
+
import.meta.hot.on('sketch-update', (data) => {
|
|
67
|
+
console.log(`[fragment] hmr update /${data.filepath}`);
|
|
68
|
+
});
|
|
66
69
|
}
|
|
67
70
|
|
|
68
71
|
export const client = { on, off, emit };
|
|
72
|
+
|
|
73
|
+
client.on('shader-update', (shaderUpdates) => {
|
|
74
|
+
shaderUpdates.forEach(({ warnings = [] } = {}) => {
|
|
75
|
+
if (warnings.length > 0) {
|
|
76
|
+
warnings.forEach((warning) => {
|
|
77
|
+
const { location } = warning;
|
|
78
|
+
console.warn(
|
|
79
|
+
`[fragment-plugin-hsr] ${warning.type} ${warning.importer}\n\n ${location.lineText}\n\n${warning.message}`,
|
|
80
|
+
);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
});
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { assignSketchFiles } from
|
|
3
|
-
import { sketchesKeys } from
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
sketchesKeys.subscribe((keys) => {
|
|
7
|
-
if (keys.length > 0) {
|
|
8
|
-
assignSketchFiles(keys);
|
|
9
|
-
}
|
|
10
|
-
})
|
|
2
|
+
import { assignSketchFiles } from '../triggers/shared.js';
|
|
3
|
+
import { loadAll, sketchesKeys } from '../stores/sketches.js';
|
|
4
|
+
import { onSketchReload } from '@fragment/sketches';
|
|
5
|
+
import '../utils/glslErrors.js';
|
|
11
6
|
|
|
7
|
+
sketchesKeys.subscribe((keys) => {
|
|
8
|
+
if (keys.length > 0) {
|
|
9
|
+
assignSketchFiles(keys);
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
12
|
|
|
13
|
+
onSketchReload(({ sketches }) => {
|
|
14
|
+
loadAll(sketches);
|
|
15
|
+
});
|
|
13
16
|
</script>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { props } from './stores/props';
|
|
2
|
+
|
|
3
|
+
const propHandler = {
|
|
4
|
+
set: function (target, key, value, receiver) {
|
|
5
|
+
Reflect.set(target, key, value, receiver);
|
|
6
|
+
|
|
7
|
+
if (key === 'value') {
|
|
8
|
+
props.update((currentProps) => currentProps);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return true;
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const propsHandler = {
|
|
16
|
+
get: (target, key) => {
|
|
17
|
+
if (typeof target[key] === 'object' && target[key] !== null) {
|
|
18
|
+
return new Proxy(target[key], propHandler);
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
set: (target, key, value) => {
|
|
22
|
+
console.log('new set', target, key, value);
|
|
23
|
+
|
|
24
|
+
target[key] = value;
|
|
25
|
+
|
|
26
|
+
props.update((currentProps) => currentProps);
|
|
27
|
+
|
|
28
|
+
return true;
|
|
29
|
+
},
|
|
30
|
+
deleteProperty: (target, prop) => {
|
|
31
|
+
if (prop in target) {
|
|
32
|
+
delete target[prop];
|
|
33
|
+
props.update((currentProps) => currentProps);
|
|
34
|
+
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export function reactiveProps(props = {}) {
|
|
41
|
+
return new Proxy(props, propsHandler);
|
|
42
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
removeBeforeCaptureFrom,
|
|
3
|
+
removeAfterCaptureFrom,
|
|
4
|
+
removeBeforeRecordFrom,
|
|
5
|
+
removeAfterRecordFrom,
|
|
6
|
+
} from './stores/exports';
|
|
7
|
+
|
|
8
|
+
export {
|
|
9
|
+
onBeforeCapture,
|
|
10
|
+
onAfterCapture,
|
|
11
|
+
onBeforeRecord,
|
|
12
|
+
onAfterRecord,
|
|
13
|
+
} from './stores/exports';
|
|
14
|
+
|
|
15
|
+
export function removeHooksFrom(context) {
|
|
16
|
+
removeBeforeCaptureFrom(context);
|
|
17
|
+
removeAfterCaptureFrom(context);
|
|
18
|
+
removeBeforeRecordFrom(context);
|
|
19
|
+
removeAfterRecordFrom(context);
|
|
20
|
+
}
|
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import Input from
|
|
1
|
+
import Input from './Input';
|
|
2
2
|
|
|
3
3
|
class Keyboard extends Input {
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
* @param {KeyboardEvent} event
|
|
7
|
+
*/
|
|
8
|
+
getStepFromEvent(event) {
|
|
9
|
+
if (event.shiftKey) {
|
|
10
|
+
return 10;
|
|
11
|
+
} else if (event.altKey) {
|
|
12
|
+
return 0.1;
|
|
13
|
+
}
|
|
4
14
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
* @param {KeyboardEvent} event
|
|
8
|
-
*/
|
|
9
|
-
getStepFromEvent(event) {
|
|
10
|
-
if (event.shiftKey) {
|
|
11
|
-
return 10;
|
|
12
|
-
} else if (event.altKey) {
|
|
13
|
-
return 0.1;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
return 1;
|
|
17
|
-
}
|
|
18
|
-
|
|
15
|
+
return 1;
|
|
16
|
+
}
|
|
19
17
|
}
|
|
20
18
|
|
|
21
19
|
export default new Keyboard();
|