画布中的线条和矩形

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了画布中的线条和矩形相关的知识,希望对你有一定的参考价值。

我尝试创建一个画布,在其中我们可以使用所选输入功能的鼠标事件绘制直线和矩形。

我将mousedown,mousemove和mouseup事件监听器附加到画布DOM,并在选择行输入或矩形输入时使用相应的功能

但它没有任何吸引力。

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>
答案

您的if结构只执行一次,因此当用户点击某些内容时,不会记录更改。

尝试这样的事情:

$("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);
        });
    }
}

完整的javascript示例以及更多错误修正:

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

另一答案

你尝试过fabric.js吗?

如果不是你应该,非常简单的js库在画布上工作,你可以绘制矩形,圆形,线形,三角形等内置支持拖拽,调整大小,旋转等。

我为你创建了一个样本,check here

以上是关于画布中的线条和矩形的主要内容,如果未能解决你的问题,请参考以下文章

如何让用户在 WPF 中使用画布绘制线条

photoshop如何改变矩形线条颜色

canvas绘制线条怎么改变线条长度

如何使所有绘制的(矩形、圆形、线条、多边形)可拖动?纯JS

从 Typescript 中的 For 循环在画布上绘制线条不会呈现

对圆形和线条使用相同的不透明度和颜色,但在画布上显示奇怪的结果[重复]