为什么这个 canvas 一直在增长? (canvas 的动态调整大小)

Why does this canvas keep growing? (dynamic resizing of canvas)

我在基于 canvas 的应用程序上工作,我需要动态调整 canvas 的大小。问题是,通过 CSS 设置宽度和高度会拉伸 canvas 而不是实际加宽绘图表面。您需要通过 html 宽度和高度属性以 像素 设置它。这就是问题所在:我希望它填充 table 单元格。

多亏了我在另一个 SE 答案中找到的几行 javascript,我找到了解决方案。

canvas.width  = canvas.offsetWidth;
canvas.height = canvas.offsetHeight;

offsetWidth 属性 考虑了 CSS 高度,因此它可用于将 100% 高度转换为像素值。所以我们让 css 调整 canvas 元素的大小,然后我们使用 JS 调整绘图表面的大小... 但它似乎只有在试图让 canvas 增长时才有效。

http://jsfiddle.net/4p18g0e9/1/

看看 chrome 中的这个 fiddle。当您调整结果 window 的大小时,canvas 会重新绘制并调整大小,因此红色方块始终具有相同的纵横比。但是,当您尝试缩小 window 时,canvas 保持相同大小,溢出到正文下方!我添加了 css 代码以在正文下方绘制边框以显示此内容。

在 firefox 中,canvas 上 100% 的 CSS 高度似乎使其比页面更宽,而不是相对于父页面。把fiddle里面的JS去掉试试,canvas很大。

我在这里解决了 chrome 的问题: http://jsfiddle.net/yb6e9mwa/2/

updateCanvasSize = function() {
    canvas.width = 0;
    canvas.height = 0;
    canvas.style.width = "1px";
    canvas.style.height = "1px";

    setTimeout(_updateCanvasSize, 0);
};

_updateCanvasSize = function() {
  canvas.style.width = "100%";
  canvas.style.height = "100%";
  canvas.width  = canvas.offsetWidth;
  canvas.height = canvas.offsetHeight;
  drawCanvas();
};

很简单,我只是将高度和CSS高度都设置为0px,等待它渲染,然后将其设置回它应该的样子。它工作正常,即使这意味着您在调整 window.

大小时看不到 canvas

但是,Firefox 上的修复将 canvas 设置为恒定的 1 像素高。 是浏览器有问题,还是我做错了什么?

这似乎是表格自动拉伸以适应内容的方式的问题,即使这意味着溢出正文。我使用 css 调整大小 属性(仅限 Chrome/Firefox)进行了快速测试。 http://jsfiddle.net/dods7dpk/

所以我按照 KenFyrstenberg 所说的做了,并改用了 div。由于 div 不会自动将它们的高度分配给它们的 children,我不得不将中间行设置为 top: 20px; bottom: 20px; 以使其自动拉伸。

http://jsfiddle.net/aL3kayLs/2/

<body>
    <div class="fillParent" style="position:relative;">
        <div style="height:20px; width:100%;">
            <div class="fillParent">Test</div>
        </div>
        <div style="position:absolute; top:20px; bottom: 20px; width:100%;">
            <div class="fillParent">
                <canvas class="fillParent" width="100" height="100">
                    Your browser is not compatible with HTML5 canvas.
                </canvas>
            </div>
        </div>
        <div style="position: absolute; bottom: 0px; height:20px; width:100%;">
            <div>Test</div>
        </div>
    </div>
</body>

body{
    border-bottom: 1px solid black;
}

html, body, .fillParent {
    height: 100%;
    width: 100%;
    overflow: hidden;
}

table {
  table-layout: fixed;
}

canvas {
    background-color: rgba(0,0,255,0.5);
}

如果不需要兼容旧浏览器(IE8及之前)mido22的解决方案更简洁,使用CSS calc函数

清理后的代码版本:http://jsfiddle.net/dsnqr5m2/2/

<body>
    <div class="fillParent">
        <div class='header'>
            <div class="fillParent">Test</div>
        </div>
        <div class='middle'>
            <div class="fillParent">
                <canvas class="fillParent" width="100" height="100">
                    Your browser is not compatible with HTML5 canvas.
                </canvas>
            </div>
        </div>
        <div class='footer'>
            <div>Test</div>
        </div>
    </div>
</body>

html, body, .fillParent {
    height: 100%;
    width: 100%;
    overflow: hidden;
}

.header, .footer{
    height:20px;
}

.middle{
    height:calc(100% - 40px);
}

canvas {
    background-color: rgba(0,0,255,0.5);
}