【发布时间】:2014-04-08 16:40:38
【问题描述】:
我将画布大小设置为浏览器的 window.innerHeight 和 window.innerWidth 的 1/3。
画布上的大部分元素也是根据画布的宽度和高度设置的,因此它们的尺寸会缩小并根据画布的大小进行定位。
我如何也基于此缩放字体大小?
例如,我正在制作的游戏的起始屏幕的字体大小是 80pt。如果浏览器真的很小,那就太大了。它离开了画布。
【问题讨论】:
标签: javascript html canvas
我将画布大小设置为浏览器的 window.innerHeight 和 window.innerWidth 的 1/3。
画布上的大部分元素也是根据画布的宽度和高度设置的,因此它们的尺寸会缩小并根据画布的大小进行定位。
我如何也基于此缩放字体大小?
例如,我正在制作的游戏的起始屏幕的字体大小是 80pt。如果浏览器真的很小,那就太大了。它离开了画布。
【问题讨论】:
标签: javascript html canvas
只需用一个因子缩放font-size。
假设您的画布默认大小为 1000 像素,字体大小为 80 像素(画布将 pt 转换为像素 - 为了简单起见,我在这里使用 80,见底部)。
这将创建以下关系:
ratio = 80 / 1000 = 0.08
让我们通过乘以该比率来验证画布宽度何时为 1000:
fontSize = 1000 * ratio = 80;
我们看到我们有 80 个字体如预期的那样。
现在画布尺寸变小了,假设是 500 像素:
fontSize = 500 * ratio = 40;
这应该对应于关系。请注意,字体不会像那样线性表现,但它会大致正确。
现在只需设置字体的大小:
ctx.font = (fontSize|0) + 'px myFont';
由此产生的最终代码本质上非常简单:
var fontBase = 1000, // selected default width for canvas
fontSize = 70; // default size for font
function getFont() {
var ratio = fontSize / fontBase; // calc ratio
var size = canvas.width * ratio; // get font size based on current width
return (size|0) + 'px sans-serif'; // set font
}
每次您需要更新字体(即调整大小)时,只需调用:
ctx.font = getFont(); // call getFont to set new font size
默认值是当前/开发过程中任何大小的快照。
要将点转换为像素大小,您只需使用系统DPI / 72:
80 pt * (96 / 72) = 107 pixels @ 96 DPI.
【讨论】:
许多响应式设计使用媒体断点来控制字体大小。
字体大小在一系列媒体大小中保持固定。
在您的调整大小事件处理程序中,将字体大小应用于一系列画布大小:
if(canvas.width<480){
context.font='14px verdana';
}else if(canvas.width<768){
context.font='30px verdana';
}else{
context.font='80px verdana';
}
[还有更高效的...]
为每种媒体格式预定义一些字体大小:
var fontSizes={
phone:{
XSmall:6,
Small:8,
Medium:10,
Large:12,
XLarge:14
},
tablet:{
XSmall:10,
Small:12,
Medium:16,
Large:24,
XLarge:30
},
desktop:{
XSmall:14,
Small:18,
Medium:30,
Large:40,
XLarge:80
},
}
您可以为画布文本使用这些预定义的字体大小:
context.font=fontSizes[media].XSmall+" verdana";
context.fillText("XSmall text",20,20);
context.font=fontSizes[media].Large+" verdana";
context.fillText("Large text",20,20);
然后在您的调整大小处理程序中,您只需设置适当的媒体类型。
这样您就不需要在项目中的任何地方重新编码context.font。
var media="desktop";
if(canvas.width<480){
media="phone";
}else if(canvas.width<768){
media="tablet";
}else{
media="desktop";
}
【讨论】:
您应该将您的坐标视为虚拟坐标:如果画布占据屏幕的 1/3,请问问您自己:字体应该占用多少空间(相对),而不是它的大小。
一劳永逸地确定画布的所有虚拟分辨率,然后以该分辨率绘制所有内容...前提是您之前缩放了画布。
例如,您可以决定您的画布具有600 x 200 虚拟分辨率。当您知道真实的窗口大小时,您将拥有真实的画布大小。然后使用scale(realWidth/600, realHeight/200) 缩放画布,所有设备上的效果都一样。
我只是做了一个小小提琴来说明,你会看到它为非常不同大小的画布生成“相同”的图像:
http://jsbin.com/tisoguve/1/edit?js,output
【讨论】:
我不喜欢为任何应用程序使用确定的宽度或高度。相反,我使用 window 对象来确定屏幕上的空间量,而不是说“width=1000”,它看起来更像下面的代码。我记下了我正在使用的当前屏幕分辨率,以便在调整屏幕上的内容大小时,所有内容都会根据创建时的大小进行缩放。假设原始屏幕分辨率为1366,我们希望原始字体设置为20......
<canvas id="canvas"" width="0" height="0" style="position:relative;" ></canvas>
var canvas = document.getElementById("canvas");
var context= canvas.getContext('2d');
var canvas.width = document.body.clientWidth;
var canvas.height = document.body.clientHeight;
var px= 20-(((1366-canvas.width)/1366)*20);
var fontStyle = "italic";
var fontWeight = "bold";
var fontSize = +px+"px";
var fontFamily = "Verdana";
var b = " ";
context.font = fontStyle + b + fontWeight + b + fontSize + b + fontFamily;
我已经使用 Safari、IE、Chrome、Firefox 进行了尝试,响应式 设计视图,它的工作原理。尝试在我的应用程序中保存、缩放和恢复在旧画布上创建了一个分辨率较低的前景图像。我认为尝试以上面显示的方式运行各种媒体尺寸似乎很大。我想我可能很想使用以下内容以及页面布局的良好样式表。
var px= 20-(((1366-canvas.width/3)/1366)*20);
context.font = +px+"px";
//place text here for this font
px= 12-(((1366-canvas.width/3)/1366)*12);
context.font = +px+"px";
//place text here for this font
对于其他对象,我会尝试使用相同的方法,但是,限制使用 javascript 绘制到画布的图像,尽可能多地使用带 % 的 css 并在必要时重绘图像以防止用户缩放页面。
context.fillText ("Click To Start", canvas.width/3, canvas.height/1.7);
context.strokeText ("Click To Start", canvas.width/3, canvas.height/1.7);
【讨论】:
另一种按比例绘制文本(或其他任何内容)的技术是使用画布转换矩阵。
诀窍是在绘制之前将坐标系 (0, 0) 临时移动到文本插入点并围绕该点进行缩放。
在 x, y 点以所需 scale 绘制 text 的示例代码:
function drawText(context, x, y, text, scale){
context.save();
context.translate(x, y)
context.scale(scale, scale);
context.fillText(text, 0, 0);
context.restore();
}
要绘制文本居中使用
context.textAlign ="center";
context.textBaseline = "middle";
【讨论】: