Draggable Rectangle on Canvas using React
Today we’ll show you how to create a draggable rectangle on canvas using React. In the previous article we have explained you, how to draw a rectangle on canvas using React.
You can also find the more article related to the Canvas in ReactJS.
Step to create draggable rectangle on Canvas
- Create a react application
- Draw a rectangle on canvas
- Add functionality to manage draggable rectangle
- Output
1. Create a react application
Let’s create a react application using `create-react-app`. Refer to this link for more information. Run the following command to set up a react app.
npx create-react-app draggable-rectangle-canvas-react
2. Draw a rectangle on canvas
In the next step, we have to write a logic to draw a rectangle on canvas using React. Check out the below article for more information.
Draw a rectangle on Canvas using React
3. Add functionality to manage draggable rectangle
- First, we have to define a few variables to manage the click, drag element and position of the drag element.
- Create a separate method `draw()` to draw an element. Here we have to clear the canvas context before we draw an element.
- Create a new method `hitBox` to identify the click event in the rectangle.
- Handle the several mouse events such as `onMouseDown`, `onMouseMove`, `onMouseUp` and `onMouseOut` to manage drag functionality.
Check out the following code.
App.js
import React, { useRef, useEffect } from 'react';
function App() {
const canvas = useRef();
let ctx = null;
const boxes = [
{ x: 200, y: 220, w: 100, h: 50 },
{ x: 100, y: 120, w: 100, h: 50 }
]
let isDown = false;
let dragTarget = null;
let startX = null;
let startY = null;
// initialize the canvas context
useEffect(() => {
// dynamically assign the width and height to canvas
const canvasEle = canvas.current;
canvasEle.width = canvasEle.clientWidth;
canvasEle.height = canvasEle.clientHeight;
// get context of the canvas
ctx = canvasEle.getContext("2d");
}, []);
useEffect(() => {
draw();
}, []);
// draw rectangle
const draw = () => {
ctx.clearRect(0, 0, canvas.current.clientWidth, canvas.current.clientHeight);
boxes.map(info => drawFillRect(info));
}
// draw rectangle with background
const drawFillRect = (info, style = {}) => {
const { x, y, w, h } = info;
const { backgroundColor = 'black' } = style;
ctx.beginPath();
ctx.fillStyle = backgroundColor;
ctx.fillRect(x, y, w, h);
}
// identify the click event in the rectangle
const hitBox = (x, y) => {
let isTarget = null;
for (let i = 0; i < boxes.length; i++) {
const box = boxes[i];
if (x >= box.x && x <= box.x + box.w && y >= box.y && y <= box.y + box.h) {
dragTarget = box;
isTarget = true;
break;
}
}
return isTarget;
}
const handleMouseDown = e => {
startX = parseInt(e.nativeEvent.offsetX - canvas.current.clientLeft);
startY = parseInt(e.nativeEvent.offsetY - canvas.current.clientTop);
isDown = hitBox(startX, startY);
}
const handleMouseMove = e => {
if (!isDown) return;
const mouseX = parseInt(e.nativeEvent.offsetX - canvas.current.clientLeft);
const mouseY = parseInt(e.nativeEvent.offsetY - canvas.current.clientTop);
const dx = mouseX - startX;
const dy = mouseY - startY;
startX = mouseX;
startY = mouseY;
dragTarget.x += dx;
dragTarget.y += dy;
draw();
}
const handleMouseUp = e => {
dragTarget = null;
isDown = false;
}
const handleMouseOut = e => {
handleMouseUp(e);
}
return (
<div class="App">
<h3>Draggable Rectangle on Canvas - <a href="http://www.cluemediator.com" target="_blank" rel="noopener noreferrer">Clue Mediator</a></h3>
<canvas onmousedown={handleMouseDown} onmousemove={handleMouseMove} onmouseup={handleMouseUp} onmouseout={handleMouseOut} ref={canvas}></canvas>
</div>
);
}
export default App;
4. Output
Run the application and check the output in the browser.
Output - Draggable Rectangle on Canvas using React - Clue Mediator
That’s it for today.
Thank you for reading. Happy Coding..!!