小编典典

如何为网页上的文本绘制动画?

all

我想要一个有一个居中单词的网页。

我希望这个词用动画来绘制,这样页面就可以像我们一样“写出”这个词,即它从一个点开始,随着时间的推移绘制线条和曲线,最终结果是一个字形。

我不在乎这是用<canvas>DOM 还是用 DOM 完成的,我也不在乎它是用 JavaScript 还是 CSS 完成的。没有 jQuery
会很好,但不是必需的。

我怎样才能做到这一点?我已经 彻底 搜索了没有运气。


阅读 109

收藏
2022-06-02

共1个答案

小编典典

我希望这个词用动画来绘制,这样页面“写”出这个词的方式与我们一样

帆布版

这将像手写一样绘制单个字符。它使用长破折号模式,其中每个字符随时间交换开/关顺序。它还有一个速度参数。

快照
示例动画(参见下面的演示)

为了增加真实感和有机感,我添加了随机字母间距、y
增量偏移、透明度、非常微妙的旋转,最后使用了已经“手写”的字体。这些可以封装为动态参数,以提供广泛的“写作风格”。

为了获得更真实的外观,默认情况下不需要路径数据。但这是一段简短而高效的代码,它近似于手写行为,并且易于实现。

这个怎么运作

通过定义虚线图案,我们可以创建行进的蚂蚁、虚线等。通过为“off”点定义一个非常长的点并逐渐增加“on”点来利用这一点,它会在为点的长度设置动画时产生在描边时画线的错觉。

由于离点太长,重复图案将不可见(长度将随所使用字体的大小和特性而变化)。字母的路径会有一个长度,所以我们需要确保每个点至少覆盖这个长度。

对于包含多条路径(例如 O、R、P
等)的字母,因为一条用于轮廓,一条用于空心部分,线条似乎是同时绘制的。我们不能用这种技术做太多的事情,因为它需要访问每个路径段来单独描边。

兼容性

对于不支持 canvas 元素的浏览器,可以在标签之间放置另一种显示文本的方法,例如样式文本:

<canvas ...>
    <div class="txtStyle">STROKE-ON CANVAS</div>
</canvas>

演示

这会产生实时动画中风( 无依赖性 ) -

var ctx = document.querySelector("canvas").getContext("2d"),

    dashLen = 220, dashOffset = dashLen, speed = 5,

    txt = "STROKE-ON CANVAS", x = 30, i = 0;



ctx.font = "50px Comic Sans MS, cursive, TSCu_Comic, sans-serif";

ctx.lineWidth = 5; ctx.lineJoin = "round"; ctx.globalAlpha = 2/3;

ctx.strokeStyle = ctx.fillStyle = "#1f2f90";



(function loop() {

  ctx.clearRect(x, 0, 60, 150);

  ctx.setLineDash([dashLen - dashOffset, dashOffset - speed]); // create a long dash mask

  dashOffset -= speed;                                         // reduce dash length

  ctx.strokeText(txt[i], x, 90);                               // stroke letter



  if (dashOffset > 0) requestAnimationFrame(loop);             // animate

  else {

    ctx.fillText(txt[i], x, 90);                               // fill final letter

    dashOffset = dashLen;                                      // prep next char

    x += ctx.measureText(txt[i++]).width + ctx.lineWidth * Math.random();

    ctx.setTransform(1, 0, 0, 1, 0, 3 * Math.random());        // random y-delta

    ctx.rotate(Math.random() * 0.005);                         // random rotation

    if (i < txt.length) requestAnimationFrame(loop);

  }

})();


canvas {background:url(http://i.imgur.com/5RIXWIE.png)}


<canvas width=630></canvas>
2022-06-02