React - Image Editor
This post is inspired by this npm library react-image-pan-zoom-rotate
Instead of reading this, you can simply install the library add the following lines of code to the App.js.
import PanViewer from "react-image-pan-zoom-rotate";
<PanViewer image={imageURL} alt="cool" />
Alternatively, let's try creating our own component.
I have rewritten the code using React useState hooks and styled-components, but only with rotate-left and flip horizontal or vertical options.
1. Create the styled-components wrappers
I like to use styled-components as we can pass in props.
import React, { useState } from "react";
import ReactDOM from "react-dom";
import styled from "styled-components";
const ToolBarContainer = styled.div`
position: absolute;
right: 20%;
z-index: 2;
top: 20px;
user-select: none;
border-radius: 2px;
background: rgb(255, 255, 255);
box-shadow: rgb(53 67 93 / 32%) 0px 2px 6px;
`;
const ToolBarItem = styled.div`
text-align: center;
cursor: pointer;
height: 40px;
width: 40px;
border-bottom: 1px solid rgb(204, 204, 204);
`;
// Main part is here, where we manipulate the image by passing in props to transform it's style
const ImgContainer = styled.img`
width: 500px;
transform: scaleY(${(props) => props.flipY}) scaleX(${(props) => props.flipX})
rotate(${(props) => props.rotation * 90}deg)
`;
// this is not styled-components, just for styling of the fas-icons in the toolbars box
const iconStyle = {
height: "100%",
width: "100%",
padding: 10,
boxSizing: "border-box",
};
2. Create the React Components
Define useState hooks and create a ImageContainer and ToolbarContainer.
const ImagePortal = (props) => {
const [flipX, setFlipX] = useState(1);
const [flipY, setFlipY] = useState(1);
const [rotation, setRotation] = useState(0);
const flipImageX = () => {
if (flipX === 1) {
setFlipX(-1);
}
if (flipX === -1) {
setFlipX(1);
}
};
const flipImageY = () => {
if (flipY === 1) {
setFlipY(-1);
}
if (flipY === -1) {
setFlipY(1);
}
};
const rotateLeft = () => {
if (rotation === -3) {
setRotation(0);
} else {
setRotation(rotation - 1);
}
};
const resetAll = () => {
setRotation(0);
setFlipY(1);
setFlipX(1);
};
return(
<>
<ImgContainer
src={props.image}
alt="test"
rotation={rotation}
flipX={flipX}
flipY={flipY}
/>
<ToolBarContainer>
<ToolBarItem>
<i
className="fas fa-rotate-left"
onClick={rotateLeft}
style={iconStyle}
></i>
</ToolBarItem>
<ToolBarItem>
<i
className="fa-solid fa-arrows-left-right"
onClick={flipImageX}
style={iconStyle}
></i>
</ToolBarItem>
<ToolBarItem>
<i
className="fa-solid fa-arrows-up-down"
onClick={flipImageY}
style={iconStyle}
></i>
</ToolBarItem>
<ToolBarItem>
<i className="fas fa-repeat" onClick={resetAll} style={iconStyle}></i>
</ToolBarItem>
</ToolBarContainer>
</>
);
};
export default ImagePortal;
3. Import to App.js
Now we just need to import the ImagePortal component into App.js
import styled from "styled-components";
import ImagePortal from "./components/ImagePortal";
// image url from unsplash
const imageURL =
"https://images.unsplash.com/photo-1640622300930-6e8daa98536f?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1772&q=80";
const Container = styled.div`
display: flex;
margin: auto;
width: 60vmin;
`;
const App = () => {
return (
<Container>
<ImagePortal image={imageURL} />
</Container>
);
};
export default App;
Top comments (0)