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

HTML5 : getImageData with onmousemove make slow my application in Firefox

本文关键字:Firefox 应用程序 带有 onmousemove getImageData HTML5      更新时间:2023-09-26

我用画布创建了一个小的html5游戏。

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

当我将鼠标移动到画布上时,我会在临时画布上绘制所有精灵,并使用 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);
}

不确定你会得到多少性能提升 - 无需清除精灵之间的临时画布....像素是透明的,直到在其上绘制精灵!

我引用了一个名为 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 字节值(红色、绿色、蓝色、阿尔法),我需要将数组索引乘以 4。事实证明,这对我来说非常快。

使用此代码直接从数组中获取任何部分非常容易,只要它不是太大。