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

时间:2019-02-03 04:59:06

标签: javascript

我正在尝试用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>

1 个答案:

答案 0 :(得分:2)

无法 加速 浏览器触发mousemove事件。
您可以使用一些基本的三角函数,在创建两个点之后,只需将两个点与缺少的DIV连接起来...等等,我只是说过DIV吗?
使用canvas不能将DOM用于绘制应用程序(嗯,除非您要创建32x32 favicon生成器,否则……)。入门非常容易
画布将具有相同的“问题”。它会 将您的鼠标移动点与一条线连接起来,但是如果您的鼠标速度很快,则该线将看起来像多边形的边缘。在这种情况下,一些贝塞尔曲线或二次曲线可能会有所帮助。最终结果将是一个更快,更UX体验的应用程序。一旦创造性地用尽,用户还可以下载自己的图形(另存为图像)。

这是一个使用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>