mousemove / mouseclick事件后html 5画布缓慢更新的问题

时间:2011-09-28 13:49:58

标签: html html5 canvas mouseevent setinterval

我最近一直在用html 5进行实验,特别是画布对象。

我似乎遇到了鼠标事件的一些问题。

该程序是随机更改的不同颜色背景的面部网格。顶部有一个云形状,我用作剪切区域,只能看到云下网格的各个部分。 (想想形状奇特的火炬束)

问题在于我尝试使用鼠标移动云区域,并且无法使用mousemove或mouseclick事件顺利更新。在循环颜色看起来可以继续时,似乎需要一两帧才能赶上。

我试过了:

  • 删除随机颜色以加速。
  • 仅使用简单的形状进行裁剪。
  • 设置setInterval函数以每1ms更新一次

可以看到在这里运行 - http://jsfiddle.net/mXrNk/14/

任何帮助将不胜感激。可能遗漏了一些明显的东西。

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

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

</script>

1 个答案:

答案 0 :(得分:3)

<强> Live Demo

我使用setTimeout而不是setInterval。当使用间隔时,如果它尝试在完成之前运行该功能,则事件将建立并且仍然继续尝试并在呼叫仍在建立时运行。

然后超时只会调用该函数一次,然后您可以在函数底部设置另一个超时以再次调用自身。这样做可以确保函数已经完成,并且不会导致等待处理的调用累积。

另外看一下这篇文章,

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

关于缓存你的路径。实际上,我打赌的西蒙·萨里斯(Simon Sarris)会突然出现并看到这个问题。