画布绘制滞后高分辨率imac webView

时间:2016-04-19 11:56:12

标签: javascript macos performance webview

我正在尝试使用鼠标移动事件模拟钢笔绘图工具。

elCanvas.on("mousedown", function(e){
            moving = true;
            var position = getPos(e);
            points = [];
            points.push(position);
            ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
            ctx.beginPath();
            ctx.moveTo(position.x, position.y);
}

elCanvas.on("mousemove", function(e){
            if (moving) {
                var curr = getPos(e);
                points.push(curr);
                ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

                var p1 = points[0];
                var p2 = points[1];
                ctx.beginPath();
                ctx.moveTo(p1.x, p1.y);

                for (var i = 1, len = points.length; i < len; i++) {
                     var midPoint = midPointBtw(p1, p2);
                     ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
                     p1 = points[i];
                     p2 = points[i + 1];
                }
                ctx.lineTo(p1.x, p1.y);
                ctx.stroke();
}

现在这段代码在Safari中正常运行。但是鼠标在macView上的webView严重滞后。我目前正在用iMac 5K显示器进行测试。

还有一件事我注意到,代码工作正常(没有延迟)与更新的webView类OSX提供(WKWebView)。但它有64位的要求。

所以我希望它能用4k或5k显示器在mac webview上工作。

此外,我将结果与www.awwapp.com进行比较,该网站在同一个webView中使用相同的设置。

注意:为了平滑,我需要重绘整个逻辑点。如果我们在每次移动后盲目地划动,将导致粗略绘制。由于这段代码在Safari中运行良好,我主要担心的是为什么webView中的代码很慢?

1 个答案:

答案 0 :(得分:2)

如果不清除画布,这会做同样的事情并且应该表现得更好。

<强>更新

使用requestAnimationFrame添加了一个动画循环来绘制点。这可能会带来额外的加速。您可以切换动画循环以查看它是否有所作为。

&#13;
&#13;
var elCanvas = document.getElementById('can');
var ctx = elCanvas.getContext('2d');
var moving = false;
var points = [];

function getPos(evt) {
  var rect = elCanvas.getBoundingClientRect();
  return {
    x: evt.clientX - rect.left,
    y: evt.clientY - rect.top
  };
}

function midPointBtw(p1, p2) {
  return {
    x: p1.x + (p2.x - p1.x) / 2,
    y: p1.y + (p2.y - p1.y) / 2
  };
}

elCanvas.addEventListener("mousedown", function(e) {
  moving = true;
  var position = getPos(e);
  points = [];
  points.push(position);
  ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
  ctx.beginPath();
  ctx.moveTo(position.x, position.y);
});

elCanvas.addEventListener("mousemove", function(e) {
  if (moving) {
    // collect point
    var curr = getPos(e);
    points.push(curr);
    if (ani_status == "off") {
      // no animaion loop.. draw here.
      draw();
    } else {
      requestAnimationFrame(draw);
    }
  }
});
  
function draw() {
    if (points.length < 2) return;
    // Draw all the points we've collected since the last draw.
    var p1 = points[0];
    var p2 = points[1];
    ctx.beginPath();
    ctx.moveTo(p1.x, p1.y);

    for (var i = 1, len = points.length; i < len; i++) {
      var midPoint = midPointBtw(p1, p2);
      ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
      p1 = points[i];
      p2 = points[i + 1];
    }
  
    ctx.lineTo(p1.x, p1.y);
    ctx.stroke();
  
    // Keep the last point for next draw.
    points = [points[points.length-1]]
}

var ani_status = "off";

function toggleAni(value) {
  ani_status = value;
}
&#13;
#can {
  border: 1px solid #777777;
}
&#13;
<form>
animation-loop<br>
on<input type=radio name=ani-loop value='on'
onclick='toggleAni(this.value)'>
off<input type=radio name=ani-loop value='off' checked onclick='toggleAni(this.value)'></form>

<canvas id='can' width=600 height=400></canvas>
&#13;
&#13;
&#13;