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)