Html5画布绘制:快速移动鼠标取消线之前,它击中画布的边缘

html5 canvas drawing: fast motion with mouse cancels line before it hits the edge of the canvas

本文关键字:边缘 取消 移动 绘制 布绘制 Html5 鼠标      更新时间:2023-09-26

到目前为止,这个应用程序工作得很好,除非线条画得非常快,离开了画布的边缘,否则线条就不会画到画布的边缘。它少了一个零件。

我正在尝试解决这个问题:

canvasVar.addEventListener ('mouseout', clearPathIfMouseCursorLeavesCanvasFunc);

 function clearPathIfMouseCursorLeavesCanvasFunc(e){
 contextVar.beginPath(); // clears the path so buttonpresses dont connect the line
 mouseButtonHeld = false;

我已经尝试了一些事情,如添加一个settimeout();,但没有工作到目前为止。我不知道是什么原因,我一直在搜索,如果别人有这个问题和修复它,但我遇到的每个画布绘图应用程序都有同样的问题。

这是非常重要的,这条线被绘制到边缘,并且用户的鼠标运动被识别,而不仅仅是一条线到鼠标离开画布的最后一个坐标。

这个问题已经困扰我好几天了。非常感谢你的帮助!整个代码:

// Varibale declaration
var canvasVar = document.getElementById('canvasHtmlElement');
var contextVar = canvasVar.getContext('2d');
var pointRadiusVar = 0.5;
var mouseButtonHeld = false;
var pointsArrPosition = 0;
//Arrays
var pointsArr = [];
// Varibale declration end
//canvas setup
canvasVar.width = window.innerWidth;
canvasVar.height = window.innerHeight;
//canvas setup end
//resize fix
window.onresize = function() {
    var tempImageVar = contextVar.getImageData(0, 0, canvasVar.width, canvasVar.height);
    canvasVar.width = window.innerWidth;
    canvasVar.height = window.innerHeight;
    contextVar.putImageData(tempImageVar, 0, 0);
  }
  //resize fix end
//functions
// Objects
function pointObject() {
  this.x = 0;
  this.y = 0;
  this.fill = '#444444';
}
function addFilledCircleFunc(x, y) {
  //alert('works1');
  var filledCircle = new pointObject;
  filledCircle.x = x;
  filledCircle.y = y;
  pointsArr.push(filledCircle);
  contextVar.lineWidth = 10; //pointRadiusVar * 2; // Line Width
  contextVar.lineTo(pointsArr[pointsArrPosition].x, pointsArr[pointsArrPosition].y);
  contextVar.stroke();
  //contextVar.beginPath();
  contextVar.fillRect(filledCircle.x, filledCircle.y, 1, 1);
  //contextVar.arc(filledCircle.x, filledCircle.y, pointRadiusVar, 0, Math.PI * 2);
  //contextVar.fill();
  //contextVar.lineWidth = 0.5;
  //contextVar.stroke();
  //contextVar.beginPath();
  pointsArrPosition++;
  //contextVar.moveTo(pointsArr[pointsArrPosition].x, pointsArr[pointsArrPosition].y);
  //alert(pointsArr[0].x);
}
//Objects end
// create circle on mouse clicked point while mousebutton is held
var addPointToCanvasVar = function(e) {
  if (mouseButtonHeld) {
    //alert('addpointfunc');
    addFilledCircleFunc(e.clientX, e.clientY);
  }
};
// MAKE SURE that lines work when drawn over the edge of the canvas
function clearPathIfMouseCursorLeavesCanvasFunc(e) {
  contextVar.beginPath(); // clears the path so buttonpresses dont connect the line
  mouseButtonHeld = false;
}
// end
// mouse Up/Down functions
var mouseDownVar = function(e) {
  //alert("mouseDown");
  addPointToCanvasVar(e); // add point on first click, not just when mousebutton is held
  mouseButtonHeld = true;
}
var mouseUpVar = function() {
  //alert("mouseUp");
  mouseButtonHeld = false;
  contextVar.beginPath(); // clears the path so buttonpresses dont connect the line
}
// mouse Up/Down Switch end
//functions end
//listeners
canvasVar.addEventListener('mousemove', addPointToCanvasVar);
canvasVar.addEventListener('mouseup', mouseUpVar);
canvasVar.addEventListener('mousedown', mouseDownVar);
canvasVar.addEventListener('mouseout', clearPathIfMouseCursorLeavesCanvasFunc);
//listeners end
<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>Confident Drawing</title>
</head>
<body style="margin: 0">
  <canvas id="canvasHtmlElement" style="display: block;">
    Your Browser does not support Canvas! Please update to a newer version.
  </canvas>
  <script src="main_0.06.js"></script>
</body>
</html>

如果你不明白我的意思:运行代码片段并在退出画布时尽可能快地画一条线

当您在边缘上快速画一条线时,线过早地在边缘附近结束的原因是,当鼠标仍在画布中并且刚好短于边缘时,最后一个mousemove事件被触发,而下一个mousemove事件在您的鼠标离开画布后被触发。要解决这个问题,只要在mouseout事件触发后,从画布中最后记录的鼠标位置到画布外的位置绘制线即可。

您可以添加一个新的全局变量mousePosition并将其初始化为{x:0,y:0}。每次mousemove触发时(无论何时调用addPointToCanvasVar),将e.clientXe.clientY记录到mousePosition。然后,当mouseout触发时(无论何时调用clearPathIfMouseCursorLeavesCanvasFunc),绘制从mousePosition到当前e.clientXe.clientY位置的其余部分。这将完成到画布边缘的行。