You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

HTML Canvas绘制文本出现光栅化模糊问题求助

Canvas子Canvas绘制文本模糊问题解决

问题描述

在主Canvas上绘制带有文本的子Canvas时,文本出现模糊/光栅化现象,效果如下:
模糊的Canvas文本效果

尝试的代码如下:

HTML代码

<canvas width="1000" height="1000" class="main"></canvas>

CSS代码

.main {
  background: blue;
}
@font-face {
font-family: 'KulminoituvaRegular';
src: url('http://www.miketaylr.com/f/kulminoituva.ttf');
}

JavaScript代码

const mainCanvas = document.querySelector('.main');
const mainCanvasContext = mainCanvas.getContext('2d');

const backgroundCanvas = document.createElement('canvas');
backgroundCanvas.width = 1000
backgroundCanvas.height = 1000

const backgroundCanvasContext = backgroundCanvas.getContext('2d');

const run = async() => {
  const title = 'SQUARE'
  const text = title.toUpperCase();

  backgroundCanvasContext.font = '300px KulminoituvaRegular';
  ctx.fillStyle = 'white';
  ctx.fillText(text, 800/2, 30);
  mainCanvasContext.drawImage(backgroundCanvas, 0, 0, mainCanvas.width, mainCanvas.height);
};

run();

问题原因

  1. 自定义字体未加载完成就绘制:异步加载的字体还没就绪时调用fillText,浏览器会用默认 fallback 字体绘制,导致文本渲染异常。
  2. 变量名错误:代码中使用了未定义的ctx,实际应为backgroundCanvasContext,会导致绘制失败或异常。
  3. 文本绘制位置错误:fillText的y坐标设为30,远小于300px的字体大小,仅绘制了文本顶部极小部分,后续放大后加剧模糊。
  4. 不必要的缩放逻辑:虽子Canvas和主Canvas尺寸一致,但绘制内容不完整会导致缩放时的模糊问题。

修复后的代码

修正后的JavaScript代码

const mainCanvas = document.querySelector('.main');
const mainCanvasContext = mainCanvas.getContext('2d');

const backgroundCanvas = document.createElement('canvas');
backgroundCanvas.width = 1000;
backgroundCanvas.height = 1000;

const backgroundCanvasContext = backgroundCanvas.getContext('2d');

const run = async() => {
  // 等待自定义字体加载完成
  await document.fonts.load('300px KulminoituvaRegular');
  
  const title = 'SQUARE';
  const text = title.toUpperCase();

  backgroundCanvasContext.font = '300px KulminoituvaRegular';
  backgroundCanvasContext.fillStyle = 'white';
  // 计算文本居中位置,设置合理基线y坐标确保完整显示
  const textWidth = backgroundCanvasContext.measureText(text).width;
  const x = (backgroundCanvas.width - textWidth) / 2;
  const y = 300;
  backgroundCanvasContext.fillText(text, x, y);
  
  // 按原尺寸绘制子Canvas到主Canvas,避免额外缩放
  mainCanvasContext.drawImage(backgroundCanvas, 0, 0);
};

run();

修复要点

  • 用document.fonts.load()等待字体加载完毕后再绘制,确保使用目标字体渲染。
  • 修正变量名错误,替换ctx为backgroundCanvasContext。
  • 计算文本居中位置,设置合适的基线y坐标,保证文本完整显示。
  • drawImage省略目标尺寸参数,直接按原尺寸绘制,避免不必要缩放。

内容的提问来源于stack exchange,提问作者alpecca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:50:03