50 lines
1.5 KiB
JavaScript
50 lines
1.5 KiB
JavaScript
const CAN_USE_OFFSCREEN = typeof OffscreenCanvas === 'function';
|
|
|
|
function createSurface(width, height) {
|
|
const w = Math.max(1, Math.ceil(width));
|
|
const h = Math.max(1, Math.ceil(height));
|
|
if (CAN_USE_OFFSCREEN) {
|
|
const canvas = new OffscreenCanvas(w, h);
|
|
const ctx = canvas.getContext('2d');
|
|
if (ctx) return { canvas, ctx, width: w, height: h };
|
|
}
|
|
if (typeof document !== 'undefined') {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = w;
|
|
canvas.height = h;
|
|
const ctx = canvas.getContext('2d');
|
|
if (ctx) return { canvas, ctx, width: w, height: h };
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function drawCachedStaticLayer(targetCtx, shared, layerId, key, x, y, width, height, build) {
|
|
if (!targetCtx || !shared || typeof build !== 'function') return false;
|
|
if (!shared._staticLayers) shared._staticLayers = new Map();
|
|
let layer = shared._staticLayers.get(layerId);
|
|
const w = Math.max(1, Math.ceil(width));
|
|
const h = Math.max(1, Math.ceil(height));
|
|
const needsRebuild = !layer
|
|
|| layer.key !== key
|
|
|| layer.width !== w
|
|
|| layer.height !== h;
|
|
|
|
if (needsRebuild) {
|
|
layer = createSurface(w, h);
|
|
if (!layer) return false;
|
|
layer.key = key;
|
|
layer.ctx.save();
|
|
try {
|
|
layer.ctx.setTransform(1, 0, 0, 1, 0, 0);
|
|
layer.ctx.clearRect(0, 0, w, h);
|
|
build(layer.ctx);
|
|
} finally {
|
|
layer.ctx.restore();
|
|
}
|
|
shared._staticLayers.set(layerId, layer);
|
|
}
|
|
|
|
targetCtx.drawImage(layer.canvas, x, y);
|
|
return true;
|
|
}
|