简体   繁体   English

画布画图滞后于高分辨率imac webView

[英]canvas drawing Lag on High resolution imac webView

I am trying to simulate a pen drawing tool using mouse move events. 我正在尝试使用鼠标移动事件来模拟钢笔绘图工具。

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();
}

Now this code is working fine in Safari. 现在,此代码在Safari中可以正常工作。 But the mouse is severely lagging in webView on mac. 但是鼠标在Mac上的webView中严重滞后。 I am currently testing it with iMac 5K display. 我目前正在iMac 5K显示器上对其进行测试。

Also one thing I noticed, the code is working fine (no lag) with newer webView class OSX provided (WKWebView). 我还注意到的一件事是,使用提供的较新的webView类OSX(WKWebView),代码可以正常工作(无延迟)。 But it has a 64 bit requirement. 但是它有64位要求。

So I want it to be working on mac webview with 4k or 5k monitor. 所以我希望它可以在带有4k或5k显示器的mac webview上运行。

Also I am comparing results with www.awwapp.com which is working good with same setup in the same webView. 另外,我正在将结果与www.awwapp.com进行比较,该结果在相同的webView中使用相同的设置效果很好。

Note: The whole points redrawing logic is necessary for me for smoothness. 注意:为了平滑起见,整点重画逻辑对我来说是必需的。 If we stroke blindly after each move, it will result in rough drawing. 如果我们在每次移动后都盲目地抚摸,将导致绘制粗糙。 And as this code is working fine in Safari, my main concern is why is it slow in webView? 由于此代码在Safari中可以正常工作,因此我主要担心的是为什么在webView中它运行缓慢?

This does the same thing without clearing the canvas and should perform better. 这无需清除画布即可完成相同的操作,并且应表现得更好。

update 更新

Added an animation loop to draw points using requestAnimationFrame. 添加了动画循环以使用requestAnimationFrame绘制点。 This may give an additional speedup. 这可以提供额外的加速。 You can toggle the animation loop to see if it makes a difference. 您可以切换动画循环以查看它是否有所不同。

 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM