Wire react-easy-crop into CreateSpace so users can crop and zoom before uploading a space icon. Adds reusable ImageCropModal component and canvas crop utility for future use in space settings and avatar editing.
44 lines
1.1 KiB
TypeScript
44 lines
1.1 KiB
TypeScript
export interface PixelCrop {
|
|
x: number;
|
|
y: number;
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
export function cropImage(imageSrc: string, pixelCrop: PixelCrop, outputType = 'image/png'): Promise<Blob> {
|
|
return new Promise((resolve, reject) => {
|
|
const img = new Image();
|
|
img.crossOrigin = 'anonymous';
|
|
img.onload = () => {
|
|
const canvas = document.createElement('canvas');
|
|
canvas.width = pixelCrop.width;
|
|
canvas.height = pixelCrop.height;
|
|
const ctx = canvas.getContext('2d');
|
|
if (!ctx) {
|
|
reject(new Error('Failed to get canvas context'));
|
|
return;
|
|
}
|
|
ctx.drawImage(
|
|
img,
|
|
pixelCrop.x,
|
|
pixelCrop.y,
|
|
pixelCrop.width,
|
|
pixelCrop.height,
|
|
0,
|
|
0,
|
|
pixelCrop.width,
|
|
pixelCrop.height,
|
|
);
|
|
canvas.toBlob(
|
|
(blob) => {
|
|
if (blob) resolve(blob);
|
|
else reject(new Error('Canvas toBlob returned null'));
|
|
},
|
|
outputType,
|
|
);
|
|
};
|
|
img.onerror = () => reject(new Error('Failed to load image'));
|
|
img.src = imageSrc;
|
|
});
|
|
}
|