开发者

Issue with slow updating of html 5 canvas after mousemove / mouseclick event

开发者 https://www.devze.com 2023-04-09 05:18 出处:网络
I have recently been experimenting for the first time with html 5 and specifically the canvas object.

I have recently been experimenting for the first time with html 5 and specifically the canvas object.

I seem to be having some issue with mouse events.

The program is a grid of faces with different coloured backgrounds randomly changed. There is a cloud shape on top that I am using as a clipping region to be able to see only the parts of the grid under the cloud. (Think oddly shaped torch beam)

The issue is that I am trying to move the cloud region with the mouse and it does not update smoothly with either mousemove or mouseclick events. Seems to take a frame or two to catch up while the cycling colours appear to carry on.

I have tried:

  • Removing the random colours for speedup.
  • Using only a simple shape for clipping.
  • Setting the setInterval function to update every 1ms

Can be seen running here - http://jsfiddle.net/mXrNk/14/

Any help would be appreciated. Probably missing something obvious.

<script>

const FPS = 60;
var myimg = new Image();

window.addEventListener('click', clicked, true);

var mouseX = 170;
var mouseY = 80;

window.onload = init;

function init() {

    canvas = document.getElementById('myCanvas');
    context = canvas.getContext('2d');

    myimg.src = "smile.png";

    setInterval(draw, 1000/FPS);

}

function draw() {

    context.clearRect(0,0,canvas.width,canvas.height);
    // draw cloud
    context.beginPath(); // begin custom shape
    context.moveTo(mouseX, mouseY);
    context.bezierCurveTo(mouseX-40, mouseY+20, mouseX-40, mouseY+70, mouseX+60, mouseY+70);
    context.bezierCurveTo(mouseX+80, mouseY+100, mouseX+150, mouseY+100, mouseX+170, mouseY+70);
    context.bezierCurveTo(mouseX+250, mouseY+70, mouseX+250, mouseY+40, mouseX+220, mouseY+20);
    context.bezierCurveTo(mouseX+260, mouseY-40, mouseX+200, mouseY-50, mouseX+170, mouseY-30);
    context.bezierCurveTo(mouseX+150, mouseY-75, mouseX+80, mouseY-60, mouseX+80, mouseY-30);
    context.bezierCurveTo(mouseX+30, mouseY-75, mouseX-20, mouseY-60, mouseX, mouseY);
    context.closePath(); // complete custom shape
    context.lineWidth = 5;
    context.strokeStyle = "#0000ff";
    context.stroke();

    context.save();
    context.clip();

    for (i = 0; i<7; i++) {
        for (j = 0; j < 13; j++) {
            context.strokeRect(j*myimg.width,  i*myimg.height, myimg.width, myimg.height);
            context.fillStyle = rndColor();
            context.fillRect(j*myimg.width,  i*myimg.height, myimg.width, myimg.height);
            context.drawImage(myimg, j*myimg.width, i*myimg.height);
            context.fillStyle = "black";
            context.font = "italic 10pt Arial ";
            context.fillText((i*13)+j, j*myimg.width+5,i*myimg.width+15);
        }
    }   

    context.restore();

}

function rndColor() {
    return '#' + ('00000' + (Math.random() * 16777216 << 0).toString(16)).substr(开发者_Go百科-6);
}

function clicked(e) {
    mouseX = e.pageX;
    mouseY = e.pageY;
}

</script>


Live Demo

I used setTimeout rather than setInterval. When using an interval if it tries to run the function before its finished the events will build up and still continue to try and run while the calls are still building up.

A timeout however will only call the function once, then you can just set another timeout at the bottom of the function to call itself again. Doing it that way ensures the function has completed, and doesn't cause a buildup of calls waiting to be processed.

Also take a look at this article,

https://simonsarris.com/increasing-performance-by-caching-paths-on-canvas/

Its about caching your paths. Its actually by Simon Sarris who I bet will pop in and see this question as well.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号