有没有办法提高JavaScript的onmousemove事件的更新速度?



我正在尝试用HTML和JavaScript制作一个简单的绘图脚本。我通过在整个窗口上创建一个div 来做到这一点,然后通过让该div 的 onmousemove 事件调用 updateFunc() 来跟踪鼠标位置,以便当您按住左键单击时,会创建一个红色的圆形div 元素并在每次更新后附加以类似于画笔。

问题是 onmousemove 事件的更新非常慢,以至于如果您太突然地移动光标,每个创建的div 元素之间都会有很大的间隙。理想情况下,创建一条线,无论您移动光标的速度如何,都应该尽可能平滑。有没有办法使用这种方法来做到这一点,或者我应该尝试其他方法?

<div onmousemove="updateFunc();" id="background" style="position:fixed;width:100%;height:100%;z-index:100%;" onmousedown="isDown = true;" onmouseup="isDown = false;"></div>
<div id="test1" style="width:10px;height:10px;background-color:red;"></div>
<script>
var test1 = document.getElementById("test1");
var isDown = false;
function updateFunc() {
    x = event.clientX;
    y = event.clientY;
    document.getElementById("test1").style.left = (x - (Number(test1.style.width.slice(0,-2)) / 2)) + "px";
    document.getElementById("test1").style.top = (y - (Number(test1.style.height.slice(0,-2)) / 2)) + "px";
    if (isDown) {
        var div = document.createElement("div");
        div.style.position = "absolute";
        div.style.top = (y - (Number(test1.style.height.slice(0,-2)) / 2)) + "px";
        div.style.left = (x - (Number(test1.style.width.slice(0,-2)) / 2)) + "px";
        div.style.backgroundColor = "red";
        div.style.width = "10px";
        div.style.height = "10px";
        div.style.borderRadius = "200px 200px 200px 200px";
        var body = document.querySelector("body");
        body.appendChild(div);
    }
}
</script>

无法加速浏览器触发mousemove事件。
您可以使用一些基本的三角函数,在创建两个点后,只需将两个点与缺少的 DIV 连接即可......等等,我刚才说的是DIV吗?
DOM 不应该用于制作绘画应用程序(好吧,除非您正在创建一个 32x32 图标生成器,但甚至比......使用canvas .入门真的很容易。
不过,Canvas 将有同样的"问题"。它会用一条线连接您的鼠标移动点,但如果您使用鼠标的速度很快 - 这条线将看起来像多边形的边缘。在这种情况下,一些贝塞尔曲线或二次曲线可能会有所帮助。最终结果将是一个更快,更符合用户体验的应用程序。用户还可以在创意耗尽后下载自己的绘图(另存为图像)。

下面是一个使用 canvasquadraticCurveTo 的演示:

var pen = {
  color: "rgba(255, 0, 0, 1.0)", // Set desired color
  size: 3                        // Set desired size
};
var pts = [];
var isDown = false;
var isTouch = false;
var cvs = document.getElementById('canvas');
var cvs2 = document.createElement('canvas');
var ctx = cvs.getContext('2d');
var ctx2 = cvs2.getContext('2d');
function setCvsSize() {
  cvs.width = cvs2.width = document.documentElement.clientWidth;
  cvs.height = cvs2.height = document.documentElement.clientHeight;
}
function penDown(ev) {
  ev.preventDefault();
  isTouch = ev.type === "touchstart";
  ev = isTouch ? ev.touches[0] : ev;
  isDown = true;
  pts.push({
    x: ev.clientX,
    y: ev.clientY
  });
  drawPoints();
}
function penMove(ev) {
  ev.preventDefault();
  ev = isTouch ? ev.touches[0] : ev;
  if (isDown) {
    ctx.clearRect(0, 0, cvs.width, cvs.height);
    ctx.drawImage(cvs2, 0, 0); // Draw to inmemory cvs2
    pts.push({
      x: ev.clientX,
      y: ev.clientY
    });
    drawPoints();
  }
}
function penUp(ev) {
  ev.preventDefault();
  isDown = isTouch = false;
  pts = [];
  // Save state to in-memory cvs2
  ctx2.clearRect(0, 0, cvs.width, cvs.height);
  ctx2.drawImage(cvs, 0, 0);
}
function clear() {
  ctx.clearRect(0, 0, cvs.width, cvs.height);
  ctx2.clearRect(0, 0, cvs.width, cvs.height);
}
function drawPoints() {
  var i = 0;
  var i2 = pts.length > 1 ? 1 : 0;
  ctx.beginPath();
  ctx.lineWidth = pen.size;
  ctx.lineJoin = 'round';
  ctx.lineCap = 'round';
  ctx.moveTo(pts[0].x, pts[0].y);
  for (; i < pts.length - i2; i++) {
    ctx.quadraticCurveTo(
      pts[i].x,
      pts[i].y,
      (pts[i].x + pts[i + i2].x) / 2,
      (pts[i].y + pts[i + i2].y) / 2
    );
  }
  ctx.strokeStyle = pen.color;
  ctx.stroke();
  ctx.closePath();
}
// EVENTS
cvs.addEventListener('touchstart', penDown);
cvs.addEventListener('mousedown', penDown);
cvs.addEventListener('touchmove', penMove);
cvs.addEventListener('mousemove', penMove);
cvs.addEventListener('touchend', penUp);
cvs.addEventListener('mouseup', penUp);
window.addEventListener('resize', setCvsSize);
// INIT
setCvsSize();
*{margin: 0;}
#canvas {
  display: block;
}
<canvas id='canvas'></canvas>

最新更新