最近,Mozilla 推出了一款名为 Browser Quest 的 HTML5 游戏。在游戏中,如果您调整窗口大小,画布也会随之调整大小。
我进行了更多调查,发现这是因为在这里找到了使用 CSS3 媒体查询https://developer.mozilla.org/en/CSS/Media_queries
但是,我仍然认为我做得不对。我的画布 ID 是#canvas
. 我将如何将它放在我的画布上?
我的画布特定宽度/高度:height:352px;
width:512px;
最近,Mozilla 推出了一款名为 Browser Quest 的 HTML5 游戏。在游戏中,如果您调整窗口大小,画布也会随之调整大小。
我进行了更多调查,发现这是因为在这里找到了使用 CSS3 媒体查询https://developer.mozilla.org/en/CSS/Media_queries
但是,我仍然认为我做得不对。我的画布 ID 是#canvas
. 我将如何将它放在我的画布上?
我的画布特定宽度/高度:height:352px;
width:512px;
因此,您不想在 CSS 中定义画布的大小,因为您只会将其从“真实”大小缩放。您总是希望使用 Canvas 的width
和height
属性。
但这并不意味着您不能以这种方式定义它的父级大小。将画布包裹在一个 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 的使用)
媒体查询不会为您提供您所寻求的功能。它们的目的只是限制将特定样式表应用于页面的时间。
此外,CSSwidth
和height
属性不会调整画布元素的实际尺寸。相反,它们将元素缩放到请求的大小。在您的情况下,我假设您希望画布实际上具有不同的分辨率。画布的分辨率是通过标签上的 DOMwidth
和height
属性指定的。<canvas>
为了处理调整大小,您将需要使用window.onresize
来捕获调整大小事件。然后,您的画布代码将需要创建一个所需大小的新画布,并正确复制原始画布中的所有内容(当您调整画布对象的大小时,其像素数据会被清除)。
正如 Xenethyl 所指出的,最重要的一点是挂钩 onresize 以便您可以适应新的画布对象大小:
您不必制作新的画布(这将迫使您重新挂钩其他事件处理程序)。
我的 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 函数。