1
votes

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 event listener to the canvas DOM and use the appropriate fuctions when the line input or rectangle input is selected

but it draws nothing.

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 isDrawing = false;
ctx.strokeStyle = "orange";
ctx.lineWidth = 3;


function handleRecUp() {
	isDrawing = false;
	canvas.style.cursor = "default";	
}

function handleRecMove(e) {
	if (isDrawing) {
		var mouseX = parseInt(e.clientX - offsetX);
		var mouseY = parseInt(e.clientY - offsetY);				
		
		ctx.clearRect(0, 0, canvas.width, canvas.height);
		ctx.beginPath();
		ctx.rect(startX, startY, mouseX - startX, mouseY - startY);
		ctx.stroke();
		
	}
}

function handleRecDown(e) {
	canvas.style.cursor = "crosshair";		
	isDrawing = true
	startX = parseInt(e.clientX - offsetX);
	startY = parseInt(e.clientY - offsetY);
}





function handleMouseDown(e) {
    e.preventDefault();   
    e.stopPropagation();
    
    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);
    
    isDown = true;
    startX = mouseX;
    startY = mouseY;
    
}

function handleMouseMove(e) {
    e.preventDefault();   
    e.stopPropagation();
    
    if (!isDown) {
        return;
    }
    
    redrawStoredLines();
    
    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);
    
    // draw the current line
    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(mouseX, mouseY);
    ctx.stroke()
    
}


function handleMouseUp(e) {
    e.preventDefault();   
    e.stopPropagation();
    
    isDown = false;
    
    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);
    
    storedLines.push({
        x1: startX,
        y1: startY,
        x2: mouseX,
        y2: mouseY
    });
    
    redrawStoredLines();
    
}

function handleMouseOut(e) {
    e.preventDefault();   
    e.stopPropagation();
    
    if(!isDown){return;}
    
    isDown = false;
    
    var mouseX = parseInt(e.clientX - offsetX);
    var mouseY = parseInt(e.clientY - offsetY);
    
    storedLines.push({
        x1: startX,
        y1: startY,
        x2: mouseX,
        y2: mouseY
    });
    
    redrawStoredLines();
    
}


function redrawStoredLines() {
    
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    
    if (storedLines.length == 0) {
        return;
    }
    
    // redraw each stored line
    for (var i = 0; i < storedLines.length; i++) {
        ctx.beginPath();
        ctx.moveTo(storedLines[i].x1, storedLines[i].y1);
        ctx.lineTo(storedLines[i].x2, storedLines[i].y2);
        ctx.stroke();
    }
}
 
    let l = document.getElementById("line");
    let c = document.getElementById("clear");
    let r = document.getElementById("rect");    

    
    
    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);
});
      
    }
    
body {
    background-color: ivory;
    padding:10px;
}
canvas {
    border:1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas" width=300 height=300></canvas><br/>
<div>        
                <input type="radio" name="shape" id="clear" value="clear" checked>Clear<br>
                
                <input type="radio" name="shape" id="line" value="line">Line<br>
                
                <input type="radio" name="shape" id="rect" value="rect">Rectangle<br>                
              </div>
2
The function handleCanvas is never called, thus no mouse event handlers are ever assigned. - Chris G
You're right I've edited the question - sylvain

2 Answers

0
votes

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

0
votes

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);

function handleRadioChanges(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;


function handleMouseDown(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;
}

function handleMouseMove(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();
    }
}


function handleMouseUp(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();
}

function handleMouseOut(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();
}


function redrawStoredLines() {

    console.log(storedLines);

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

    if (storedLines.length == 0) return;

    // redraw each stored line
    for (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);

function handleRadioChanges(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);
});