2016-04-19 73 views
0

私はマウスの移動イベントを使用してペン描画ツールをシミュレートしようとしています。キャンバス描画高解像度imag 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で正常に動作しています。しかし、マウスはmac上のwebViewでひどく遅れています。私は現在、iMac 5Kディスプレイでテスト中です。

また、私が気付いたことの1つは、コードがOSXが提供する新しいWebViewクラス(WKWebView)でうまく動作していることです。しかし、それは64ビットの要件を持っています。

だから私は4kまたは5kのモニターでmac webviewで作業したいと思っています。

また、同じwebViewで同じ設定でうまく動作しているwww.awwapp.comと結果を比較しています。

注:滑らかさのために、ポイントの再描画ロジックが必要です。移動ごとに盲目的にストロークすると、大雑把な描画になります。 Safariでこのコードが正常に動作しているので、私の主な関心事はWebViewの速度が遅いことです。

+0

あなたはもパフォーマンスの損失を持っています。なぜあなたはそれぞれの 'mousemove'のすべての点の間にすべてのカーブを描きますか?最後の点と新しい点の間に曲線を描くだけでいいです。 – MysterX

+0

それはそれぞれの点の後で盲目的にストロークすると荒い描画になるからです。ここに示すようにhttp://perfectionkills.com/exploring-canvas-drawing-techniques/ そして、このコードはサファリの下でうまくいきます。だから私はWebViewコードでも改善のチャンスがあると思う。 – Vrishank

答えて

2

これはキャンバスを消去せずに同じことを行い、優れたパフォーマンスを発揮します。

更新

はrequestAnimationFrameのを使用してポイントを描画するアニメーションループを追加しました。これにより、追加のスピードアップが得られる可能性があります。アニメーションループを切り替えて、それが違いを生むかどうかを確認することができます。

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; 
 
}
#can { 
 
    border: 1px solid #777777; 
 
}
<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>

+0

これはうまくいった! **キャンバスをクリアすると、費用のかかる操作が目に見える範囲まで改善されますか?または、これは高解像度の場合にすぎませんか? – Vrishank

+0

@Vrishank私はキャンバスをクリアするのはコストがかかりすぎるとは思わないが、すべてのポイントをクリアして再描画することの組み合わせがある。私はそれが役立つかどうかを確認するためにテストできるアニメーションループを追加しました。 – wolfhammer

+0

私はもう別の問題に直面しています。私はそれがいくつかの異なる範囲だと思うので、新しい質問として投稿しました。 http://stackoverflow.com/questions/36768997/kineticjs-layer-draw-taking-too-much-time-in-mac-webview-on-high-resolution-moni – Vrishank

関連する問題