Skip to content

Commit b5c7b9b

Browse files
author
time-to-program
committed
crop image before uploading
1 parent 6fc37e0 commit b5c7b9b

File tree

10 files changed

+331
-73
lines changed

10 files changed

+331
-73
lines changed

package-lock.json

Lines changed: 78 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
"@testing-library/user-event": "^13.5.0",
99
"react": "^18.2.0",
1010
"react-dom": "^18.2.0",
11+
"react-easy-crop": "^4.5.1",
12+
"react-image-crop": "^10.0.8",
1113
"react-scripts": "5.0.1",
1214
"web-vitals": "^2.1.4"
1315
},

public/index.html

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@
2424
work correctly both with client-side routing and a non-root public URL.
2525
Learn how to configure a non-root public URL by running `npm run build`.
2626
-->
27+
<link rel="preconnect" href="https://fonts.googleapis.com" />
28+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
29+
<link
30+
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@400;500;600;700;800&display=swap"
31+
rel="stylesheet"
32+
/>
33+
2734
<title>React App</title>
2835
</head>
2936
<body>

src/App.css

Lines changed: 0 additions & 38 deletions
This file was deleted.

src/App.js

Lines changed: 84 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,90 @@
1-
import logo from './logo.svg';
2-
import './App.css';
1+
import React, { useState } from "react";
2+
import FileInput from "./components/FileInput";
3+
import ImageCropper from "./components/ImageCropper";
34

45
function App() {
6+
const [image, setImage] = useState("");
7+
const [currentPage, setCurrentPage] = useState("choose-img");
8+
const [imgAfterCrop, setImgAfterCrop] = useState("");
9+
10+
// Invoked when new image file is selected
11+
const onImageSelected = (selectedImg) => {
12+
setImage(selectedImg);
13+
setCurrentPage("crop-img");
14+
};
15+
16+
// Generating Cropped Image When Done Button Clicked
17+
const onCropDone = (imgCroppedArea) => {
18+
const canvasEle = document.createElement("canvas");
19+
canvasEle.width = imgCroppedArea.width;
20+
canvasEle.height = imgCroppedArea.height;
21+
22+
const context = canvasEle.getContext("2d");
23+
24+
let imageObj1 = new Image();
25+
imageObj1.src = image;
26+
imageObj1.onload = function () {
27+
context.drawImage(
28+
imageObj1,
29+
imgCroppedArea.x,
30+
imgCroppedArea.y,
31+
imgCroppedArea.width,
32+
imgCroppedArea.height,
33+
0,
34+
0,
35+
imgCroppedArea.width,
36+
imgCroppedArea.height
37+
);
38+
39+
const dataURL = canvasEle.toDataURL("image/jpeg");
40+
41+
setImgAfterCrop(dataURL);
42+
setCurrentPage("img-cropped");
43+
};
44+
};
45+
46+
// Handle Cancel Button Click
47+
const onCropCancel = () => {
48+
setCurrentPage("choose-img");
49+
setImage("");
50+
};
51+
552
return (
6-
<div className="App">
7-
<header className="App-header">
8-
<img src={logo} className="App-logo" alt="logo" />
9-
<p>
10-
Edit <code>src/App.js</code> and save to reload.
11-
</p>
12-
<a
13-
className="App-link"
14-
href="https://reactjs.org"
15-
target="_blank"
16-
rel="noopener noreferrer"
17-
>
18-
Learn React
19-
</a>
20-
</header>
53+
<div className="container">
54+
{currentPage === "choose-img" ? (
55+
<FileInput setImage={setImage} onImageSelected={onImageSelected} />
56+
) : currentPage === "crop-img" ? (
57+
<ImageCropper
58+
image={image}
59+
onCropDone={onCropDone}
60+
onCropCancel={onCropCancel}
61+
/>
62+
) : (
63+
<div>
64+
<div>
65+
<img src={imgAfterCrop} className="cropped-img" />
66+
</div>
67+
68+
<button
69+
onClick={() => {
70+
setCurrentPage("crop-img");
71+
}}
72+
className="btn"
73+
>
74+
Crop
75+
</button>
76+
77+
<button
78+
onClick={() => {
79+
setCurrentPage("choose-img");
80+
setImage("");
81+
}}
82+
className="btn"
83+
>
84+
New Image
85+
</button>
86+
</div>
87+
)}
2188
</div>
2289
);
2390
}

src/App.test.js

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/components/FileInput.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React, { useRef } from "react";
2+
3+
function FileInput({ onImageSelected }) {
4+
const inputRef = useRef();
5+
6+
const handleOnChange = (event) => {
7+
if (event.target.files && event.target.files.length > 0) {
8+
const reader = new FileReader();
9+
reader.readAsDataURL(event.target.files[0]);
10+
reader.onload = function (e) {
11+
onImageSelected(reader.result);
12+
};
13+
}
14+
};
15+
16+
const onChooseImg = () => {
17+
inputRef.current.click();
18+
};
19+
20+
return (
21+
<div>
22+
<input
23+
type="file"
24+
accept="image/*"
25+
ref={inputRef}
26+
onChange={handleOnChange}
27+
style={{ display: "none" }}
28+
/>
29+
30+
<button className="btn" onClick={onChooseImg}>
31+
Choose Image
32+
</button>
33+
</div>
34+
);
35+
}
36+
37+
export default FileInput;

0 commit comments

Comments
 (0)