ZetCode

JavaScript Canvas measureText 教程

最后修改于 2025 年 4 月 3 日

在本文中,我们将探讨 JavaScript 中的 Canvas measureText 方法。此方法对于在 HTML canvas 上渲染文本之前测量文本尺寸至关重要。掌握文本测量对于精确的文本布局和对齐至关重要。

基本定义

Canvas measureText 是一个返回 TextMetrics 对象的方法,该对象包含有关指定文本宽度的信息。通过提供精确的测量值,它可以帮助在 canvas 上准确地定位文本。

该方法使用当前的字体设置(大小、字体、样式)来计算文本尺寸。返回的对象包含 width、actualBoundingBoxLeft 和 actualBoundingBoxRight 等属性。

基本文本测量

本示例演示了如何在 canvas 上绘制文本之前测量文本宽度。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Basic Text Measurement</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    ctx.font = '30px Arial';
    const text = 'Hello Canvas';
    const metrics = ctx.measureText(text);
    
    console.log('Text width:', metrics.width);
    
    ctx.fillText(text, 50, 100);
</script>

</body>
</html>

在这个基本示例中,我们将字体设置为 30px Arial 并测量文本“Hello Canvas”。measureText 方法返回一个 TextMetrics 对象。

我们将文本宽度记录到控制台,然后在位置 (50,100) 绘制文本。这显示了如何在 canvas 上渲染文本之前获取文本尺寸。

水平居中文本

本示例展示了如何使用 measureText 水平居中文本。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Centering Text Horizontally</title>
</head>
<body>

<canvas id="myCanvas" width="400" height="200"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    ctx.font = 'bold 36px Georgia';
    const text = 'Centered Text';
    const metrics = ctx.measureText(text);
    const textWidth = metrics.width;
    
    const x = (canvas.width - textWidth) / 2;
    
    ctx.fillStyle = 'navy';
    ctx.fillText(text, x, 100);
</script>

</body>
</html>

在这里,我们测量文本宽度并计算 x 坐标以使其居中。公式 (canvas.width - textWidth) / 2 给出了正确的 x 坐标。

我们为文本使用了粗体 36px Georgia 字体和海军蓝。文本在 canvas 上完美水平居中。

测量多行文本

本示例演示了测量和定位多行文本。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Multiple Lines Measurement</title>
</head>
<body>

<canvas id="myCanvas" width="500" height="300"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    ctx.font = '24px Arial';
    const lines = ['First line of text', 'Second line', 'Third line'];
    const lineHeight = 30;
    let y = 50;
    
    lines.forEach(line => {
        const metrics = ctx.measureText(line);
        const x = (canvas.width - metrics.width) / 2;
        ctx.fillText(line, x, y);
        y += lineHeight;
    });
</script>

</body>
</html>

本示例展示了如何测量和垂直居等多行文本。每行都会单独测量以计算其水平位置。

我们使用固定的行高 30px,并为每一行增加 y 坐标。所有行都使用与前一个示例相同的公式进行水平居中。

高级文本度量

本示例探讨了包括边界框度量在内的更高级文本度量。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Advanced Text Metrics</title>
</head>
<body>

<canvas id="myCanvas" width="600" height="400"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    ctx.font = 'italic 40px Times New Roman';
    const text = 'Advanced Metrics';
    const metrics = ctx.measureText(text);
    
    console.log('Basic width:', metrics.width);
    console.log('Actual bounding box left:', metrics.actualBoundingBoxLeft);
    console.log('Actual bounding box right:', metrics.actualBoundingBoxRight);
    console.log('Font bounding box ascent:', metrics.fontBoundingBoxAscent);
    console.log('Font bounding box descent:', metrics.fontBoundingBoxDescent);
    
    // Draw reference lines
    ctx.strokeStyle = 'red';
    ctx.lineWidth = 1;
    
    // Baseline
    ctx.beginPath();
    ctx.moveTo(50, 200);
    ctx.lineTo(550, 200);
    ctx.stroke();
    
    // Text position
    ctx.fillStyle = 'blue';
    ctx.fillText(text, 100, 200);
</script>

</body>
</html>

本示例演示了 TextMetrics 对象中可用的高级文本度量属性。这些属性包括边界框度量和字体度量。

我们将各种度量记录到控制台并绘制参考基线。文本以斜体 40px Times New Roman 渲染,以显示度量如何随样式变化。

动态文本换行

本示例展示了如何使用 measureText 实现文本换行。

index.html
<!DOCTYPE html>
<html>
<head>
    <title>Text Wrapping</title>
</head>
<body>

<canvas id="myCanvas" width="500" height="400"></canvas>

<script>
    const canvas = document.getElementById('myCanvas');
    const ctx = canvas.getContext('2d');
    
    ctx.font = '18px Arial';
    const maxWidth = 300;
    const lineHeight = 25;
    const text = 'This is a long paragraph that needs to be wrapped to fit within the specified maximum width. The measureText method helps us determine where to break lines.';
    const words = text.split(' ');
    let line = '';
    let y = 50;
    
    for (let word of words) {
        const testLine = line + word + ' ';
        const metrics = ctx.measureText(testLine);
        
        if (metrics.width > maxWidth && line.length > 0) {
            ctx.fillText(line, 100, y);
            line = word + ' ';
            y += lineHeight;
        } else {
            line = testLine;
        }
    }
    
    ctx.fillText(line, 100, y);
</script>

</body>
</html>

本示例通过测量每一行潜在的文本并当其超出最大宽度时进行换行来实现文本换行。单词逐个添加。

当一行文本超出 maxWidth(300px)时,该行会被渲染,然后开始新的一行。lineHeight(25px)控制行之间的垂直间距。此技术对于在 canvas 上渲染段落非常有用。

来源

MDN Canvas measureText 文档

在本文中,我们探讨了在 HTML canvas 上测量文本的各种技术。掌握 measureText 对于创建精确的文本布局和实现文本换行和居中文本等功能至关重要。

作者

我叫 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直撰写编程文章。至今,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有十多年的经验。

列出 所有 JS Canvas 教程