1

I was trying to build a project in which a user can add a rectangle and set up a connection between them by drawing a line, that is double click on one rectangle to start and double-clicking on the other rectangle to finish the line. The rectangle can be moved anywhere in the canvas and lines should be intact.This code helps me to add the feature rectangle move I have added 2 functionality 1) Add rectangle on clicking a button 2) Save the position on clicking save. Now I want to add the lines on the canvas to connect the rectangles

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            background-color: ivory;
        }

        #canvas {
            border: 1px solid red;
        }

        #canvasimg {
            position: absolute;
            top: 10%;
            left: 52%;
            display: none;
        }
    </style>
</head>

<body>
    <h4>Drag one or more of the shapes</h4>

    <canvas id="canvas" width=300 height=300></canvas>

    <button onclick="addShape()">Add Rectangle</button>
    <button onclick="save()">Save</button>

    <script src="canvas.js"></script>

</body>

</html>

Script.js

        function save() {
        var shape = JSON.stringify(shapes, ['x', 'y', 'number'])
        console.log(shape);

        var blob = new Blob(
            [shape],
            { type: "contentType" });
        var url = window.URL.createObjectURL(blob);
        var anchor = document.createElement("a");
        anchor.href = url;
        anchor.download = "test.txt";
        anchor.click();

        window.URL.revokeObjectURL(url);
        document.removeChild(anchor);
    }

    // get canvas related references
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    var BB = canvas.getBoundingClientRect();
    var offsetX = BB.left;
    var offsetY = BB.top;
    var WIDTH = canvas.width;
    var HEIGHT = canvas.height;

    // drag related variables
    var dragok = false;
    var startX;
    var startY;

    // an array of objects that define different shapes
    var shapes = [];
    var number = 0;
    // add rectangle on click
    function addShape() {
        shapes.push({ x: 0, y: 0, width: 30, height: 30, fill: "#444444", isDragging: false, number: number });
        draw();
        number++;
    }

    // listen for mouse events
    canvas.onmousedown = myDown;
    canvas.onmouseup = myUp;
    canvas.onmousemove = myMove;

    // call to draw the scene
    draw();

    // draw a single rect
    function rect(r) {
        ctx.fillStyle = r.fill;
        ctx.fillRect(r.x, r.y, r.width, r.height);
    }

    // draw a single rect
    function circle(c) {
        ctx.fillStyle = c.fill;
        ctx.beginPath();
        ctx.arc(c.x, c.y, c.r, 0, Math.PI * 2);
        ctx.closePath();
        ctx.fill();
    }

    // clear the canvas
    function clear() {
        ctx.clearRect(0, 0, WIDTH, HEIGHT);
    }

    // redraw the scene
    function draw() {
        clear();
        // redraw each shape in the shapes[] array
        for (var i = 0; i < shapes.length; i++) {
            // decide if the shape is a rect or circle
            // (it's a rect if it has a width property)
            if (shapes[i].width) {
                rect(shapes[i]);
            } else {
                circle(shapes[i]);
            };
        }
    }


    // handle mousedown events
    function myDown(e) {

        // tell the browser we're handling this mouse event
        e.preventDefault();
        e.stopPropagation();

        // get the current mouse position
        var mx = parseInt(e.clientX - offsetX);
        var my = parseInt(e.clientY - offsetY);

        // test each shape to see if mouse is inside
        dragok = false;
        for (var i = 0; i < shapes.length; i++) {
            var s = shapes[i];
            // decide if the shape is a rect or circle               
            if (s.width) {
                // test if the mouse is inside this rect
                if (mx > s.x && mx < s.x + s.width && my > s.y && my < s.y + s.height) {
                    // if yes, set that rects isDragging=true
                    dragok = true;
                    s.isDragging = true;
                }
            } else {
                var dx = s.x - mx;
                var dy = s.y - my;
                // test if the mouse is inside this circle
                if (dx * dx + dy * dy < s.r * s.r) {
                    dragok = true;
                    s.isDragging = true;
                }
            }
        }
        // save the current mouse position
        startX = mx;
        startY = my;
    }


    // handle mouseup events
    function myUp(e) {
        // tell the browser we're handling this mouse event
        e.preventDefault();
        e.stopPropagation();

        // clear all the dragging flags
        dragok = false;
        for (var i = 0; i < shapes.length; i++) {
            shapes[i].isDragging = false;
        }
    }


    // handle mouse moves
    function myMove(e) {
        // if we're dragging anything...
        if (dragok) {

            // tell the browser we're handling this mouse event
            e.preventDefault();
            e.stopPropagation();

            // get the current mouse position
            var mx = parseInt(e.clientX - offsetX);
            var my = parseInt(e.clientY - offsetY);

            // calculate the distance the mouse has moved
            // since the last mousemove
            var dx = mx - startX;
            var dy = my - startY;

            // move each rect that isDragging 
            // by the distance the mouse has moved
            // since the last mousemove
            for (var i = 0; i < shapes.length; i++) {
                var s = shapes[i];
                if (s.isDragging) {
                    s.x += dx;
                    s.y += dy;
                }
            }

            // redraw the scene with the new rect positions
            draw();

            // reset the starting mouse position for the next mousemove
            startX = mx;
            startY = my;

        }
    }
Priyom saha
  • 630
  • 1
  • 9
  • 28
  • I don't really know ``, but I think you want to do this: https://www.tutorialspoint.com/html5/canvas_drawing_lines.htm -- You may need to calculate where the center of each rectangle is (if the centers are where you want to `moveTo()` and `lineTo()`.) – Cat Jun 08 '20 at 06:52
  • I am unable to do that. Can You please provide me with the code – Priyom saha Jun 08 '20 at 07:43
  • Sorry, I don't have any other code for that. (I don't think I've ever dealt with the `canvas` element except here on SO.) It just seemed like that tutorial was doing something very similar to what you were asking about. Maybe the guides on MDN can help as well? https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes – Cat Jun 08 '20 at 07:53

0 Answers0