Zooming means enlarging an image so that the details in the image become more visible and apparent. Zooming a picture has many wide applications ranging from zooming through a camera lens to zooming on a photo on the internet, e.t.c.
On the other hand, Rotate is an image processing feature that allows us to turn an image in a clockwise or counterclockwise direction.
In this post, we'll learn how to zoom and rotate the image with React-image-zoom package, Cloudinary, and React.js.
React-image-zooom is an npm package that will allow users to zoom in on images. This component has minimal styling footprint. In addition, we can pass in custom class names and id props that'll enable us to customise the package to fit our design needs.
Cloudinary is a platform on which we can upload, store, manage, transform, and deliver images and videos for web and mobile applications.
Sandbox
The complete project is on CodeSandbox. Fork and run it to quickly get started.
https://codesandbox.io/embed/focused-pare-kx8jdl?fontsize=14&hidenavigation=1&theme=dark
Prerequisites
This post requires the following:
- Experience with JavaScript and react.js
- Installation of Node.js
- A Cloudinary account. Signup is free!
Setups and Installations
We will run the following command in the terminal to create a new React.js application:
1npx create-react-app zoom-rotate-app
The above command bootstraps a react application in ****the zoom-rotate folder.
Next, we'll navigate into the project directory and install some dependencies:
1cd zoom-rotate # to navigate into the project directory
Navigate to the src
directory and delete all the files except App.js
and index.js
Next, we'll install the following npm packages:
- react-image-zooom, so we can access the zoom component in a React environment.
- @cloudinary/url-gen to add cloudinary transformations and also generate a URL.
- react-icons to give us access to icons for rotating our image.
1npm install react-image-zooom @cloudinary/url-gen react-icons
or
1yarn add react-image-zooom @cloudinary/url-gen react-icons
Next, we'll install the bootstrap library with the following command to handle our styles.
1npm install react-bootstrap bootstrap
Next, we'll log in to cloudinary, navigate to the samples folder and navigate to people and tag a few images.
Create a tag name and click on the Update button.
Next, we'll provide our details in this URL format and query it to get our cloudinary tagged assets:
1https://res.cloudinary.com/<cloud-name>/<type>/list/<tag-name>.json
Next, we’ll remove restrictions on Image list in cloudinary. Navigate to settings (the gear icon), click on the Security tab and uncheck Resource List
under Restricted media types.
Scroll down to save settings.
Next, import the following line of code inside the pages/index.js
file:
1import "bootstrap/dist/css/bootstrap.min.css";
Your index.js
should look like this:
1//index.js2import React from 'react';3import ReactDOM from 'react-dom/client';4import App from './App';5import "bootstrap/dist/css/bootstrap.min.css";67const root = ReactDOM.createRoot(document.getElementById('root'));8 root.render(9 <React.StrictMode>10 <App />11 </React.StrictMode>12 );
Building the Zoom Effect
Now, clean up the App.js
file and update it with the following lines of code :
1import "./App.css";2import ImageZoom from "react-image-zooom";3import { useState, useEffect } from "react";45const App = () => {6 const [imageData, setImageData] = useState(null);78 const baseURL = "https://res.cloudinary.com/<cloud-name>/image";910 const getImages = async () => {11 const res = await fetch(12 "https://res.cloudinary.com/<cloud-name>/image/list/<tag-name>.json"13 );14 const data = await res.json();15 setImageData(data);16 };171819return (20 <div className="App">21 <h1>ZOOM and Roatate Images in React.js</h1>22 <div className="gallery">23 {imageData &&24 imageData.resources.map((item) => {25 const { format, public_id, version, type } = item;26 return (27 <div key={version} className="gallery-img">28 <ImageZoom29 src={`${baseURL}/${type}/v${version}/${public_id}.${format}`}30 alt="Zoom-images"31 zoom="300"32 />33 </div>34 );35 })}36 </div>37 </div>38);39};40export default App;
In the snippets above, we:
- Imported
ImageZoom
from "react-image-zooom" and useState and useEffect from “react”. - Created
imageData
state constant with useState hook and created a baseURL constant. - Created the
getImages()
function to fetch the tagged assets from Cloudinary and update the imageData state. - Looped through the
imageData
, generated a URL for the images, and used theImageZoom
component and display them.
We would see our images rendered with zoom-in and zoom-out functionalities in the browser.
Building the Rotate Effect
First, let's head to Cloudinary media library, and double click on any image asset and copy the image directory.
Next, update the App.js
with the following snippets:
1//App.js2...3import { Cloudinary } from "@cloudinary/url-gen";4import { byAngle } from "@cloudinary/url-gen/actions/rotate";5import { BsArrowClockwise, BsArrowCounterclockwise } from "react-icons/bs";67const App = () => {8 ...9 const [imageURL, setImageURL] = useState();10 const [rotateValue, setRotateValue] = useState(0);1112 const rotateImages = () => {13 const cld = new Cloudinary({14 cloud: {15 cloudName: "cloud-name",16 },17 });18 const rotateImg = cld19 .image("image directory here")20 .rotate(byAngle(rotateValue));21 setImageURL(rotateImg.toURL());22 };2324 ...2526useEffect(() => {27 ...28 rotateImages();29});3031return (32 <div className="App">33 <h1>Zoom and Roatate Images in React.js</h1>34 <div className="gallery">35 ...36 </div>3738 <div className="rotate">39 <img src={imageURL} alt="snow-boy" width={500} height={500} />40 <div className="controls m-3">41 <button42 onClick={() => setRotateValue(rotateValue - 90)}43 className="m-1 btn-primary"44 >45 <BsArrowCounterclockwise />46 </button>47 <button48 onClick={() => setRotateValue(rotateValue + 90)}49 className="m-1 btn-primary"50 >51 <BsArrowClockwise />52 </button>53 </div>54 </div>55 </div>56 );57};58export default App;
In the snippets above, we:
- Imported Cloudinary and
byAngle
rotate actions from "@cloudinary/url-gen." - Imported Clockwise and CounterClockwise arrows from react-icons and created
imageURL
androtateValue
state constants. - Created the
rotateImages()
function and inside it, instantiated a new instance of Cloudinary and passed our cloud name. - Created the
rotateImg
constant, targeted our image asset, called therotate()
andbyAngle()
functions on it. Then passed therotateValue
state and updated theimageURL
state. - Rendered the
imageURL
in an img tag and rendered the Counterclockwise and Clockwise arrows with anonClick()
function that will decrease or increase therotateValue
state.
Your App.js
should look like this:
1//App.js2import "./styles.css";3import ImageZoom from "react-image-zooom";4import { useState, useEffect } from "react";5import { Cloudinary } from "@cloudinary/url-gen";6import { byAngle } from "@cloudinary/url-gen/actions/rotate";7import { BsArrowClockwise, BsArrowCounterclockwise } from "react-icons/bs";89const App = () => {10 const [imageData, setImageData] = useState(null);11 const [imageURL, setImageURL] = useState();12 const [rotateValue, setRotateValue] = useState(0);13 const rotateImages = () => {14 const cld = new Cloudinary({15 cloud: {16 cloudName: "cloud-name"17 }18 });1920 const rotateImg = cld21 .image("image directory here")22 .rotate(byAngle(rotateValue));23 setImageURL(rotateImg.toURL());24 };2526 const baseURL = "https://res.cloudinary.com/<cloud-name>/image";27 const getImages = async () => {28 const res = await fetch(29 "https://res.cloudinary.com/<cloud-name>/image/list/<tag-name>.json"30 );31 const data = await res.json();32 setImageData(data);33 };3435useEffect(() => {36 getImages();37 rotateImages();38});3940return (41 <div className="App">42 <h1>Zoom and Rotate Images in React.js</h1>43 <div className="gallery">44 {imageData &&45 imageData.resources.map((item) => {46 const { format, public_id, version, type } = item;47 return (48 <div key={version} className="gallery-img">49 <ImageZoom50 src={`${baseURL}/${type}/v${version}/${public_id}.${format}`}51 alt="Zoom-images"52 zoom="300"53 />54 </div>55 );56 })}57 </div>58 <div className="rotate">59 <img src={imageURL} alt="snow-boy" width={500} height={500} />60 <div className="controls m-3">61 <button62 onClick={() => setRotateValue(rotateValue - 90)}63 className="m-1 btn-primary"64 >65 <BsArrowCounterclockwise />66 </button>67 <button68 onClick={() => setRotateValue(rotateValue + 90)}69 className="m-1 btn-primary"70 >71 <BsArrowClockwise />72 </button>73 </div>74 </div>75 </div>76 );77};78export default App;
We will have the zoom and rotate functionalities working on the images in the browser as expected.
Conclusion
In this post, we discussed how to implement zoom and rotating image functionalities using cloudinary, React-image-zooom and React.
Resources
The following resource might be helpful: