如何等待在画布中加载图像

时间:2017-02-28 18:02:53

标签: javascript angularjs html5 canvas selenium-webdriver

我的测试需要与画布中加载的图像进行交互。

但我不知道如何实现加载图像的等待。 如果我希望只有画布测试开始与它交互,那么仍然会加载图像。

我必须使用driver.sleep(),但这是一个糟糕且不可靠的解决方案。 页面代码的一部分有画布:

<canvas class='ol-unselectable' width='816' height='400' style='width: 100%; height: 100%;'></canvas>

此外,该应用程序是用Angular编写的。

浏览器中开发人员控制台中的“网络”选项卡显示在加载图像时是Img请求。

我认为,可以编写一些代码来检查在浏览器中将图像加载到画布中并通过js executor使用它。

但我不知道怎么做。请帮帮我。

UPD。我尝试构建自定义等待条件:

exports.isAllImageLoad = function isAllImageLoad(driver) {
    return new Condition('image loading', function(driver) {
        return driver.executeScript(
            'var img = new Image();' +
            'img.onload = function() { return true; };' +
            'img.onload()'
        ).then(function(result) {
            console.log('image loading: ' + result);
            return result;
        });
    });
};

并将其用于:

return driver.wait(isAllImageLoad(driver), waitTimeOut);

但是控制台告诉我img.onload()的结果是null

UPD.i尝试使用此代码:

exports.isAllImageLoad = function isAllImageLoad(driver) {
    return new Condition('image loading', function(driver) {
        return driver.executeScript(
            'var image = new Image();' +
            'function mainLoop(){' +
                'if(image.complete){' +
                    'return true;' +
                '}else{' +
                    'return false;' +
                '}' +
            '}' +
            'mainLoop();'
        ).then(function(result) {
            console.log('image loading: ' + result);
            return result;
        });
    });
};

但同样的回报null

3 个答案:

答案 0 :(得分:0)

Jef Claes在他的website

上解释得非常好
  

浏览器在脚本已经存在的情况下异步加载图像   解释和执行。如果图像没有完全加载画布   无法呈现它。

     

幸运的是,这并不难解决。我们只需要等待开始   绘图直到我们从图像收到回调,通知加载   已经完成了。
  window.addEventListener(&#34; load&#34;,draw,true);

function draw(){                                    
    var img = new Image();
    img.src = "http://3.bp.blogspot.com/_0sKGHtXHSes/TPt5KD-xQDI/AAAAAAAAA0s/udx3iWAzUeo/s1600/aspnethomepageplusdevtools.PNG";

    img.onload = function(){
        var canvas = document.getElementById('canvas');
        var context = canvas.getContext('2d');    

        context.drawImage(img, 0, 0);        
    };            
}

答案 1 :(得分:0)

您可以将所有代码放置在成功加载图片后要处理的image onload事件中。

<强>样本 (在成功加载后在画布上绘制图像)

var ctx = document.getElementById('canvas').getContext('2d');
ctx.fillStyle = 'black';
ctx.font="50px Arial";
ctx.fillText('Loading...', 300, 200);
var image = new Image();
image.src = 'https://s-media-cache-ak0.pinimg.com/originals/e9/dc/10/e9dc10141d0b4e5c9e360cc5669e65ed.jpg';
image.onload = function() {
  ctx.clearRect(0, 0, 816, 480)
  ctx.drawImage(image, 0, 0);
}
#canvas {
  background-color: lightgrey;
}
<canvas id="canvas" class="ol-unselectable" width="816" height="400" style="width: 100%; height: 100%;"></canvas>

答案 2 :(得分:0)

这是等待onload的替代方法。

当DOM完成了图像的所有操作并且已加载,或者图像加载失败时,它将信号量image.complete设置为true。

您可以使用该信号量来确定渲染图像是否安全。

var image = new Image();
image.src = "imageURI";
function mainLoop(){
     if(image.complete){
          ctx.drawImage(image,0,0,100,100);
     }else{
          ctx.fillRect(0,0,100,100); // image placeholder
     }
     requestAnimationFrame(mainLoop);
}
mainLoop();

这允许您在加载图像时继续渲染。

虽然您无法直接判断图像是否已加载或存在错误。

另一种方法是附加您自己的信号量。

var image = new Image();
image.src = "imageURI";
image.onload =  function(){this.ready=true}

并使用就绪信号量指示图像已准备好呈现。