1. ホーム
  2. ジャバスクリプト

[解決済み】Webページ上のテキストの描画をアニメーション化するには?

2022-04-16 17:43:08

質問

単語を1つだけ中央に配置したWebページを作りたいのですが、どうすればいいですか?

つまり、ある点から始まり、最終的にグリフになるように、時間をかけて線や曲線を描いていくのです。

で行われても構わない。 <canvas> やDOM、JavaScriptやCSSで行われているかどうかは気にしない。jQueryがないのはありがたいが、必須ではない。

どうすればいいのでしょうか?私が検索したのは 徹底的に を使用しましたが、うまくいきませんでした。

解決方法は?

<ブロッククオート

この単語をアニメーションで描画して、ページ上で を書き出すのと同じように、単語を書き出します。

キャンバス版

これは、より手書きに近い形で一文字を描画するものである。長いダッシュパターンを使用し、1文字ごとにオン・オフの順序が時間的に入れ替わります。また、speedパラメータも用意されています。

<イグ

アニメーション例(下のデモをご覧ください)

リアルさとオーガニック感を高めるために、ランダムな文字間隔、yデルタオフセット、透明度、非常に微妙な回転を加え、最後にすでに手書きのフォントを使用しました。これらは動的なパラメータとしてまとめることができ、幅広い「書き味」を提供することができます。

さらにリアルな外観にするためには、パスデータが必要ですが、デフォルトではありません。しかし、これは手書きの動作に近い、短くて効率的なコードで、簡単に実装できます。

仕組み

ダッシュパターンを定義することで、蟻の行進や点線などを作成することができます。これを利用して、quot;off"のドットを非常に長く定義し、quot;on"のドットを徐々に長くしていくと、ドットの長さをアニメーションさせながらストロークしたときに線を引いたような錯覚を与えることができるようになるのです。

オフのドットが長いので、繰り返し模様は見えません(長さは使用する書体のサイズや特徴によって異なります)。文字のパスには長さがあるので、各ドットが少なくともこの長さをカバーしていることを確認する必要があります。

複数のパスからなる文字(例:O、R、Pなど)の場合、1つは輪郭、もう1つはくぼみの部分なので、同時に線が引かれているように見えます。この場合、それぞれのパスセグメントにアクセスし、別々にストロークさせる必要があるため、この手法ではあまり対処できません。

互換性

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>