SVGアニメーション、mask要素で手書き風テキスト。

〽️「線」でマスクする。 〽️画像作成。 〽️コーディング。 〽️理解していれば応用も。





⬆︎SVGついてのまとめページ、CSSアニメーションの基本コーナーはこちら。

こんにちは、「ふ」です。
前回は「線」を描くSVGアニメーションについて紹介しました。
その中でテキストのアウトラインもアニメーションさせてみましたが、では「テキスト自体」をアニメーションさせて、手で書いているような表現をするにはどうすればいいのか。今回探っていきます。

こういったアニメーションの実装には、外部のライブラリを使用しているケースもよく見かけます。しかし、フツーのnativeなコーディングで簡単に作成することができます。

今回登場するmask要素についての解説はちょっぴり難解なものがありますが、頑張って仕組みを理解し、応用にも役立ててください。

SVG、線を描くアニメーション。

2020.09.23
〽️ 破線のプロパティをつかいます。


*前回の記事⬆︎も踏まえた内容と成増ので、まだお読みになっていない方はぜひ参考にしてください。

「線」でマスクする。。


◼︎ SVGタグ内


<mask id = "〇〇"> 〜オブジェクト〜 </mask>

手書き風アニメーションを実装するには、SVGの<mask>要素を使います。
id属性を付け、参照出来るようにしておきます。

◼︎ CSS


element { mask:url(#〇〇); }

マスクを掛けたい要素に対して、maskプロパティにurlを参照させることで実装できます。

こちらの画像。前面に重ねた円で背面の正方形をマスクしてみましょう。

結果はこのように。
前面オブジェクトでクリップされているみたいですが、正方形の色がマスクをかける前より薄くなっています。

SVGにおけるマスクは、マスクを掛けられる側のオブジェクトを「隠す」役割ではありません。
マスクを掛ける側のオブジェクトの「不透明度」を掛けられる側のオブジェクトに「移植する」働きをします。
前面にあった円の不透明度が正方形に移植されたため、色合いも変わってしまったのですね。


webカラーで一般的に使用されるRGBは、それに加えたalpha値だけによって「不透明度」が決定されますが、SVGにおける「不透明度」は、rgba全ての値を使って算出されます。
計算式は以下の通り。

「「2◼︎ SVG、ピクセルの情報から算出される不透明度」」   (0.2125*r+0.7154*g+0.0721*b)*alpha

ややこしいですね💧
もう少しお付き合いください。


rgbaのうちalpha値は「1(完全な不透明)」に固定しているとします。
通常RGB値は0〜255と、256段階に分割して表現されますが、これを0〜1の範囲で256分割して表現したとき、

マスクオブジェクトが完全な黒(RGB : 0 0 0)の時、計算結果は0〜「完全な透明」となり、マスクされる側のオブジェクトにもそれが移植され、完全な透明と成増。

完全な白(RGB : 1 1 1)のときは計算結果は1 〜「完全な不透明」となり、 マスクされる側のオブジェクトも完全な不透明に成増。

SVGのマスクは図形オブジェクトだけでなく、「線」で行うことも可能です。
マスクしてみましょう。

このようになりました。

ところで、マスクする側の線をCSSで破線にしてみましょう。
前回使ったstroke-dasharrayを使います。

破線部分はマスクされますが、隙間部分はalpha値が0 〜完全な不透明なので、背面のオブジェクトにも移植されて透明に成増。

ここで線幅を広げていきます。
もっともっと。

〜背面オブジェクトが隠れるくらいに広げました。

さらに、1つの破線で後ろのオブジェクトが完全に隠れるまでstroke-dasharrayも大きくします。プレビューしながら値を調整。

1つの破線で、背面オブジェクトが完全にマスクされました。
〜この状態を①としましょう。

同じく前回使用したstroke-dashoffsetでdasharrayと同じ長さ分、破線のスタート位置をずらします。

破線の隙間部分に背面オブジェクトがすっぽり入ってしまっているので、何も見えなくなりました。
〜これが②。そして、

時間経過とともに②→①と変化させれば、徐々に背面オブジェクトが表示されていくアニメーションができます。

この仕組みを使って、背面オブジェクトをテキスト、前面オブジェクトを「手書きの軌道」にすれば、テキストを描いていくようなアニメーションが実現するのです。
実際に作っていきましょう。

画像作成。


画像から作っていきます。

これがマスクされる側のテキストオブジェクト。デバイスのフォントに依存しないよう、アウトライン化しておきましょう。

その上から、筆運びの軌跡を線でなぞってマスクオブジェクトを作っっていきます。
わかりやすいよう、ひとまずマスクの線にも色を付けています。

このとき鉛筆ツールなどのフリーハンド系を使用してもいいのですが、アンカーポイントが大量に生成されてしまうので、ペジェ(ペンツール)を使うことをおすすめします。

一通りなぞったら、背面のテキストが隠れるまで線幅を広げていきましょう。

このとき、アニメーションの進行上まだ見せたくない部分に線が干渉しないよう、線の位置や軌道をダイレクト選択ツール(ノードツール)を使って微調整しながら作業を進めてください。

出来上がったら、SVG形式で書き出します。

コーディング。


ではいよいよコーディングしていきましょう。
今回はプレビューしやすいよう、HTMLの<body>〜</body>内にインラインで表記しました。

◼︎ HTML

<body> 「「4<!--テキスト部分-->」」 <path d = ・・・ 「「3〜略〜」」 「「4<!--マスクに使う線-->」」 <path d = ・・・ 「「3〜略〜」」 />

まづはそのままプレビュー。このようになっています。



「「3<!--マスクに使う線-->」」 <path 「「1 id = "mask-line"」」 d = ・・・ 「「3〜略〜」」 />

マスクする側の線オブジェクトにid名を付けます。「mask-line」としました。
そしてCSSで参照し、stroke-dasharrayを広げていきましょう。

◼︎ CSS

#mask-line { 「「1stroke-dasharray:500px;」」 }

‥まだまだ短いですね。1つの破線が線オブジェクトいっぱいの長さになるまで、もっと広げていきます。

現在2600px。破線が線オブジェクトいっぱいの長さになりました。
次にstroke-dashoffsetを変化させるアニメーションを仕込んでいきます。

◼︎ CSS


#mask-line { stroke-dasharray:2600px; 「「1animation:h-written 6s infinite;」」 } @keyframes h-written { 「「10% { stroke-dashoffset:2600px; } 100% { stroke-dashoffset:0px; }」」 }


animationプロパティの内容は、

・アニメーション名 : h-written
・継続時間 : 6s
・繰り返し : inifinite(無限大)

としました。

キーフレームですが、0%ではstroke-dashoffsetを先ほど指定した2600px、100%で0px。
破線部分が徐々にテキストに重なっていく仕組みです。

プレビューはこんな感じ。
それでは、線オブジェクトで背面のテキストをマスクしましょう。参照出来るよう、要素id属性を付けていきます。

「「3<!--テキスト部分-->」」 <g 「「1id = "text"」」> <path d = ・・・ 〜略〜 </g> 「「3<!--マスクに使う線-->」」 「「1<mask id = "mask-ani">」」 <path id = "maskline" d = ・・・ 〜略〜 /> 「「1</mask>」」

テキスト部分はSVGで書き出された段階で<g>〜</g>でグループ化されていると思います。id名を「text」とします。また線オブジェクトの外側を<mask>〜</mask>で囲み、id名を「mask-ani」とします。

◼︎ CSS

#text { mask:url(#mask-ani); }

CSSで#textをマスク。url先を#mask-aniに指定。
プレビューしてみましょう。

いい感じですね。

では最後の仕上げ。線オブジェクトにはプレビューしやすいように色を付けたまま作業を進めてきましたが、背面のテキストが完全に不透明になるよう、線の色を完全な「白」に指定します。

◼︎ CSS

#mask-line { stroke-dasharray:2600px; animation:h-written 6s infinite; 「「1stroke:#fff;」」 }

結果はこちら⬇︎。

完成です。お疲れ様でした!

理解していれば応用も。


最後までお読みいただき、ありがとうございました。
今回は難解なmask要素の挙動と破線プロパティ操作の合わせ技でした。外部ライブラリなどを使用せずに原始的な手順をお伝えしたのは、仕組みを理解していれば応用が広がるからです。

仕組みを理解できた皆さんなら、例えば、虹を架けるアニメーションなんかにも簡単に応用できますね!

他にも新たな使い道を探してみてください。ではまた〜 ♩



関連記事

SVGアニメーション04、軸を基準に拡大/縮小 〜

2020.06.13
〽️ 「切実な一言」に使おう。


SVGアニメーション、エンドレスに流れる画像。

2020.07.23
〽️ タイトル部分に使えそう?ふふふ。


SVGアニメーション06、アニメーションに合わせてテキストの色を反転。

2020.07.15
〽️ 3つの長方形を動かします。











「ふ」です。

swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。