import { UpploadEffect } from "../../effect";
import Cropper from "cropperjs";
import {
IHandlersParams,
ITemplateParams,
IUpploadFile,
} from "../../helpers/interfaces";
import {
safeListen,
fitImageToContainer,
canvasToBlob,
} from "../../helpers/elements";
type CropNum = 1 | 2 | 3 | undefined;
export default class Crop extends UpploadEffect {
name = "crop";
icon = ``;
aspectRatio = NaN;
hideAspectRatioSettings = false;
aspectRatioOptions = {
free: NaN,
square: 1,
"16:9": 16 / 9,
} as { [index: string]: number };
autoCropArea: CropNum = 1;
viewMode: CropNum = 1;
originalFile: IUpploadFile = { blob: new Blob() };
constructor({
aspectRatio,
aspectRatioOptions,
hideAspectRatioSettings,
autoCropArea,
viewMode,
}: {
aspectRatio?: number;
aspectRatioOptions?: { [index: string]: number };
hideAspectRatioSettings?: boolean;
autoCropArea?: CropNum;
viewMode?: CropNum;
} = {}) {
super();
if (aspectRatio) this.aspectRatio = aspectRatio;
if (aspectRatioOptions) this.aspectRatioOptions = aspectRatioOptions;
if (autoCropArea) this.autoCropArea = autoCropArea;
if (viewMode) this.viewMode = viewMode;
if (hideAspectRatioSettings)
this.hideAspectRatioSettings = hideAspectRatioSettings;
}
template = ({ file, translate }: ITemplateParams) => {
const image = URL.createObjectURL(file.blob);
this.originalFile = file;
return `
${
!this.aspectRatio && !this.hideAspectRatioSettings
? `
${Object.keys(this.aspectRatioOptions)
.map(
(aspectRatio, index) => `
`
)
.join("")}
`
: ""
}
`;
};
handlers = (params: IHandlersParams) => {
const cropperElement = params.uppload.container.querySelector(
".uppload-cropping-element img"
) as HTMLImageElement | null;
const originalFile = this.originalFile;
const type =
originalFile.type &&
["image/jpeg", "image/webp"].indexOf(originalFile.type) !== -1
? originalFile.type
: "image/png";
if (cropperElement) {
fitImageToContainer(params, cropperElement).then(() => {
const cropper = new Cropper(cropperElement, {
aspectRatio: this.aspectRatio,
autoCropArea: this.autoCropArea,
viewMode: this.viewMode,
ready() {
canvasToBlob(cropper.getCroppedCanvas(), type).then((blob) => {
originalFile.blob = blob;
params.next(originalFile);
});
},
cropend() {
canvasToBlob(cropper.getCroppedCanvas(), type).then((blob) => {
originalFile.blob = blob;
params.next(originalFile);
});
},
});
const aspectRatios = params.uppload.container.querySelectorAll(
"input[name='crop-aspect-ratio']"
);
aspectRatios.forEach((aspectRatio) => {
safeListen(aspectRatio, "change", () => {
const selectedAspectRatio = params.uppload.container.querySelector(
"input[name='crop-aspect-ratio']:checked"
);
if (selectedAspectRatio) {
cropper.setAspectRatio(
this.aspectRatioOptions[
selectedAspectRatio.getAttribute("data-name") || "free"
]
);
canvasToBlob(cropper.getCroppedCanvas(), type).then((blob) => {
originalFile.blob = blob;
params.next(originalFile);
});
}
});
});
});
}
};
}