【问题标题】:Calculate letter size in javascript在javascript中计算字母大小
【发布时间】:2012-03-02 23:02:15
【问题描述】:

我需要在 javascript 中计算字母的确切大小。字母可以有不同的 font-size 或 font-family 属性等。

我尝试为此使用 div 元素,但这种方法只给出了 div 的大小,而不是字母。

<div style="display: inline; background-color: yellow; font-size: 53px; line-height:32px">A</div>

有人知道如何解决这个问题吗?

【问题讨论】:

  • 在您的示例中,您将字体大小设置为 53pts。为什么屏幕上会不一样?
  • @Larry K,并非所有字体都是等宽字体。字母“i”将确定与字母“w”不同的边界矩形,具体取决于字体系列、类型、字距和其他因素。
  • 你想解决什么问题?
  • 我需要计算一个字母的大小。

标签: javascript html fonts size


【解决方案1】:

这对于一般情况来说基本上是不可能的。字体字距调整将导致字母的可变“宽度”取决于操作系统、浏览器等,以及基于哪些字母彼此相邻。如果 os+browser 没有您指定的字体,则可能会发生字体替换。

也许用你所追求的更高层次的目标重新提出问题可能会导致提出其他可能更有成效的方法来解决你的问题?

【讨论】:

  • 这就是为什么我需要在应用所有样式后计算它。根据系统如何“绘制”,我想知道大小。
【解决方案2】:

@Irongaze.com 是正确的,您的字体会根据条件具有不同的实际大小。

如果你想校准一个特定的字母,我相信element.getBoundingClientRect()会给你有用的坐标。确保完全重置您用作控制箱的容器。请注意,在不同的系统上,您可能会得到不同的结果。

jsFiddle

请注意,这不会为您提供字母实际可见部分的大小,而是它确定的容器的大小。例如line-height,不会改变实际字母大小,但会影响其他字母的定位。请注意这一点。

如果您描述了您要解决的问题,这将对我们有所帮助。可能会有更好的解决方案。

【讨论】:

  • 我不能使用行高,因为我不知道它的价值。字体大小可以动态更改,具体取决于系统。
  • @Max,建议使用 element.getBoundingClientRect()。 Line-height 是一个反例,它无法给出准确的结果。
【解决方案3】:

正如其他人所提到的,这是无法直接衡量的。但是你可以用一种更迂回的方式来解决它:将字母绘制到画布上并确定填充了哪些像素。

这是demo that does this。肉是这个功能:

/**
 * Draws a letter in the given font to an off-screen canvas and returns its
 * size as a {w, h, descenderH} object.
 * Results are cached.
 */
function measureLetter(letter, fontStyle) {
  var cacheKey = letter + ' ' + fontStyle;
  var cache = measureLetter.cache;
  if (!cache) {
    measureLetter.cache = cache = {};
  }
  var v = cache[cacheKey];
  if (v) return v;

  // Create a reasonably large off-screen <canvas>
  var cnv = document.createElement('canvas');
  cnv.width = '200';
  cnv.height = '200';

  // Draw the letter
  var ctx = cnv.getContext('2d');
  ctx.fillStyle = 'black';
  ctx.font = fontStyle;
  ctx.fillText(letter, 0.5, 100.5);

  // See which pixels have been filled
  var px = ctx.getImageData(0, 0, 200, 200).data;
  var minX = 200, minY = 200, maxX = 0, maxY = 0;
  var nonZero = 0;
  for (var x = 0; x < 200; x++) {
    for (var y = 0; y < 200; y++) {
      var i = 4 * (x + 200 * y);
      var c = px[i] + px[i + 1] + px[i + 2] + px[i + 3];
      if (c === 0) continue;
      nonZero++;
      minX = Math.min(x, minX);
      minY = Math.min(y, minY);
      maxX = Math.max(x, maxX);
      maxY = Math.max(y, maxY);
    }
  }

  var o = {w: maxX - minX, h: maxY - minY, descenderH: maxY - 100};
  cache[cacheKey] = o;
  return o;
}

请注意,这对抗锯齿很敏感——结果可能会偏离一个像素。

【讨论】:

  • 它也非常慢。不要使用这种技术,除非您缓存结果,并且只在页面上执行几次......但非常酷。 :-)
  • 这个解决方案已经包含了缓存,所以自己缓存结果是没有意义的。
  • 我们如何添加行高?
猜你喜欢
  • 2020-09-17
  • 1970-01-01
  • 1970-01-01
  • 2020-01-04
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 2014-10-03
  • 1970-01-01
相关资源
最近更新 更多