【问题标题】:How to draw a pixel font on the canvas without anti-aliasing如何在没有抗锯齿的情况下在画布上绘制像素字体
【发布时间】:2021-12-14 01:23:54
【问题描述】:

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

当我做 fillText 时,字体在 firefox 中完美显示,但在 chrome 中模糊:

火狐

铬

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

我试过CTX.translate(0.5, 0);和CTX.imageSmoothingEnabled = true;

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

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

【问题讨论】:

    标签: javascript canvas text fonts antialiasing


    【解决方案1】:

    是否只是希望 5 年后他们添加了解决此问题的官方方法?

    嗯……不超过几个月前,more text modifiers一直是added to the canvas API,其中ctx.textRendering,基本相当于SVG's text-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 );
    }
    @font-face {
      font-family: pixel;
      src: url("https://dl.dropboxusercontent.com/s/hsdwvz761xqphhb/pixel.ttf");
    }
    <label></label><br>
    <canvas width="500"></canvas>

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

    【讨论】:

      猜你喜欢
      • 2010-11-26
      • 1970-01-01
      • 2012-01-25
      • 1970-01-01
      • 1970-01-01
      • 2013-10-12
      • 2013-12-04
      • 2014-09-03
      相关资源
      最近更新 更多