调用clearRect后,HTML5画布不会在Chrome中重绘

时间:2013-03-12 00:06:51

标签: javascript html5 canvas

我一直盯着这个太久了,需要一些帮助。我有以下简化的小提琴示例,适用于IE,但不适用于Chrome(没有错误,只是在Chrome中清除画布后没有重绘图像):

http://jsfiddle.net/JrLh7/3/

var myApp = {};
// redraw function that will be called during init and then will loop.
myApp.redrawFunction = function() {
    window.requestAnimationFrame(myApp.redrawFunction);
    // clear canvas (not needed in this simplified example, but I need it in my real app)
    myApp.drawingContext.clearRect(0, 0, myApp.canvas.width, myApp.canvas.height);
    // draw an image.
    var myImage = new Image();
    myImage.onload = function() {
        myApp.drawingContext.drawImage(myImage, 0, 0);
    };
    myImage.src= "http://www.w3.org/html/logo/img/mark-word-icon.png";
};
// initialize
$(function () {
    // setup the animation frame objects.
    window.requestAnimationFrame = window.requestAnimationFrame
        || window.mozRequestAnimationFrame
        || window.webkitRequestAnimationFrame
        || window.msRequestAnimationFrame;
    window.cancelAnimationFrame = window.CancelAnimationFrame
        || window.CancelRequestAnimationFrame
        || window.mozCancelAnimationFrame
        || window.mozCancelRequestAnimationFrame
        || window.msCancelAnimationFrame
        || window.msCancelRequestAnimationFrame
        || window.webkitCancelAnimationFrame
        || window.webkitCancelRequestAnimationFrame;
    // get canvas references.
    myApp.canvas = $("canvas")[0];
    myApp.drawingContext = myApp.canvas.getContext("2d");
    $(myApp.canvas).css("background-color", "#999999");
    // update canvas size to fill screen.
    myApp.canvas.width = $(window).width();
    myApp.canvas.height = $(window).height();
    $(window).resize(function (){
        myApp.canvas.width = $(window).width();
        myApp.canvas.height = $(window).height();
    });
    // start redraw loop
    myApp.redrawFunction();
});

如果你在IE 10中打开这个小提琴,它可以工作(你看到一个标志)。如果您在Chrome中打开它,则会看到一个空白画布,显示清除画布后我的drawImage调用无效。我缺少什么想法?

1 个答案:

答案 0 :(得分:3)

问题在于您正在清除画布,然后等待图像加载,当图像加载时,动画再次运行,清除画布并等待加载新图像。因此,在调用clearRect后,您总是会立即看到画布状态,因为当您调用drawImage时,动画例程将再次启动,然后您才有可能看到drawImage()的结果和你会看到clearRect()的结果。

解决方案是在图像准备好绘制之前不要清除画布。 http://jsfiddle.net/JrLh7/6/

var myApp = {};
// redraw function that will be called during init and then will loop.
myApp.redrawFunction = function() {
    // Don't clear the canvas here, it will be empty until the onload handler is called 
    var myImage = new Image();
    myImage.onload = function() {
        // Clear canvas and immediately paint the image
        myApp.drawingContext.clearRect(0, 0, myApp.canvas.width, myApp.canvas.height);
        myApp.drawingContext.drawImage(myImage, 0, 0);
        // Then you should ask for another frame after you've finished painting the canvas
       window.requestAnimationFrame(myApp.redrawFunction);
    };
    myImage.src= "http://www.w3.org/html/logo/img/mark-word-icon.png";
};

注意

拥有异步的动画例程并没有多大意义。如果是这样,至少在完成绘制画布之前不应该请求新的动画帧。