如何在画布上绘制像素字体而不使用抗锯齿

sta*_*ers 4 javascript fonts text canvas antialiasing

我有一个像素艺术字体(在 ttf 文件中),我发现它的原始分辨率为 8 像素 ( CTX.font = '8px mainfont';)

当我执行 fillText 时,字体在 Firefox 中显示完美,但在 chrome 中显示模糊:

在此输入图像描述火狐浏览器

铬合金铬合金

我尝试将 X 坐标偏移不同的量(例如 0.5),但它变得更加模糊。通常它始终是一个舍入整数。

我尝试CTX.translate(0.5, 0);过并且CTX.imageSmoothingEnabled = true;

我尝试过CSSfont-smooth: none; font-smooth: never; -webkit-font-smoothing : none;

过去,我必须将字体转换为特殊格式,并使用库在画布上绘制它们。只是希望 5 年后他们添加一个官方方法来解决这个问题吗?

Kai*_*ido 5

只是希望 5 年后他们添加一个官方方法来解决这个问题吗?

嗯...不到几个月前,canvas API 中添加了更多的文本修饰符,其中,它基本上相当于SVG 的.ctx.textRenderingtext-rendering

因此,没有一个选项会真正强制关闭抗锯齿功能,但使用textRendering = "geometricPrecision".

此外,目前仅基于 Chromium 的浏览器支持此功能……并且仅在chrome://flags/#enable-experimental-web-platform-features打开时才支持。

const label = document.querySelector( "label" );
const canvas = document.querySelector( "canvas" );
const ctx = canvas.getContext( "2d" );
if( !ctx.textRendering ) {
  console.warn( `Your browser doesn't support the textRendering property on Canvas
If you are on Chrome be sure to enable chrome://flags/#enable-experimental-web-platform-features` );
}

let state = 0;
const states = [
  () => {
    label.textContent = "optimizeLegibility";
    ctx.textRendering = "optimizeLegibility";
    drawText();
  },
  () => {
    label.textContent = "geometricPrecision";
    ctx.textRendering = "geometricPrecision";
    drawText();
  },
  () => {
    label.textContent = "difference";
    ctx.textRendering = "optimizeLegibility";
    drawText();
    ctx.globalCompositeOperation = "xor";
    ctx.textRendering = "geometricPrecision";
    drawText();
    ctx.globalCompositeOperation = "source-over";
  }
];

document.fonts.load( "120px pixel" ).then( begin );

function begin() {
  
  ctx.clearRect( 0, 0, canvas.width, canvas.height );
  ctx.font = "120px pixel";
  states[ state ]();
  state = (state + 1) % states.length;
  setTimeout( begin, 1000 );
  
} 
function drawText() {
  ctx.textBaseline = "top";
  ctx.fillText( "TESTING", 0, 0 );
}
Run Code Online (Sandbox Code Playgroud)
@font-face {
  font-family: pixel;
  src: url("https://dl.dropboxusercontent.com/s/hsdwvz761xqphhb/pixel.ttf");
}
Run Code Online (Sandbox Code Playgroud)
<label></label><br>
<canvas width="500"></canvas>
Run Code Online (Sandbox Code Playgroud)

目前,最好的方法可能是将文本预先渲染为位图。