fragment-tools 0.1.11 → 0.1.13
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 +5 -0
- package/.prettierrc +9 -0
- package/bin/index.js +16 -15
- package/package.json +2 -1
- package/src/cli/plugins/screenshot.js +25 -10
- package/src/cli/server.js +22 -15
- 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/lib/canvas-recorder/GIFRecorder.js +29 -34
- package/src/client/app/lib/gl/Renderer.js +139 -127
- 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/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/ui/Build.svelte +24 -21
- 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/ColorInput.svelte +14 -0
- package/src/client/app/ui/fields/ProgressInput.svelte +3 -1
- package/src/client/app/ui/fields/Select.svelte +45 -17
- package/src/client/app/utils/canvas.utils.js +29 -21
- package/src/client/app/utils/color.utils.js +50 -6
- package/src/client/app/utils/file.utils.js +1 -1
- package/src/client/public/js/gif.js +0 -2
- package/src/client/public/js/gif.worker.js +0 -2
package/.prettierignore
ADDED
package/.prettierrc
ADDED
package/bin/index.js
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import sade from
|
|
4
|
-
import { run } from
|
|
3
|
+
import sade from 'sade';
|
|
4
|
+
import { run } from '../src/cli/index.js';
|
|
5
5
|
|
|
6
6
|
sade('fragment [entry]')
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
7
|
+
.version('0.1.13')
|
|
8
|
+
.describe('Run a dev environment for fragment')
|
|
9
|
+
.option('-n, --new', 'Create file if it does not exist', false)
|
|
10
|
+
.option('-t, --template', 'Specify template to create the file from', '2d')
|
|
11
|
+
.option('-p, --port', 'Port to bind', 3000)
|
|
12
|
+
.option('-dev, --development', 'Enable development mode', false)
|
|
13
|
+
.option('-b, --build', 'Build sketch for production', false)
|
|
14
|
+
.option('--exportDir', 'Directory used for exports', process.cwd())
|
|
15
|
+
.option('--outDir', 'Directory used for static build', null)
|
|
16
|
+
.option('--emptyOutDir', 'Empty outDir before static build', false)
|
|
17
|
+
.action((entry, options) => {
|
|
18
|
+
run(entry, options);
|
|
19
|
+
})
|
|
20
|
+
.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fragment-tools",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "A web development environment for creative coding",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
"chokidar": "^3.5.2",
|
|
26
26
|
"convert-length": "^1.0.1",
|
|
27
27
|
"get-port": "^6.0.0",
|
|
28
|
+
"gifenc": "^1.0.3",
|
|
28
29
|
"glslify": "^7.1.1",
|
|
29
30
|
"kleur": "^4.1.4",
|
|
30
31
|
"sade": "^1.7.4",
|
|
@@ -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
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import
|
|
3
|
-
import fs from "fs/promises";
|
|
2
|
+
import kleur from "kleur";
|
|
4
3
|
import { fileURLToPath } from 'url';
|
|
5
4
|
import { createServer, defineConfig, build } from "vite";
|
|
6
5
|
import { svelte } from '@sveltejs/vite-plugin-svelte'
|
|
@@ -62,7 +61,7 @@ export async function start({ options, filepaths, entries, fragment }) {
|
|
|
62
61
|
}
|
|
63
62
|
},
|
|
64
63
|
dbPlugin(),
|
|
65
|
-
screenshotPlugin({ cwd }),
|
|
64
|
+
screenshotPlugin({ cwd, exportDir: options.exportDir }),
|
|
66
65
|
checkDependencies({
|
|
67
66
|
cwd,
|
|
68
67
|
app,
|
|
@@ -83,7 +82,9 @@ export async function start({ options, filepaths, entries, fragment }) {
|
|
|
83
82
|
'__FRAGMENT_PORT__': fragment.server ? fragment.server.port : undefined,
|
|
84
83
|
'__START_TIME__': Date.now(),
|
|
85
84
|
'__SEED__': Date.now(),
|
|
86
|
-
'
|
|
85
|
+
'__BUILD__': options.build,
|
|
86
|
+
'__DEV__': !options.build,
|
|
87
|
+
|
|
87
88
|
},
|
|
88
89
|
optimizeDeps: {
|
|
89
90
|
include: ['convert-length', 'webm-writer', 'changedpi'],
|
|
@@ -127,19 +128,25 @@ export async function start({ options, filepaths, entries, fragment }) {
|
|
|
127
128
|
});
|
|
128
129
|
|
|
129
130
|
await server.listen();
|
|
131
|
+
|
|
130
132
|
log.success(`Server started at:`);
|
|
131
133
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
.
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
134
|
+
const { resolvedUrls } = server;
|
|
135
|
+
|
|
136
|
+
for (const url of resolvedUrls.local) {
|
|
137
|
+
console.log(
|
|
138
|
+
` ${kleur.green('➜')} ${kleur.bold('Local')}: ${kleur.cyan(
|
|
139
|
+
url,
|
|
140
|
+
)}`,
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
for (const url of resolvedUrls.network) {
|
|
144
|
+
console.log(
|
|
145
|
+
` ${kleur.green('➜')} ${kleur.bold('Network')}: ${kleur.cyan(
|
|
146
|
+
url,
|
|
147
|
+
)}`,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
143
150
|
|
|
144
151
|
return server;
|
|
145
152
|
}
|
|
@@ -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
|
|
|
@@ -1,51 +1,46 @@
|
|
|
1
|
-
import { map } from
|
|
2
|
-
import {
|
|
3
|
-
import CanvasRecorder from
|
|
1
|
+
import { map } from '../../utils/math.utils';
|
|
2
|
+
import { GIFEncoder, quantize, applyPalette } from 'gifenc';
|
|
3
|
+
import CanvasRecorder from './CanvasRecorder';
|
|
4
4
|
|
|
5
5
|
class GIFRecorder extends CanvasRecorder {
|
|
6
|
+
start() {
|
|
7
|
+
this.encoder = GIFEncoder();
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
this.tmpCanvas = document.createElement('canvas');
|
|
10
|
+
this.tmpContext = this.tmpCanvas.getContext('2d');
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
if (!GIFRecorder.loaded) {
|
|
11
|
-
await loadScript('/js/gif.worker.js');
|
|
12
|
-
await loadScript('/js/gif.js');
|
|
12
|
+
this.maxColors = Math.floor(map(this.quality, 1, 100, 1, 256));
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const quality = map(this.quality, 1, 100, 10, 0);
|
|
14
|
+
super.start();
|
|
15
|
+
}
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
});
|
|
17
|
+
getBitmapRGBA(bitmap, width = bitmap.width, height = bitmap.height) {
|
|
18
|
+
this.tmpCanvas.width = width;
|
|
19
|
+
this.tmpCanvas.height = height;
|
|
20
|
+
this.tmpContext.clearRect(0, 0, width, height);
|
|
21
|
+
this.tmpContext.drawImage(bitmap, 0, 0, width, height);
|
|
22
|
+
return this.tmpContext.getImageData(0, 0, width, height).data;
|
|
26
23
|
}
|
|
27
24
|
|
|
28
25
|
tick() {
|
|
29
|
-
|
|
30
|
-
}
|
|
26
|
+
const { width, height } = this.canvas;
|
|
31
27
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
this.result = result;
|
|
36
|
-
this.writer = null;
|
|
28
|
+
const pixels = this.getBitmapRGBA(this.canvas, width, height);
|
|
29
|
+
const palette = quantize(pixels, this.maxColors);
|
|
30
|
+
const index = applyPalette(pixels, palette);
|
|
37
31
|
|
|
38
|
-
|
|
32
|
+
this.encoder.writeFrame(index, width, height, {
|
|
33
|
+
palette: palette,
|
|
34
|
+
delay: this.frameDuration,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
end() {
|
|
39
|
+
this.encoder.finish();
|
|
42
40
|
|
|
43
|
-
|
|
44
|
-
reject(err);
|
|
45
|
-
});
|
|
41
|
+
this.result = new Blob([this.encoder.bytes()], { type: 'image/gif' });
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
});
|
|
43
|
+
super.end();
|
|
49
44
|
}
|
|
50
45
|
}
|
|
51
46
|
|
|
@@ -1,148 +1,160 @@
|
|
|
1
1
|
class Renderer {
|
|
2
|
+
constructor({
|
|
3
|
+
canvas = document.createElement("canvas"),
|
|
4
|
+
antialias = false,
|
|
5
|
+
alpha = true,
|
|
6
|
+
depth = false,
|
|
7
|
+
stencil = false,
|
|
8
|
+
premultipliedAlpha = false,
|
|
9
|
+
pixelRatio = window.devicePixelRatio,
|
|
10
|
+
webgl = 2,
|
|
11
|
+
}) {
|
|
12
|
+
let gl;
|
|
13
|
+
let attributes = {
|
|
14
|
+
depth,
|
|
15
|
+
stencil,
|
|
16
|
+
antialias,
|
|
17
|
+
alpha,
|
|
18
|
+
premultipliedAlpha,
|
|
19
|
+
preserveDrawingBuffer: true,
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
this.canvas = canvas;
|
|
23
|
+
|
|
24
|
+
if (webgl === 2) gl = canvas.getContext("webgl2", attributes);
|
|
25
|
+
if (!gl) {
|
|
26
|
+
gl =
|
|
27
|
+
canvas.getContext("webgl", attributes) ||
|
|
28
|
+
canvas.getContext("experimental-webgl", attributes);
|
|
29
|
+
}
|
|
2
30
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
gl = canvas.getContext('webgl', attributes) || canvas.getContext('experimental-webgl', attributes);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
this.gl = gl;
|
|
31
|
-
|
|
32
|
-
this.state = {
|
|
33
|
-
activeTextureUnit: 0,
|
|
34
|
-
textureUnits: [],
|
|
35
|
-
flipY: false,
|
|
36
|
-
viewport: { width: 0, height: 0 },
|
|
37
|
-
pixelRatio,
|
|
38
|
-
width: 0,
|
|
39
|
-
height: 0,
|
|
40
|
-
};
|
|
41
|
-
this.gl.state = this.state;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
render({
|
|
45
|
-
geometry,
|
|
46
|
-
program,
|
|
47
|
-
primitiveType = this.gl.TRIANGLES,
|
|
48
|
-
offset = 0,
|
|
49
|
-
count = 3
|
|
50
|
-
}) {
|
|
51
|
-
if (program.needsUpdate) {
|
|
52
|
-
program.compile();
|
|
53
|
-
}
|
|
31
|
+
this.gl = gl;
|
|
32
|
+
|
|
33
|
+
this.state = {
|
|
34
|
+
activeTextureUnit: 0,
|
|
35
|
+
textureUnits: [],
|
|
36
|
+
flipY: false,
|
|
37
|
+
viewport: { width: 0, height: 0 },
|
|
38
|
+
pixelRatio,
|
|
39
|
+
width: 0,
|
|
40
|
+
height: 0,
|
|
41
|
+
};
|
|
42
|
+
this.gl.state = this.state;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
render({
|
|
46
|
+
geometry,
|
|
47
|
+
program,
|
|
48
|
+
primitiveType = this.gl.TRIANGLES,
|
|
49
|
+
offset = 0,
|
|
50
|
+
count = 3,
|
|
51
|
+
}) {
|
|
52
|
+
if (program.needsUpdate) {
|
|
53
|
+
program.compile();
|
|
54
|
+
}
|
|
54
55
|
|
|
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
|
-
|
|
56
|
+
this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
57
|
+
|
|
58
|
+
this.gl.useProgram(program._program);
|
|
59
|
+
|
|
60
|
+
for (let attributeName in program.attributesLocations) {
|
|
61
|
+
let location = program.attributesLocations[attributeName];
|
|
62
|
+
let buffer = geometry.buffers[attributeName];
|
|
63
|
+
|
|
64
|
+
this.gl.enableVertexAttribArray(location);
|
|
65
|
+
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, buffer);
|
|
66
|
+
|
|
67
|
+
const size = 2; // 2 components per iteration
|
|
68
|
+
const type = this.gl.FLOAT; // the data is 32bit floats
|
|
69
|
+
const normalize = false; // don't normalize the data
|
|
70
|
+
const stride = 0; // 0 = move forward size * sizeof(type) each iteration to get the next position
|
|
71
|
+
const bufferOffset = 0; // start at the beginning of the buffer
|
|
72
|
+
this.gl.vertexAttribPointer(
|
|
73
|
+
location,
|
|
74
|
+
size,
|
|
75
|
+
type,
|
|
76
|
+
normalize,
|
|
77
|
+
stride,
|
|
78
|
+
bufferOffset
|
|
79
|
+
);
|
|
80
|
+
}
|
|
80
81
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
82
|
+
let textureUnit = -1;
|
|
83
|
+
|
|
84
|
+
for (let uniformName in program.uniforms) {
|
|
85
|
+
let location = program.uniformsLocations[uniformName];
|
|
86
|
+
if (location) {
|
|
87
|
+
let uniform = program.uniforms[uniformName];
|
|
88
|
+
|
|
89
|
+
if (uniform.type === "float") {
|
|
90
|
+
this.gl.uniform1f(location, uniform.value);
|
|
91
|
+
} else if (uniform.type === "vec2") {
|
|
92
|
+
this.gl.uniform2f(location, uniform.value[0], uniform.value[1]);
|
|
93
|
+
} else if (uniform.type === "vec3") {
|
|
94
|
+
this.gl.uniform3f(
|
|
95
|
+
location,
|
|
96
|
+
uniform.value[0],
|
|
97
|
+
uniform.value[1],
|
|
98
|
+
uniform.value[2]
|
|
99
|
+
);
|
|
100
|
+
} else if (uniform.type === "vec4") {
|
|
101
|
+
this.gl.uniform4f(
|
|
102
|
+
location,
|
|
103
|
+
uniform.value[0],
|
|
104
|
+
uniform.value[1],
|
|
105
|
+
uniform.value[2],
|
|
106
|
+
uniform.value[3]
|
|
107
|
+
);
|
|
108
|
+
} else if (uniform.type === "sampler2D") {
|
|
109
|
+
if (uniform.value) {
|
|
110
|
+
textureUnit = textureUnit + 1;
|
|
111
|
+
uniform.value.update(textureUnit);
|
|
112
|
+
|
|
113
|
+
this.gl.uniform1i(location, textureUnit);
|
|
114
|
+
}
|
|
105
115
|
}
|
|
106
|
-
|
|
107
|
-
this.gl.drawArrays(primitiveType, offset, count);
|
|
116
|
+
}
|
|
108
117
|
}
|
|
109
118
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
119
|
+
this.gl.drawArrays(primitiveType, offset, count);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
setPixelRatio(pixelRatio = this.state.pixelRatio) {
|
|
123
|
+
if (this.state.pixelRatio !== pixelRatio) {
|
|
124
|
+
this.state.pixelRatio = pixelRatio;
|
|
125
|
+
this.setSize();
|
|
115
126
|
}
|
|
127
|
+
}
|
|
116
128
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
129
|
+
setSize({ width = this.state.width, height = this.state.height } = {}) {
|
|
130
|
+
this.state.width = width;
|
|
131
|
+
this.state.height = height;
|
|
120
132
|
|
|
121
|
-
|
|
122
|
-
|
|
133
|
+
this.canvas.width = this.state.width * this.state.pixelRatio;
|
|
134
|
+
this.canvas.height = this.state.height * this.state.pixelRatio;
|
|
123
135
|
|
|
124
|
-
|
|
125
|
-
|
|
136
|
+
this.setViewport();
|
|
137
|
+
}
|
|
126
138
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
139
|
+
setViewport({ width = this.state.width, height = this.state.height } = {}) {
|
|
140
|
+
let w = Math.floor(width * this.state.pixelRatio);
|
|
141
|
+
let h = Math.floor(height * this.state.pixelRatio);
|
|
130
142
|
|
|
131
|
-
|
|
132
|
-
|
|
143
|
+
if (this.state.viewport.width !== w || this.state.viewport.height !== h) {
|
|
144
|
+
this.gl.viewport(0, 0, w, h);
|
|
133
145
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
}
|
|
146
|
+
this.state.viewport.width = w;
|
|
147
|
+
this.state.viewport.height = h;
|
|
137
148
|
}
|
|
149
|
+
}
|
|
138
150
|
|
|
139
|
-
|
|
140
|
-
|
|
151
|
+
destroy() {
|
|
152
|
+
let extension = this.gl.getExtension("WEBGL_lose_context");
|
|
141
153
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
154
|
+
if (extension) {
|
|
155
|
+
extension.loseContext();
|
|
145
156
|
}
|
|
157
|
+
}
|
|
146
158
|
}
|
|
147
159
|
|
|
148
160
|
export default Renderer;
|
|
@@ -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
|
});
|