MyRedland/js/functions.js

136 lines
3.1 KiB
JavaScript

"use strict";
import React, { useState, useRef } from "react";
import ReactCrop, {
centerCrop,
makeAspectCrop,
PixelCrop,
} from "react-image-crop";
import "react-image-crop/src/ReactCrop.scss";
export async function blobImgCrop(image, crop) {
const canvas = document.createElement("canvas");
canvasPreview(image, canvas, crop);
const blob = await toBlob(canvas);
if (!blob) {
console.error("Failed to create blob");
return "";
}
return blob;
}
function toBlob(canvas) {
return new Promise((resolve) => {
canvas.toBlob(resolve);
});
}
export async function canvasPreview(image, canvas, crop) {
const ctx = canvas.getContext("2d");
if (!ctx) {
throw new Error("No 2d context");
}
const scaleX = image.naturalWidth / image.width;
const scaleY = image.naturalHeight / image.height;
// devicePixelRatio slightly increases sharpness on retina devices
// at the expense of slightly slower render times and needing to
// size the image back down if you want to download/upload and be
// true to the images natural size.
const pixelRatio = window.devicePixelRatio;
// const pixelRatio = 1
canvas.width = Math.floor(crop.width * scaleX * pixelRatio);
canvas.height = Math.floor(crop.height * scaleY * pixelRatio);
ctx.scale(pixelRatio, pixelRatio);
ctx.imageSmoothingQuality = "high";
const cropX = crop.x * scaleX;
const cropY = crop.y * scaleY;
const centerX = image.naturalWidth / 2;
const centerY = image.naturalHeight / 2;
ctx.save();
// 5) Move the crop origin to the canvas origin (0,0)
ctx.translate(-cropX, -cropY);
// 4) Move the origin to the center of the original position
ctx.translate(centerX, centerY);
// 1) Move the center of the image to the origin (0,0)
ctx.translate(-centerX, -centerY);
ctx.drawImage(
image,
0,
0,
image.naturalWidth,
image.naturalHeight,
0,
0,
image.naturalWidth,
image.naturalHeight
);
ctx.restore();
}
export function AvatarCropper(props) {
const [crop, setCrop] = React.useState({
unit: "%",
x: 10,
y: 10,
width: 80,
height: 80,
});
if (props["onStart"]) {
props["onStart"](crop);
}
return React.createElement(
ReactCrop,
{
aspect: 1,
crop: crop,
onChange: (c) => {
setCrop(c);
if (props["onChange"]) props["onChange"](c);
},
minWidth: 50,
minHeight: 50,
onComplete: (local_crop, pcrop) => {
if (props["onComplete"]) {
props["onComplete"](local_crop);
}
},
},
React.createElement("img", {
src: props.src,
onLoad: (e) => {
const { naturalWidth: width, naturalHeight: height } = e.currentTarget;
const crop_local = centerCrop(
makeAspectCrop(
{
width: 50,
height: 50,
},
1,
width,
height
),
width,
height
);
setCrop(crop_local);
console.log(props["onLoad"]);
if (props["onLoad"]) {
props["onLoad"](crop_local);
}
},
})
);
}