画布上的CSS纵横比

时间:2012-05-09 21:30:18

标签: html5 canvas

最近,Mozilla推出了名为Browser Quest的HTML5游戏。在游戏中,如果您调整窗口大小,画布也会调整大小。

我进一步了解,我发现这是因为在这里找到了CSS3媒体查询https://developer.mozilla.org/en/CSS/Media_queries

然而,我仍然认为我做得不对。我的画布ID是#canvas。我怎么把它放在画布上呢?

我的画布特定宽度/高度:height:352px; width:512px;

3 个答案:

答案 0 :(得分:2)

因此,您不希望在CSS中定义画布的大小,因为您只会将其缩小到“真实”大小。您总是希望使用Canvas的widthheight属性。

但这并不意味着你无法以这种方式定义它的父母大小。将画布包裹在div中并将div的CSS宽度/高度设置为100%(或任何你想要的)

在设置过程中的代码中,您将不得不这样做:

// javascript pseudocode
canvas.width = theCanvasParent.clientWidth; // or whatever attribute it is, I'd reccomend putting all of those things in one giant container div
canvas.height = theCanvasParent.clientHeight;

由于大多数浏览器在父div更改大小时不会触发事件,因此您只需要用计时器检查每半秒,以查看div是否已更改大小。如果有,则相应地调整画布大小。

但是有onresize事件,并且根据您的网页设置方式,这可能会有效。

在Firefox,Opera,Google Chrome和Safari中,onresize事件仅在浏览器窗口大小发生变化时触发

在Internet Explorer中,当浏览器窗口或元素的大小发生更改时,会触发onresize事件。

因此,如果改变你的div大小的唯一方法是改变窗口的大小,onresize就可以了。否则你需要一个定时器,不断检查画布大小和div大小是否不同(如果是这样,调整画布大小)。

不断检查的计时器是Mozilla Bepsin团队所做的事情(在Bespin成为Skywriter之前,然后与Ace项目合并,放弃所有Canvas使用)

答案 1 :(得分:1)

媒体查询不会为您提供所需的功能。它们的目的只是限制特定样式表应用于页面的时间。

此外,CSS widthheight属性不会调整canvas元素的实际尺寸。相反,他们将元素缩放到请求的大小。在你的情况下,我假设你希望画布实际上是一个不同的分辨率。画布的分辨率是通过width标记上的DOM height<canvas>属性指定的。

为了处理调整大小,您需要使用window.onresize来捕获resize事件。然后,您的画布代码将需要创建所需大小的新画布,并正确复制原始画布上的所有内容(当您调整画布对象的大小时,其像素数据将被清除)。

答案 2 :(得分:0)

正如Xenethyl所指出的,最重要的一点是挂钩onresize,以便您可以适应新的画布对象大小:

  • 将画布尺寸(绘图区域尺寸)调整到画布渲染区域(clientWidth和clientHeight)
  • 考虑绘图算法的画布的新尺寸
  • 重绘画布

您不必制作新画布(这将迫使您重新挂钩其他事件处理程序)。

我的Web应用程序中的大多数画布,为了完美地调整到窗口,由一个专用类管理,其骨架在这里:

function Grapher(options) {
    this.graphId = options.canvasId;
    this.dimChanged = true; // you may remove that if you want (see above)
};

Grapher.prototype.draw = function() {
    if (!this._ensureInit()) return;

    // makes all the drawing, depending on the state of the application's model

    // uses dimChanged to know if the positions and dimensions of drawed objects have
    //  to be recomputed due to a change in canvas dimensions

}

Grapher.prototype._ensureInit = function() {
    if (this.canvas) return true;
    var canvas = document.getElementById(this.graphId);
    if (!canvas) {
        return false;
    }
    if (!$('#'+this.graphId).is(':visible')) return false;
    this.canvas = canvas;
    this.context = this.canvas.getContext("2d");
    var _this = this;
    var setDim = function() {
        _this.w = _this.canvas.clientWidth;
        _this.h = _this.canvas.clientHeight;
        _this.canvas.width = _this.w;
        _this.canvas.height = _this.h;
        _this.dimChanged = true;
        _this.draw(); // calls the function that draws the content
    };
    setDim();
    $(window).resize(setDim);
    // other inits (mouse hover, mouse click, etc.)
    return true;
};

在你的情况下,我会创建一个new Grapher({canvasId:'#canvas'}),并且#canvas维度在css中定义(通常以复杂的方式调整到可用空间)。

最有趣的一点是在setDim函数中。