/
canvas.ts
58 lines (55 loc) · 1.7 KB
/
canvas.ts
1
2
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
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
import { adaptDPI } from "@thi.ng/adapt-dpi";
import { isString } from "@thi.ng/checks";
import type { WeblGLCanvasOpts } from "./api/canvas";
import type { WebGLExtensionMap } from "./api/ext";
import { error } from "./error";
const defaultOpts: WebGLContextAttributes = {
alpha: true,
antialias: true,
depth: true,
premultipliedAlpha: true,
preserveDrawingBuffer: false,
stencil: false,
};
export const glCanvas = (opts: Partial<WeblGLCanvasOpts> = {}) => {
const canvas = opts.canvas
? isString(opts.canvas)
? <HTMLCanvasElement>document.getElementById(opts.canvas)
: opts.canvas
: document.createElement("canvas");
opts.width && (canvas.width = opts.width);
opts.height && (canvas.height = opts.height);
opts.autoScale !== false && adaptDPI(canvas, canvas.width, canvas.height);
opts.parent && opts.parent.appendChild(canvas);
const gl = <WebGLRenderingContext>canvas.getContext(
opts.version === 2 ? "webgl2" : "webgl",
{
...defaultOpts,
...opts.opts,
}
);
if (!gl) {
error("WebGL unavailable");
}
opts.onContextLost &&
canvas.addEventListener("webglcontextlost", opts.onContextLost);
return {
canvas,
gl,
ext: getExtensions(gl, opts.ext!),
};
};
export const getExtensions = <K extends keyof WebGLExtensionMap>(
gl: WebGLRenderingContext,
ids: K[],
required = true
): Pick<WebGLExtensionMap, K> => {
const ext: any = {};
if (ids) {
for (let id of ids) {
ext[id] = gl.getExtension(id);
required && !ext[id] && error(`extension ${id} not available`);
}
}
return ext;
};