【问题标题】:HTML5 canvas not redrawing in Chrome after calling clearRect调用 clearRect 后,HTML5 画布未在 Chrome 中重绘
【发布时间】:2013-03-12 09:12:19
【问题描述】:

我已经盯着这个太久了,需要一些帮助。我有以下简化的小提琴示例,它适用于 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 调用在清除画布后不起作用。有什么我想念的想法吗?

【问题讨论】:

    标签: javascript html canvas


    【解决方案1】:

    问题是您正在清除画布,然后您正在等待加载图像,当图像加载时,动画再次运行,清除画布并等待新图像加载。因此,您总是在调用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";
    };
    

    注意

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

    【讨论】:

    • 所以另一件奇怪的事情是,如果我忘记了清晰的部分,而是为图像设置动画,它会继续绘制新图像(您会一遍又一遍地看到相同图像的轨迹)。如果我继续创建新的图像对象,这甚至可以在 Chrome 中使用。我只是好奇为什么突然清除会破坏它?
    • jsfiddle.net/xHMyN/1 例如。如果创建多个图像是问题,为什么在这里创建多个图像不会失败?
    • @JeremyArmstrong 我想我有问题,请检查答案
    • 我需要重新考虑如何在绘制图像之前对图像进行排队,但我认为这是我需要的答案。感谢您的帮助。
    • @JeremyArmstrong 大多数游戏都会预先缓存图像,你有这么多不可行吗?我不认为解决方案是在每个动画帧中动态加载它们......
    猜你喜欢
    • 2013-07-31
    • 1970-01-01
    • 2011-12-25
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多