HTML5画布没有更新:浏览器错误或我做错了什么?

时间:2012-04-16 15:58:32

标签: javascript html html5 canvas

我有一些HTML 5代码,首先是两个黑色画布,然后通过为每一行画一条红线,一次更新一行画布。它应该看起来像一个红色的窗帘落在黑色背景上。

奇怪的是,起初它看起来像是随机行(比如5%)被跳过并留下黑色。我以为我有一个bug。但后来我注意到,如果我调整浏览器窗口大小,黑线全部变为红色。那么我认为这是某种浏览器重绘的错误。然后我注意到Chrome和Safari都有这种行为。

那么你认为这两种浏览器都有相同的错误,或者我做错了什么?

有趣的是,如果两幅画布都使用style =“width:100%; height:100%”,则此问题就会消失。

<html>
<table>
    <tr>
        <td><canvas id="myCanvas1" style="width:100%; height:100%"></canvas></td>
        <td><canvas id="myCanvas2" style="width:200px; height:400px"></canvas></td>
    </tr>
</table>
<script type="text/javascript">
    var canvases = [document.getElementById("myCanvas1"), document.getElementById("myCanvas2")];

    for(var i = 0; i < canvases.length; i++) {
        var canvas = canvases[i];
        var ctx = canvas.getContext("2d");
        ctx.fillStyle = "black";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
    }

    function updateRow(rowNum) { 

        var done = true;
        for(var i = 0; i < canvases.length; i++) {
            var canvas = canvases[i];

            if(rowNum >= canvas.height) {
                return;
            }
            done = false;

            var ctx = canvas.getContext("2d");

            var imageDataForRow = ctx.getImageData(0, rowNum, canvas.width, 1);

            for(var offset = 0; offset < imageDataForRow.data.length; offset += 4) {
                imageDataForRow.data[offset] = 255;
                imageDataForRow.data[offset + 1] = 0;
                imageDataForRow.data[offset + 2] = 0;
                imageDataForRow.data[offset + 3] = 255;
            }

            ctx.putImageData(imageDataForRow, 0, rowNum);
        }

        if(!done) {
            var paintNextRow = function() {
                updateRow(rowNum + 1);
            }
            setTimeout(paintNextRow, 1);
        }
    }

    updateRow(0);

</script>

1 个答案:

答案 0 :(得分:1)

这是你的问题:

<canvas id="myCanvas1" style="width:100%; height:100%">

您使用CSS宽度和高度设置画布的宽度和高度,而不是<canvas> html属性。你实际上是在尺寸为300x150(默认值)的画布上拉伸整个屏幕。

您需要在canvas标记中定义宽度/高度:<canvas width="500" height="500">

或代码:

var canvas = document.getElementById("canvas");
canvas.width = 500;
canvas.height = 500;

而不是CSS。如果你这样做了:

<canvas style="width: 500px; height: 500px;">

然后你会有300x150画布(默认大小)缩放/扭曲为500x500,这几乎肯定是你得到的。


看起来您希望动态更改画布宽度。这没关系,但你必须做一些事情。一种方法是使用窗口的onresize事件,并在每次发生这种情况时将画布宽度设置为等于div的clientWidth(如果clientWidth当然已更改)。另一种方法是做一个简单的通用计时器,每隔半秒左右检查一次同样的事情,并设置canvas.width等于div.style.clientWidth

(我写了上面的写意,所以可能有一个错字,但你明白了)