libpag
Version:
Portable Animated Graphics
69 lines (61 loc) • 2.32 kB
text/typescript
import { CANVAS_POOL_MAX_SIZE } from '../constant';
import { isInstanceOf } from './type-utils';
import { SAFARI_OR_IOS_WEBVIEW, WORKER } from './ua';
const canvasPool = new Array<HTMLCanvasElement | OffscreenCanvas>();
export const isOffscreenCanvas = (element: any) => isInstanceOf(element, globalThis.OffscreenCanvas);
export const isCanvas = (element: any) =>
isOffscreenCanvas(element) || isInstanceOf(element, globalThis.HTMLCanvasElement);
export const getCanvas2D = (width: number, height: number) => {
let canvas = canvasPool.pop() || createCanvas2D();
if (canvas !== null) {
canvas.width = width;
canvas.height = height;
}
return canvas;
};
export const releaseCanvas2D = (canvas: HTMLCanvasElement | OffscreenCanvas) => {
if (canvasPool.length < CANVAS_POOL_MAX_SIZE) {
canvasPool.push(canvas);
}
};
const createCanvas2D = () => {
/**
* Safari browser does not support OffscreenCanvas before version 16.4.
* After version 16.4, OffscreenCanvas is supported, but type checking errors still exist for WebGL interfaces on OffscreenCanvas.
* Therefore, HTMLCanvas Element is used uniformly in Safari.
*/
if (SAFARI_OR_IOS_WEBVIEW && !WORKER) {
return document.createElement('canvas');
}
try {
const offscreenCanvas = new OffscreenCanvas(0, 0);
const context = offscreenCanvas.getContext('2d') as OffscreenCanvasRenderingContext2D;
if (typeof context.measureText === 'function') return offscreenCanvas;
return document.createElement('canvas');
} catch (err) {
return document.createElement('canvas');
}
};
export const calculateDisplaySize = (canvas: HTMLCanvasElement) => {
const styleDeclaration = globalThis.getComputedStyle(canvas, null);
const computedSize = {
width: Number(styleDeclaration.width.replace('px', '')),
height: Number(styleDeclaration.height.replace('px', '')),
};
if (computedSize.width > 0 && computedSize.height > 0) {
return computedSize;
} else {
const styleSize = {
width: Number(canvas.style.width.replace('px', '')),
height: Number(canvas.style.height.replace('px', '')),
};
if (styleSize.width > 0 && styleSize.height > 0) {
return styleSize;
} else {
return {
width: canvas.width,
height: canvas.height,
};
}
}
};