简体   繁体   中英

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. But the mouse is severely lagging in webView on mac. I am currently testing it with iMac 5K display.

Also one thing I noticed, the code is working fine (no lag) with newer webView class OSX provided (WKWebView). But it has a 64 bit requirement.

So I want it to be working on mac webview with 4k or 5k monitor.

Also I am comparing results with www.awwapp.com which is working good with same setup in the same 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?

This does the same thing without clearing the canvas and should perform better.

update

Added an animation loop to draw points using 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> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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