首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >看上去不错吧?

看上去不错吧?
EN

Stack Overflow用户
提问于 2012-12-12 06:31:50
回答 2查看 277关注 0票数 0

几年前,我为APNGedit制作了一个Javascript脚本,用于绘制笑人标识。它使用了现已失效的mozTextAlongPath

最近,我重新发现了这个脚本,并使用翻译、旋转和fillText()重做了它。然而,这不尊重字符的宽度,也没有角化(它看起来很糟糕)。

2009年原版(不完美,但没问题):

现行版本:

如何在HTML5画布上以弧形绘制文本并使其看起来很好?

基于Kolink答案的解决方案代码:

代码语言:javascript
复制
ctx.fillStyle = primaryColor;
ctx.font = fontSize + 'px ' + fontFamily;

var textWidth = ctx.measureText(text).width,
    charRotation = 0,
    character, charWidth, nextChar, nextWidth, bothWidth, kern, extraRotation, charSegment;

for (var i=0, l=text.length; i<l; i++) {
    character = nextChar || text[i];
    charWidth = nextWidth || ctx.measureText(character).width;

    // Rotate so the letter base makes a circle segment instead of a tangent
    extraRotation = (Math.PI/2) - Math.acos((charWidth/2) / radius);

    ctx.save();
    ctx.translate(radius, h/2);
    ctx.rotate(charRotation);
    ctx.translate(0, -textRadius);
    ctx.rotate(extraRotation);
    ctx.fillText(character,0,0);
    ctx.restore();

    nextChar = text[i+1] || '';
    nextWidth = ctx.measureText(nextChar).width;

    bothWidth = ctx.measureText(character+nextChar).width;
    kern = bothWidth - charWidth - nextWidth;

    charSegment = (charWidth+kern) / textWidth; // percent of total text size this takes up
    charRotation += charSegment * (Math.PI*2);
}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-12 06:40:25

显然,在圆弧上放置字母并不困难(只需将中心底部与圆圈对齐)。然而,正如您所指出的,问题在于解决问题。

幸运的是,我们有了measureText(),它可以告诉我们字母的宽度,因此可以使用什么内核。

圆周仅为2πr,文本的总宽度为ctx.measureText("Your text here");。得到这两个值的比率,你会发现你需要多少空间或挤在一起你的话。

您可能希望将空格修饰符应用于整个单词,而不是单个字母。要做到这一点,在句子中使用measureText(),去掉空格以获得字母的宽度(扩展为空格的总宽度)。

现在你需要画出每个单词的去向。再次使用measureText()查找每个单词的宽度,并在您的圆圈上绘制它的中心点,在每个单词之间添加一部分总空格值。现在,在每个字母上使用measureText(),并在正确的位置绘制它,以获得完美的角化。

一切都很好,你应该有一个完美的圆圈的文本。

票数 1
EN

Stack Overflow用户

发布于 2013-03-08 21:06:35

所以测量文本是好的,我最后做的,是Math.pow(measureText + measureTextOfLastChar, 3 / 4)

由于某些原因,当前字符和先前字符宽度之和的平方根使得一些空格太细,而根本没有平方根,这也使它变得糟糕,但是Math.pow( sum,3/4)由于某种原因创造了一个很大的比率。这是代码(在coffeescript中)

代码语言:javascript
复制
CanvasRenderingContext2D::fillTextCircle = (str, centerX, centerY, radius, angle) ->
  len = str.length
  s = undefined
  @save()
  @translate centerX, centerY
  @rotate - (1 + 1 / len) * angle / 2
  n = 0

  prevWidth = 0
  while n < len
    thisWidth = @measureText(str[n]).width
    @rotate angle / len * Math.pow(thisWidth + prevWidth, 3 / 4) / @measureText(str).width
    s = str[n]
    prevWidth = @measureText(str[n]).width
    @fillText s, -@measureText(str[n]).width / 2, -1 * radius
    n++
  @restore()

那就叫它用

代码语言:javascript
复制
context.fillTextCircle('hiya world', halfWidth, halfHeight, 95, 26)

我只是在猜测和检查一下,虽然我服用了calc 4,所以我下意识地知道自己在做什么。无论如何,它会产生完美的字符间距,如果没有Math.pow,就无法获得这种间距(sum_character_widths,3/4)。

除了将Math.pow(和,3/4)保存在循环中之外,一切都可以更改,因为这是我在网上找到的其他内容中更好的部分。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13834099

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档