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.
1 | 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
andonMouseOut
to manage drag functionality.
Check out the following code.
App.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | 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 className="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.
That’s it for today.
Thank you for reading. Happy Coding..!!