Skip to content Skip to sidebar Skip to footer

Line And Rectangle In Canvas

I trying to create a canvas in which we can draw straight line and rectangle using mouse events in function of the selected input . I attach a mousedown, mousemove, and mouseup eve

Solution 1:

Your if structure is only executed once, so when a user clicks on something, the changes are not recorded.

Try something like this:

$("input[type=radio]").on("change", handleRadioChanges);

functionhandleRadioChanges(event){
    if (l.checked === true) {
        $("#canvas").mousedown(function (e) {
            handleMouseDown(e);
        });
        $("#canvas").mousemove(function (e) {
            handleMouseMove(e);
        });
        $("#canvas").mouseup(function (e) {
            handleMouseUp(e);
        });
        $("#canvas").mouseout(function (e) {
            handleMouseOut(e);
        });

    }

    if (c.checked === true) {
        storedLines.length = 0;
        redrawStoredLines();
    }

    if (r.checked === true) {
        $("#canvas").on('mousedown', function (e) {
            handleRecDown(e);
        }).on('mouseup', function (e) {
            handleRecUp();
        }).on('mousemove', function (e) {
            handleRecMove(e);
        });
    }
}

Complete Javascript sample with more bugfixes:

var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var canvasOffset = $("#canvas").offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var storedLines = [];
var startX = 0;
var startY = 0;
var isDown;
var type = "line"; // current type
ctx.strokeStyle = "orange";
ctx.lineWidth = 3;


functionhandleMouseDown(e) {
    e.preventDefault();
    e.stopPropagation();

    canvas.style.cursor = "crosshair";

    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);

    isDown = true;
    startX = mouseX;
    startY = mouseY;
}

functionhandleMouseMove(e) {
    e.preventDefault();
    e.stopPropagation();

    if (!isDown) return;

    redrawStoredLines();

    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);

    if(type == "rect"){
        ctx.beginPath();
        ctx.rect(startX, startY, mouseX - startX, mouseY - startY);
        ctx.stroke();
    }
    if(type == "line"){
        ctx.beginPath();
        ctx.moveTo(startX, startY);
        ctx.lineTo(mouseX, mouseY);
        ctx.stroke();
    }
}


functionhandleMouseUp(e) {
    canvas.style.cursor = "default";

    e.preventDefault();
    e.stopPropagation();

    isDown = false;

    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);

    storedLines.push({
        type: type,
        x1: startX,
        y1: startY,
        x2: mouseX,
        y2: mouseY
    });

    redrawStoredLines();
}

functionhandleMouseOut(e) {
    e.preventDefault();
    e.stopPropagation();

    if (!isDown) return;

    isDown = false;

    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);

    storedLines.push({
        type: type,
        x1: startX,
        y1: startY,
        x2: mouseX,
        y2: mouseY
    });

    redrawStoredLines();
}


functionredrawStoredLines() {

    console.log(storedLines);

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    if (storedLines.length == 0) return;

    // redraw each stored linefor (var i = 0; i < storedLines.length; i++) {
        if(storedLines[i].type == "line"){
            ctx.beginPath();
            ctx.moveTo(storedLines[i].x1, storedLines[i].y1);
            ctx.lineTo(storedLines[i].x2, storedLines[i].y2);
            ctx.stroke();
        }
        if(storedLines[i].type == "rect"){
            ctx.beginPath();
            ctx.rect(storedLines[i].x1, storedLines[i].y1, 
                storedLines[i].x2 - storedLines[i].x1, storedLines[i].y2 - storedLines[i].y1);
            ctx.stroke();
        }
    }
}




let l = document.getElementById("line");
let c = document.getElementById("clear");
let r = document.getElementById("rect");

$("input[type=radio]").on("change", handleRadioChanges);

functionhandleRadioChanges(event) {
    if(l.checked){
        type = "line";
    }
    if(r.checked){
        type = "rect";
    }
    if (c.checked === true) {
        storedLines.length = 0;
        redrawStoredLines();
    }
}

$("#canvas").mousedown(function (e) {
    handleMouseDown(e);
});
$("#canvas").mousemove(function (e) {
    handleMouseMove(e);
});
$("#canvas").mouseup(function (e) {
    handleMouseUp(e);
});

Solution 2:

Did you try fabric.js?

If not you should, very simple js library which works on canvas, you can draw rectangle, circle, line, traingle etc. with bulit in support for drag n drop, resize, rotate etc.

I created a sample for you, check here

Post a Comment for "Line And Rectangle In Canvas"