Skip to content

Commit

Permalink
support input props
Browse files Browse the repository at this point in the history
  • Loading branch information
zhaoyao91 committed Oct 21, 2019
1 parent 404054a commit 15cdd11
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 9 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ Options with `*` prefix are recommended to set.

### Common Options

- `inputOptions` ? : object
- \* `maxWidth` = Infinity
- \* `maxHeight` = Infinity
- `mimeType` = 'image/jpeg'
- `quality` ? : number
- `cropOptions` ? : object
- \* `aspect` ? : number
- `maxZoom` ? : number
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-image-cropper",
"version": "0.2.4",
"version": "0.3.0",
"description": "Select, crop, preview, edit, all in one!",
"keywords": [
"react-bootstrap",
Expand Down
49 changes: 42 additions & 7 deletions src/CropImageModal.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { useRef } from "react";
import { Button, Modal } from "react-bootstrap";
import React, { useEffect, useRef, useState } from "react";
import { Button, Modal, Spinner } from "react-bootstrap";
import useObjectURL from "use-object-url";

import CropImagePanel from "./CropImagePanel";
import { getCroppedFile } from "./utils";
import { getCroppedFile, limitImageSize } from "./utils";

export default function CropImageModal({
show,
Expand All @@ -13,10 +13,18 @@ export default function CropImageModal({
onConfirm, // (croppedFile) => void
onCancel, // void => void
onRemove, // void => void
inputOptions = {}, // {maxWidth, maxHeight, mimeType, quality}
cropOptions = {}, // {aspect, maxZoom}
outputOptions = {}, // {maxWidth, maxHeight, mimeType, quality}
displayOptions = {} // {title, removeButtonText, confirmButtonText, showRemoveButton, showConfirmButton}
}) {
const {
maxWidth: inputMaxWidth = Infinity,
maxHeight: inputMaxHeight = Infinity,
mimeType: inputMimeType = "image/jpeg",
quality: inputQuality
} = inputOptions;

const { aspect, maxZoom } = cropOptions;

const {
Expand All @@ -35,6 +43,28 @@ export default function CropImageModal({
} = displayOptions;

const imageUrl = useObjectURL(imageFile);

const [resizedUrl, setResizedUrl] = useState();
const [resizing, setResizing] = useState(false);

useEffect(() => {
if (imageUrl) {
setResizing(true);
limitImageSize({
imageUrl,
maxWidth: inputMaxWidth,
maxHeight: inputMaxHeight,
mimeType: inputMimeType,
quality: inputQuality
})
.then(url => setResizedUrl(url))
.catch(err => console.error(err))
.finally(() => setResizing(false));
} else {
setResizedUrl();
}
}, [imageUrl]);

const cropResultRef = useRef();

function handleCropComplete(croppedArea, croppedAreaPixels) {
Expand All @@ -43,7 +73,7 @@ export default function CropImageModal({

function handleConfirm() {
getCroppedFile(
imageUrl,
resizedUrl,
cropResultRef.current.croppedAreaPixels,
maxWidth,
maxHeight,
Expand All @@ -57,10 +87,15 @@ export default function CropImageModal({
<Modal.Header closeButton>
<Modal.Title>{title}</Modal.Title>
</Modal.Header>
<Modal.Body style={{ minHeight: "50vh" }}>
{imageUrl && (
<Modal.Body style={{ height: "50vh" }}>
{resizing && (
<div className="d-flex justify-content-center align-items-center h-100">
<Spinner animation="grow" />
</div>
)}
{resizedUrl && (
<CropImagePanel
imageUrl={imageUrl}
imageUrl={resizedUrl}
value={value}
onChange={onChange}
onCropComplete={handleCropComplete}
Expand Down
2 changes: 2 additions & 0 deletions src/HiddenCropper.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import CropImageModal from "./CropImageModal";
export default function HiddenCropper({
triggerRef, // ref.current.trigger()
onCropped, // (croppedFile) => void
inputOptions = {},
cropOptions = {},
outputOptions = {},
displayOptions = {}
Expand Down Expand Up @@ -59,6 +60,7 @@ export default function HiddenCropper({
onChange={setCropState}
onConfirm={handleConfirm}
onCancel={handleCancel}
inputOptions={inputOptions}
cropOptions={cropOptions}
outputOptions={outputOptions}
displayOptions={{ ...displayOptions, showRemoveButton: false }}
Expand Down
4 changes: 4 additions & 0 deletions src/ImageCropper.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import CropImageModal from "./CropImageModal";
export default function ImageCropper({
fileRef,
onChange,
inputOptions,
cropOptions,
outputOptions,
displayOptions,
Expand Down Expand Up @@ -85,6 +86,7 @@ export default function ImageCropper({
onConfirm={handleConfirm}
onCancel={handleCancel}
onRemove={handleRemove}
inputOptions={inputOptions}
cropOptions={cropOptions}
outputOptions={outputOptions}
displayOptions={displayOptions}
Expand All @@ -102,6 +104,7 @@ export function ControlledImageCropper({
onConfirm,
onCancel,
onRemove,
inputOptions = {},
cropOptions = {},
outputOptions = {},
displayOptions = {},
Expand Down Expand Up @@ -143,6 +146,7 @@ export function ControlledImageCropper({
onConfirm={onConfirm}
onCancel={onCancel}
onRemove={onRemove}
inputOptions={inputOptions}
cropOptions={cropOptions}
outputOptions={outputOptions}
displayOptions={displayOptions}
Expand Down
31 changes: 30 additions & 1 deletion src/utils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// 以下工具复制自 https://codesandbox.io/s/q8q1mnr01w
// 以下工具部分复制自 https://codesandbox.io/s/q8q1mnr01w
// 略有修改

export async function createImageDomFromUrl(url) {
Expand All @@ -10,6 +10,35 @@ export async function createImageDomFromUrl(url) {
});
}

export async function limitImageSize({
imageUrl,
maxWidth,
maxHeight,
mimeType,
quality
}) {
const image = await createImageDomFromUrl(imageUrl);

if (image.width <= maxWidth && image.height <= maxHeight) {
return imageUrl;
}

const { width, height } = limitSize(
image.width,
image.height,
maxWidth,
maxHeight
);

const canvas = document.createElement("canvas");
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext("2d");
ctx.drawImage(image, 0, 0, width, height);

return canvas.toDataURL(mimeType, quality);
}

/**
* This function was adapted from the one in the ReadMe of https://github.com/DominicTobias/react-image-crop
* @param {string} imageUrl - Image File url
Expand Down

0 comments on commit 15cdd11

Please sign in to comment.