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
|
export const detect2dCanvasBlockOnCanvas = (canvas: HTMLCanvasElement, resetDimensions = true, canvasOpts: CanvasRenderingContext2D | CanvasRenderingContext2DSettings = {
desynchronized: true,
alpha: true,
willReadFrequently: false,
// @ts-ignore type is incomplete
colorType: 'float16' as const,
colorSpace: 'display-p3' as const,
}): null | Error => {
const dimensions = resetDimensions ? [canvas.width, canvas.height] as const : [0, 0] as const;
const [w, h] = [255, 255];
const checks = 32;
const ctx = canvasOpts instanceof CanvasRenderingContext2D && canvasOpts && canvasOpts.canvas.width >= 256 && canvasOpts.canvas.height >= 256 ? canvasOpts : (() => {
[canvas.width, canvas.height] = [w, h];
return canvas.getContext('2d', canvasOpts) as CanvasRenderingContext2D | null
})();
if (ctx) {
try {
// make sure we have canvas support
ctx.fillStyle = '#0099ff';
ctx.fillRect(0, 0, w, h);
for (let i = 0; i < checks; i++) {
const data = ctx.getImageData(i % w, i % h, 1, 1).data;
if (
data[0] !== 0 ||
data[1] !== 153 ||
data[2] !== 255 ||
data[3] !== 255
) {
if (resetDimensions) [canvas.width, canvas.height] = dimensions;
return new Error("Canvas Data doesn't match written data.");
}
}
ctx.clearRect(0, 0, w, h);
} catch (error) {
if (resetDimensions) [canvas.width, canvas.height] = dimensions;
return new Error('No canvas support', {
cause: error
});
}
} else {
if (resetDimensions) [canvas.width, canvas.height] = dimensions;
return new Error('No canvas support: ctx is undefined.');
}
return null;
}
export const checkFor2dCanvasSupport = () => detect2dCanvasBlockOnCanvas(document.createElement('canvas'), false)
|