简体   繁体   English

HTML5 Canvas 中的桥接文字效果

[英]Bridge Text Effect in HTML5 Canvas

Want to create a Bridge Text Effect like below, i tried using arctext but it doesnt help.想要创建一个像下面这样的Bridge Text Effect ,我尝试使用 arctext 但它没有帮助。 I tried to google id but it doesnt understand Bridge text Shapes.我试图谷歌 id,但它不理解桥文本形状。

在此处输入图片说明

<!DOCTYPE HTML>
<html>
  <head>
    <style>
      body {
        margin: 0px;
        padding: 0px;
      }
    </style>
  </head>
  <body>
    <canvas id="myCanvas" width="578" height="200"></canvas>
    <script>
      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
      var x = canvas.width / 2;
      var y = canvas.height / 2;

      context.font = '30pt Calibri';
      // textAlign aligns text horizontally relative to placement
      context.textAlign = 'center';
      // textBaseline aligns text vertically relative to font style
      context.textBaseline = 'middle';
      context.fillStyle = 'blue';
      context.fillText('BRIDGE TEXT', x, y);
    </script>
  </body>
</html>

Displacement位移

There are at least two ways you can achieve a curved text effect - both share the same principle of displacement of pixels (moving them out of position relative to their real position), it's just a matter of which method we use to do this.至少有两种方法可以实现弯曲的文本效果 - 两者共享相同的像素位移原理(将它们移动到相对于它们的实际位置的位置),这只是我们使用哪种方法来做到这一点的问题。

In the following demo I will use simple slicing using the internal drawImage method.在下面的演示中,我将使用内部drawImage方法使用简单的切片。 Optional we could have iterated the pixel buffer and manually projected the pixels but for cases such as this it's simpler to use slicing IMO and we get anti-aliasing for free.可选,我们可以迭代像素缓冲区并手动投影像素,但对于这种情况,使用切片 IMO 更简单,我们可以免费获得抗锯齿。

Example + demo示例 + 演示

Here is a full example (see demo for sliders and custom text) on one way of doing this:这是执行此操作的一种方式的完整示例(请参阅滑块和自定义文本的演示):

ONLINE DEMO HERE在线演示在这里

The result will be:结果将是:

桥接示例

var ctx = demo.getContext('2d'), /// get canvas
    font = '64px impact',        /// define font
    w = demo.width,              /// cache width and height
    h = demo.height,
    curve,                       /// curve for our text
    offsetY,                     /// offset from top (see note)
    bottom,                      /// bottom origin
    textHeight,                  /// height of text
    angleSteps = 180 / w,        /// angle steps per pixel
    i = w,                       /// counter (for x)
    y,
    os = document.createElement('canvas'), /// off-screen canvas
    octx = os.getContext('2d');

/// set off-screen canvas same size as our demo canavs
os.width = w;
os.height = h;

/// prep text for off-screen canvas
octx.font = font;
octx.textBaseline = 'top';
octx.textAlign = 'center';

/// main render function
function renderBridgeText() {

    /// snipped... get various data (see demo for detail)

    /// clear canvases
    octx.clearRect(0, 0, w, h);
    ctx.clearRect(0, 0, w, h);

    /// draw the text (see demo for details)    
    octx.fillText(iText.value, w * 0.5, 0);

    /// slide and dice (MAIN)
    i = w;
    while (i--) {
        /// calc distance based on curve (=radius) and x position
        y = bottom - curve * Math.sin(i * angleSteps * Math.PI / 180);

        /// draw the slice for this vertical line
        ctx.drawImage(os, i, offsetY, 1, textHeight,
                          i, offsetY, 1, y);
    }
}

Note on offset: offset can be many things - in this demo I let it be the top source of the text to "correct" the curving a little as texts aren't drawn at the very top (due to various glyph geometry which I'm not gonna into here) - you will see this clearly between Chrome and Firefox as the text is rendered differently.关于偏移的注意事项:偏移可以是很多东西 - 在这个演示中,我让它成为文本的主要来源,以“纠正”弯曲一点,因为文本不是在最顶部绘制的(由于我的各种字形几何形状)我不会在这里介绍)-您会在 Chrome 和 Firefox 之间清楚地看到这一点,因为文本的呈现方式不同。

The demo let you change text and adjust a few parameters so you can see what effect they have on the text.该演示允许您更改文本并调整一些参数,以便您可以查看它们对文本的影响。

How it works工作原理

The width is divided first on number of pixels we want to displace on the x axis.宽度首先根据我们想要在 x 轴上位移的像素数进行划分。 This gives us the delta angle we need to use for each pixel step.这为我们提供了每个像素步长需要使用的增量角。

Then we calculate a basic distance based on angle for y-axis using sinus using curve as radius.然后我们使用曲线作为半径,使用正弦曲线计算基于 y 轴角度的基本距离。 As the delta angle now corresponds to an angle from 0 to 180 based on x position this will gives us a nice curve matching the text width which is drawn in center.由于 delta 角度现在对应于基于 x 位置的从 0 到 180 的角度,这将为我们提供一条与中心绘制的文本宽度相匹配的漂亮曲线。

This value we subtract from bottom to get the y position for the bottom of text.我们从底部减去这个值以获得文本底部的 y 位置。

Then we pick a normal sized slice from the source, one pixel thick, and we scale it to destination based on the y value.然后我们从源中选择一个正常大小的切片,一个像素厚,我们根据 y 值将其缩放到目标。 This does the trick.这就是诀窍。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM