【问题标题】:BitmapText using fabricjs使用fabricjs的位图文本
【发布时间】:2018-08-01 04:19:57
【问题描述】:

我研究了 HTML5 和 CSS3 中使用的字体。我知道网页字体(如 ttf/otf、eot、woff、woff2)将支持网页。但是,我需要在画布中使用 *.fon 字体(本机应用程序中使用的字体)。

我提到了link,bitmaptext 可以与扩展 fabric.image 一起使用。但是,我需要像 fabricjs 的普通文本对象一样使用位图文本。例如。字体样式、换行、行距、字体更改等

是否可以使用 bitmaptext 或有任何其他方式来呈现 *.fon 文件中的文本?

.fon file converted to bitmap

【问题讨论】:

  • 您不能将此 .fon 转换为 Web 兼容字体吗?看起来是最好的解决方案。
  • 可以。但是,我想改变字符的字体大小(宽度和高度不成比例)不像普通的文本字体大小。例如。如果我使用 6x9 字体,字符宽度为 6px,高度为 9px,那么我的字体大小可能是 12x9 或 6x18。这在普通的网络字体中是不可能的。
  • 所以你最好的办法是继承 iText 而不是文本,并覆盖渲染方法,此时你有一个可编辑的位图文本
  • 目前,我创建了一个以 *.fon 作为图像的字符集,并扩展了 fabric.image 类作为来自link 的参考。你的意见是扩展 IText 而不是 Image?
  • 您认为如何根据这个用例制作教程?我可以将教程添加到fabricjs.com,然后将其作为链接发布在这里,或者复制答案中的完整代码。我认为是子类教程的好用例

标签: fonts html5-canvas fabricjs webfonts


【解决方案1】:

在这里您可以看到 Textbox 类的基本覆盖。

我添加了处理基本功能所需的所有属性,我将 measureChar 函数存根以返回位图字体的固定宽度 6px。

在初始化时,我创建了一个地图,告诉我位图字体中最常见字符的位置,最后我编写了一个简单的渲染方法来检索它需要的画布部分以绘制该字符。

你仍然需要弄清楚 fontColor、fontSize、doubleWidth 和 doubleHeight,但是既然你有这个例子就应该直截了当

(function() {
  fabric.BitmapText = fabric.util.createClass(fabric.Textbox, {
    type: 'bitmapText',
    bitmap: 'https://i.stack.imgur.com/ITDgw.png',
    readyToRender: false,
    charWidth: 6,
    charHeight: 9,
    fontSize: 9,

    charMap: ' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}'
      .split('').reduce(function(acc, char, index) {
        acc[char] = index + 31;
        return acc;
      }, {}),
    initialize: function(text, options) {
      this.callSuper('initialize', text, options);
      var image = fabric.document.createElement('img');
      image.onload = (function() {
        var canvas = fabric.document.createElement('canvas');
        canvas.width = image.width;
        canvas.height = image.height;
        console.log(canvas.width)
        canvas.getContext('2d').drawImage(image, 0, 0);
        this.bitmapResource = canvas;
        this.readyToRender = true;
        this.dirty = true;
        if (this.canvas) this.canvas.requestRenderAll();
      }).bind(this);
      image.src = this.bitmap;
    },

    // override: make it return a fixed box 6x9
    _measureChar: function(_char, charStyle, previousChar, prevCharStyle) {
      return { width: 6, kernedWidth: 6 };
    },

    _renderChar: function(method, ctx, lineIndex, charIndex, _char, left, top) {
      if (!this.readyToRender) return;
      var charMap = this.charMap, res = this.bitmapResource;
      _char.split('').forEach(function(singleChar) {
        ctx.drawImage(res, charMap[singleChar] * 6, 0, 5, 9, left, top - 6, 5, 9);
        ctx.translate(6, 0);
      });
    },
  });


  var canvas = new fabric.Canvas('c');
  var text = new fabric.BitmapText('Hello i am a bitmap text');

  canvas.add(text);
  canvas.setActiveObject(text);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.1.0/fabric.min.js"></script>
<canvas id="c" width="350" height="400" />

【讨论】:

  • 感谢@AndreaBogazzi,它在 sn-p 中运行良好。我可以知道您使用的是哪个版本的 fabric.js 吗?目前我正在使用fabric 1.7.19
  • 我用的是最新的 2.1.0,今天应该变成 2.2.0。如果您处于早期项目阶段,您应该继续最新的。此覆盖可能不适用于 1.7,因为 measure char 不同
  • 谢谢,@AndreaBogazzi。它工作正常。我正在用位图文本中的多行文本进行渲染。我可以用不同的位图源渲染不同的文本行吗?
  • 在“ctx.drawImage(res, charMap[singleChar] * 6, 0, 5, 9, left, top - 6, 5, 9); 行中。我想知道top差异与6的目的。
  • 这种差异的目的只是使文本与光标对齐,只是通过反复试验找到的值。
猜你喜欢
  • 1970-01-01
  • 2017-10-14
  • 2013-03-04
  • 1970-01-01
  • 2016-07-02
  • 2023-03-28
  • 2021-07-05
  • 1970-01-01
  • 2016-05-25
相关资源
最近更新 更多