How to Create Draggable Canvas Element in React

Last updated on: by Digamber

In this comprehensive post, we will walk you through on how to create a draggable canvas element in React js using JavaScript canvas methods and function component.

From the user interfaces point of view, “draggable” refers to an element that can be quite easily moved around by the user.

It can obtained by clicking and holding the element, then dragging it to a new position from the current position.

Draggable elements are commonly used in web development for features such as sliders, drag and drop interfaces, and resizable elements.

Draggable elements can be used for a wide range of purposes, from simple sliders and resizable elements to more complex drag and drop interfaces.

However, we will use the simple approaches in a series that will guide you to implement draggable canvas rectangle in React js application.

React HTML5 Canvas Draggable Rectangle Example

We are going to break down the entire process into the several steps:

  • Step 1: Build React Project
  • Step 2: Install Bootstrap Library
  • Step 3: Create Function Component
  • Step 4: Build Canvas Draggable Component
  • Step 5: Update App Js File
  • Step 6: Start React Server

Build React Project

You have setup Node and npm in your system; it allows you to create a new React app.

To install React framework, you have to open command prompt, add the command and run the below command.

npx create-react-app my-react-app

Now, navigate to the project folder:

cd my-react-app

Install Bootstrap Library

This step is utterly optional; we are using bootstrap to design the basic layout and useful UI components.

npm install bootstrap --legacy-peer-deps

Create Function Component

Next, create a new components/, then you need to create CanvasDrag.js file.

import React from 'react'
function CanvasDrag() {
  return (
    <div></div>
  )
}
export default CanvasDrag

Build Canvas Draggable Component

The following code guides on: How to start and set the canvas context, assign dynamic dimensions and draw and drag canvas elements.

You have to open the components/CanvasDrag.js file.

import React, { useRef, useEffect } from "react";
function CanvasDrag() {
  const canvas = useRef();
  let getCtx = null;
  const canBoxes = [
    { x: 190, y: 250, w: 120, h: 70 },
    { x: 110, y: 115, w: 100, h: 70 },
  ];
  let isMoveDown = false;
  let targetCanvas = null;
  let startX = null;
  let startY = null;
  useEffect(() => {
    const canvasDimensions = canvas.current;
    canvasDimensions.width = canvasDimensions.clientWidth;
    canvasDimensions.height = canvasDimensions.clientHeight;
    getCtx = canvasDimensions.getContext("2d");
  }, []);
  useEffect(() => {
    canvasDraw();
  }, []);
  const canvasDraw = () => {
    getCtx.clearRect(
      0,
      0,
      canvas.current.clientWidth,
      canvas.current.clientHeight,
    );
    canBoxes.map((info) => fillCanvas(info));
  };
  const fillCanvas = (info, style = {}) => {
    const { x, y, w, h } = info;
    const { backgroundColor = "#D75755" } = style;
    getCtx.beginPath();
    getCtx.fillStyle = backgroundColor;
    getCtx.fillRect(x, y, w, h);
  };
  const moveableItem = (x, y) => {
    let isCanvasTarget = null;
    for (let i = 0; i < canBoxes.length; i++) {
      const block = canBoxes[i];
      if (
        x >= block.x &&
        x <= block.x + block.w &&
        y >= block.y &&
        y <= block.y + block.h
      ) {
        targetCanvas = block;
        isCanvasTarget = true;
        break;
      }
    }
    return isCanvasTarget;
  };
  const onMouseDown = (e) => {
    startX = parseInt(e.nativeEvent.offsetX - canvas.current.clientLeft);
    startY = parseInt(e.nativeEvent.offsetY - canvas.current.clientTop);
    isMoveDown = moveableItem(startX, startY);
  };
  const onMouseMove = (e) => {
    if (!isMoveDown) return;
    const mouseX = parseInt(e.nativeEvent.offsetX - canvas.current.clientLeft);
    const mouseY = parseInt(e.nativeEvent.offsetY - canvas.current.clientTop);
    const mouseStartX = mouseX - startX;
    const mouseStartY = mouseY - startY;
    startX = mouseX;
    startY = mouseY;
    targetCanvas.x += mouseStartX;
    targetCanvas.y += mouseStartY;
    canvasDraw();
  };
  const onMouseUp = (e) => {
    targetCanvas = null;
    isMoveDown = false;
  };
  const onMouseOut = (e) => {
    onMouseUp(e);
  };
  return (
    <div>
      <canvas
        onMouseDown={onMouseDown}
        onMouseMove={onMouseMove}
        onMouseUp={onMouseUp}
        onMouseOut={onMouseOut}
        ref={canvas}
      ></canvas>
    </div>
  );
}
export default CanvasDrag;

Update App Js File

The App.js file is solely responsible for creating the structure and behavior of our React application components.

Here is why, we have to register previously built component into the App.js file.

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import CanvasDrag from "./components/CanvasDrag";
function App() {
  return (
    <div className="container mt-3">
      <h2 className="mb-3">React Canvas Draggable Shapes Example</h2>
      <CanvasDrag />
    </div>
  );
}
export default App;

Start React Server

Navigate to the console, type below command and press enter to run the app.

npm start

The above command starts the app on the browser:

http://localhost:3000

How to Create Draggable Canvas Element in React

Conclusion

In conclusion, allowing elements to be draggable on a canvas can greatly enhance the user experience and interactivity of a React application.

React provides a robust framework for building interactive web applications with draggable elements on a canvas.

React’s state management system permits seamless integration of draggable components, and its reusable component system offers a flexible way for creating dynamic interfaces.

In this tutorial, we have learned how to create draggable canvas rectangle element in React js app.

positronX.io - Tamso Ma Jyotirgamaya
Digamber

A Full-stack developer with a passion to solve real world problems through functional programming.