type Drawable = ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement;
const newCanvas = () => document.createElement('canvas');
export function cropTo(image: Drawable, size: number, flipped = false, canvas: HTMLCanvasElement = newCanvas()) {
let width: number;
let height: number;
// If ImageData
if (image instanceof ImageData) {
width = image.width;
height = image.height;
}
// If image, bitmap, or canvas
else if (image instanceof HTMLImageElement || image instanceof HTMLCanvasElement) {
width = image.width;
height = image.height;
}
// If video element
else if (image instanceof HTMLVideoElement) {
width = image.videoWidth;
height = image.videoHeight;
} else {
throw new Error("Unsupported Drawable type");
}
const min = Math.min(width, height);
const scale = size / min;
const scaledW = Math.ceil(width * scale);
const scaledH = Math.ceil(height * scale);
const dx = scaledW - size;
const dy = scaledH - size;
canvas.width = canvas.height = size;
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
// Handle ImageData separately
if (image instanceof ImageData) {
ctx.putImageData(image, ~~(dx / 2) * -1, ~~(dy / 2) * -1); // Adjust this if needed
} else {
ctx.drawImage(image, ~~(dx / 2) * -1, ~~(dy / 2) * -1, scaledW, scaledH);
}
if (flipped) {
ctx.scale(-1, 1);
ctx.drawImage(canvas, size * -1, 0);
}
return canvas;
}