【问题标题】:How can I set the size of a custom font rendering to an off-screen canvas in three.js?如何在three.js中将自定义字体渲染的大小设置为屏幕外画布?
【发布时间】:2019-02-22 14:23:21
【问题描述】:

我需要使用 自定义字体 并在屏幕外的画布上渲染它们,我已经这样做了,但我无法设置字体渲染的大小 - 结果是很小的渲染。

我见过的所有来源,包括 w3schools.com、developer.mozilla.org 等。天真地假设我们都使用系统字体,并以一种草率的方式与字体名称混合定义大小:ctx.font = "30px宋体”;

事实上,̶,如果我使用的名称我的自定义字体文件放置在相同的文件夹̶(̶“̶c̶u̶s̶t̶o̶m̶.̶w̶o̶f̶f̶”̶)̶̶(或.otf)的̶它的工作原理,̶但是,如果我添加不起作用的像素或点大小(“30px custom.woff”)!

令人沮丧的是,字体粗细等其他参数似乎是单独定义的(谈论令人难以置信的 HTML5 不一致让我们想起了过去)。那么,有没有办法改变在 JS 中创建的屏幕外画布的自定义字体的渲染大小?

我这样创建屏幕外画布:

var offScreenCanvas = document.createElement('canvas');
offScreenCanvas.width = 256;
offScreenCanvas.height = 256;
var ctx = offScreenCanvas.getContext("2d");

后来,我把字体渲染成这样:

ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.font = 'custom.woff'; 
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, offScreenCanvas.width, 256);

ctx.fillStyle = 'black';
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(txt, offScreenCanvas.width / 2, offScreenCanvas.height / 2); 

然后我制作该渲染的纹理并在 three.js 表面上使用它。

三个.js r96.0

jsfiddle 上的字体替换(参见 cmets):

【问题讨论】:

    标签: javascript fonts three.js html5-canvas


    【解决方案1】:

    您可以创建一个 CSS 字体规则并随意命名。然后你就可以使用你自己的名字了。

    <style>
    @font-face {
        font-family: 'myfontname';
        src: url('custom.woff');
    }
    </style>
    

    然后在你的脚本中

    ctx.font = '30px myfontname';
    

    如果你说它可以传递字体文件,那么试试

    ctx.font = "fontfile.woff";
    // most likely you need to wait/check that the font has loaded first and then
    ctx.font = ctx.font.replace('(\d+)px', "20px");
    

    【讨论】:

    • 行得通,谢谢!所以需要在CSS中定义。我认为 JS 缺乏这种能力。不过,这对我来说已经足够了。我会等几天,以防有人发布一个简单的 JS 解决方案,如果没有,我会选择这个作为答案。
    • 更正:不,它不起作用!我在Chrome中看到文字大小增加了,我以为问题解决了,但是字体被系统字体替换了! Firefox 不这样做,并且根本不呈现字体。所以这个方法也不起作用(我不能收回我的投票,因为......没有足够的声誉 - 去图。)。
    • @user5515 它应该可以工作。很可能是字体文件尚未加载的问题。见stackoverflow.com/questions/5680013/…
    • 自定义字体确实加载并出现在一个微小的渲染中。只有当我在字体名称前添加“40px”时,它才不会在 FF 和 Chrome 中加载,并且 Chrome 会用我写的系统字体替换它。除非添加“40px”导致它延迟......
    • 在 ctx.font = '30px myfontname'; 之后添加一个 alert("!") 就足够了根据您的建议,验证即使有足够的时间,如果添加 30px,字体也不会加载。所以这不是问题。
    【解决方案2】:

    因为我在 JS 中创建屏幕外画布 没有首先在 HTML 中预定义它,因为我正在从画布上的各种字体渲染创建许多纹理,并且因为我使用的是自定义字体放置在文件夹中而不是加载 Google 字体,没有建议的解决方案按原样工作,但是 discourse.threejs.org 中的 Gabriele PetrioliMugen87 都有很大帮助。

    所以它终于在 Firefox、Chrome 和 Opera 上正常运行了。 IE11 是不可能的,因为它无论如何都不支持所有 three.js 功能,所以我根本没有理由支持它(而且我对 Edge 浏览器一无所知,因为我仍然使用 Windows 7,但我怀疑有类似问题...)。

    1) Mugen87 的等待字体加载的建议是关键:

    document.fonts.onloadingdone = function (fontFaceSetEvent) {
    
       // create canvas and render the font here (see above) 
    
    }
    

    2) 对于文件夹上的自定义字体,这在我的情况下有效:

    放置在样式或 CSS 中(格式是可选的,但建议使用):

      @font-face {
        font-family: 'custom bold';
        src: url('fonts/custom bold.woff') format('woff');
      }
      @font-face {
        font-family: 'custom reg';
        src: url('fonts/custom regular.woff') format('woff');;
      }
    

    3) 要在 Chrome 中工作,我发现在 body 样式中也包含 font-family 是关键,但由于我想使用比一种字体更多的字体(显然),我每次需要时都在 JS 中这样做一个字体,像这样:

    var fontreg;
    
    fontreg = "custom reg";
    document.body.style.fontFamily = fontreg;
    
    ctx.font = "40px " + fontreg;
    

    希望对其他人也有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-15
      • 1970-01-01
      • 2021-10-01
      • 2012-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多