繁体   English   中英

HTML5 Canvas 字体大小基于Canvas大小

[英]HTML5 Canvas Font Size Based on Canvas Size

我将 canvas 大小设置为浏览器的 window.innerHeight 和 window.innerWidth 的 1/3。

canvas上的大部分元素也是根据canvas的宽高设置的,这样按比例缩小,根据canvas的尺寸定位。

我如何基于此缩放字体大小?

例如,我正在制作的游戏的开始屏幕的字体大小是 80pt。 如果浏览器真的很小,那就太大了。 它关闭了 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.

许多响应式设计使用媒体断点来控制字体大小。

字体大小通过一系列介质尺寸保持固定。

在resize事件处理程序中,将字体大小应用于一系列画布大小:

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

在此输入图像描述

我不喜欢在任何应用中使用确定的宽度或高度。 相反,我使用窗口对象来确定屏幕上的空间量而不是说“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);  

绘制缩放文本(或其他任何内容)的另一种技术是使用 canvas 转换矩阵。

诀窍是暂时将坐标系 (0, 0) 移动到文本插入点并在绘制之前围绕该点进行缩放。

  1. 保存绘图上下文
  2. 使用context.translate()将坐标系移动到文本插入点
  3. 使用 use context.scale()以所需的比例因子放大/缩小
  4. 在翻译点 (0, 0) 插入文本。
  5. 恢复上下文。

x, y点绘制具有所需比例文本的示例代码:

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";

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM