HTML5:使用 onmousemove 的 getImageData 使我在 Firefox 中的应用程序变慢

HTML5 : getImageData with onmousemove make slow my application in Firefox

我用 canvas 创建了一个 html5 小游戏。

在canvas中,有很多显示的精灵,其中一个会自动从左向右移动。其他都是静态的。

当我将鼠标移动到 canvas 上时,我在临时 canvas 中绘制所有精灵,然后使用 getImageData 找到鼠标悬停在其上的精灵。

但是 getImageData 使 Firefox 中移动的精灵变慢。

那么避免这种减速的解决方案是什么?

这是我的代码:

function getSelectedObject(array_objects)
{
    //Clear the temporary canvas :
    tmpcx.clearRect(0, 0, tmpc.width, tmpc.height);

    /*Search the right sprite object :*/
    for(var i = array_objects.length-1; i >= 0; i--)
    {
        array_objects[i].draw(tmpcx);

        imageData = tmpcx.getImageData(mouse_x, mouse_y, 1, 1);

        component = imageData.data;

        if(component[3] > 0)
        {   
            //Return the sprite object found : 
            return array_objects[i];
        }

        else
        {
            tmpcx.clearRect(0, 0, tmpc.width, tmpc.height);
        }
    }

    return false;
}


canvas.onmousemove = function(event)
{

selectedObject = getSelectedObject(array_objects);

}

不确定这样做会带来多少性能提升 - 无需清除精灵之间的温度 canvas ....在绘制精灵之前,像素是清晰的!

我引用了一个名为 checkBoundingBoxisOver 的函数 - 不确定您是否可以编写此函数,但我现在不能 - 此外,我什至不知道您的 array_objects是!!!

我认为这很简单,只需要精灵的 x、y、宽度、高度来初步检查精灵是否可能在鼠标下方,然后再进行昂贵的绘制

function getSelectedObject(array_objects) {
    //Clear the temporary canvas :
    tmpcx.clearRect(0, 0, tmpc.width, tmpc.height);
    var sprite;
    /*Search the right sprite object :*/
    for (var i = array_objects.length - 1; i >= 0; i--) {

        sprite = array_objects[i];

        if (checkBoundingBoxisOver(sprite, mouse_x, mouse_y)) {

            sprite.draw(tmpcx);
            imageData = tmpcx.getImageData(mouse_x, mouse_y, 1, 1);
            component = imageData.data;
            if (component[3] > 0) {
                return sprite;
            }
        }
    }
    return false;
}

我 运行 遇到类似的问题,从动画的每一帧的大位图中读取像素。在我的例子中,它是一张黑白图像,显示世界是水还是陆地。

即使只读取一个像素,getImageData 在 Firefox 上也非常慢。

我的解决方案是只调用一次 getImageData 并将结果存储在 imageData 变量中

    var imageData = self.context.getImageData(0,0,image.width, image.height);

然后就可以反复调用图片数据,拉出你想要的图片部分了。在我的例子中,我只需要一个像素或一种颜色,看起来像这样

    var pixelRed = this.imageData.data[(y* imageWidth * 4) + (x * 4)] == 0;

x 和 y 是不言自明的,因为像素是 4 字节值(红色、绿色、蓝色、Alpha)我需要将我的数组索引乘以 4。事实证明这对我来说非常快。

只要不是太大,使用这段代码直接从数组中抓取任何部分都非常容易。