Blog本サイトはJavaScriptが有効の状態にないと正常に表示されません。このメッセージが表示される場合、ブラウザの設定状況をご確認ください。長野県を拠点に活動するフリーランスのグラフィック&WebデザイナーのWebサイトです。アニメーション文字を書き順通りに徐々にアニメーションさせて描画する「ハンドライティングアニメーション」をSVGで実装する方法。同じようなことをやっていて、それのSVGバージョン。場合は、当然ながら動画として出力しvideo要素で動画を埋め込んで表示させるわけだけど、SVGの場合は、(主に)インラインSVGを設置してJavaScriptでアニメーションさせて実現する。前までは、一部のブラウザでうまく表示できなかった(気がした)が、今は全く問題なく表示させることができるようになっていた。古いIE(10以前)ではさすがに無理だけど、もう考慮する必要はないと思われるので、十分に使える表現だと思う。SVGの作成が意外に面倒だったので作成時のポイントとか、HTMLへ設置する方法、JS実装ではまった点等を覚書として書いておく。ハンドライティングアニメーションとは正直、正式な名称はよく分からないんだけど、以下のようなアニメーションを「ハンドライティングアニメーション」と勝手に呼んでいる。これをSVGで表現する場合、SVGのマスキング(mask要素)を用いる方法とクリッピング(clipPath要素)を用いる方法の2通りの方法がある。両方とも試してみて、簡単なデモも作ってみた。DEMOChrome、Safari、Firefoxでは、どちらも問題なく表示できているけど、EdgeとIE11ではクリッピングを用いた方法がうまく表示できていない。理由はよく分からなかった(SVGの書き方がよくないのかもしれない)が、記述的にもマスキングの方がシンプルなので、実際に使用する際はmask要素を用いた方法でやるのがいいと思う。ちなみにJSはどちらも同じ。デモのコード一式はGitHubにアップしてある。svg-handwriting-animation大まかな仕組みや必要なものざっくりと解説すると以下のような感じになる。前述の通り、この実装には2通りの方法があるが、どちらの場合もそのものの形をあらわすベースとなるSVG画像(以下「ベース画像」という)とベース画像に沿ってアニメーションするSVG画像(以下「アニメーション画像」という)の2つのSVGが必要となる。ベース画像はそのものの形をあらわす外枠となる画像なので、必然的にクローズドパスとなるが、アニメーション画像は一方向に進むだけの画像なので、基本的にはオープンパスとなる(絶対ではない)。今回は、JSの実装上、アニメーション画像のSVGはpath要素で構成されている必要があるので、その点だけ注意が必要。クローズドパスでも複雑な形であればpath要素で出力されるし、オープンパスでもpath要素で出力されない場合もある。設定でも変わってくると思うので、出力されたSVGコードの確認は必須。余談だけど、ベース画像をSVG画像ではなく、SVGのtext要素で代用することもできた。位置を合わせるのが非常にめんどくさいのと、レスポンシブ化がほぼほぼ不可能なのでやらない方がいい。なると全長が表示される)。それに伴いベース画像が塗りつぶされていくように見える手で書いたような(ハンドライティング)アニメーションになるという感じ。SVGのstrokeDasharrayとstrokeDashoffsetを利用したアニメーションは前からよくあるけど、これとマスク(またはクリッピング)の効果を利用しているという点が肝になってる。SVG画像の作成まず、mask要素を用いる方法の場合、ベース画像は外部SVGファイル、アニメーション画像はインラインSVGが必要になる。ベース画像はSVG形式でなく、透過のPNG形式でも大丈夫だけど、Retinaディスプレイ等で閲覧した場合、ぼやけることがあるのでSVG形式がオススメ。clipPath要素を用いる方法の場合には、ベース画像、アニメーション画像ともにインラインSVGとなる。作成のポイントSVG画像を作成する際のポイントは以下の通り。path要素で出力されるよう考慮するベース画像、アニメーション画像ともに同じ大きさ(viewBox値)となるようにする作成方法SVGを作成するツールはなんでもいい。以下はイラストレーターを使用した場合の記載となる。文字(テキスト)をアニメーションさせる想定で進める。同じアートボード上にベース画像、アニメーション画像を同時に作成していく。新規作成まず、カラーコードをRGBにして新規ドキュメントを作成する。大きさは適当でいいけど、小さすぎるとSVGに出力した際に数値がおかしくなるので、なるべく大きめで作っておく。ベース画像の作成ベース画像は、文字ツールを使って好きなテキストをタイプし、アウトライン化する。カーニングとかは適当に。ベース画像はこれだけで完了。テキストをアウトライン化アニメーション画像の作成アニメーション画像は、ベース画像に合せて描画させたい順(アニメーション順)にペーンツールでアンカーポイントを打っていき、線(の太さ)で覆っていく。赤がアニメーション画像(色はなんでもいい)。分かりやすいように不透明度を下げているパスは、文字ごとに分けても、繋げられるだけ繋げてしまってもいい。文字ごとに分けた方が線の太さを途中で変えられたり、pathごとに色を変えることができたりするので柔軟性が高くなる。オープンパスが基本だけど、SVGに出力された時にpath要素として出力されればいいので、閉じてしまってもpath要素で出力されていれば問題はない。パスが直線の場合は、オープンパスであってもline要素として出力されてしまうので、もし一直線のパスがある場合には「複合パス」にしておくことでpath要素で出力されるようになる(ここはイラストレーターの設定によって変わるかもしれないが念のため)。一直線のパスは「複合パス」にしておくベース画像を全てパス(線)で綺麗に覆うことができたらアニメーション画像は完了。ついてベース画像とアニメーション画像は別々に使用するわけだけど、個別にSVGとして保存してしまうとviewBoxの値が異なってしまうので、一旦、それぞれでグループ化だけしておいて(レイヤー名を半角英数でつけておくと分かりやすい)一緒にSVG化してしまうのがいい。viewBoxの値はアートボードの大きさと同じになるため、(大きい方の)アニメーション画像に合わせたサイズに調整しておく必要がある。アニメーション画像は「線」だけでできているので、そのままだと「線」を含めた正確な大きさが分からない。正確な大きさを割り出したければ、一旦「オブジェクト」→「パス」→「パスのアウトライン」でパスをアウトライン化すれば正確な値を知ることができる(小数点は繰上げでおk)。SVGで保存SVGにする方法はいくつかあるが、「別名で保存」からのファイル形式を「SVG(svg)」にして「保存」すると、「SVGオプション」→「詳細オプション」でいろいろと設定できて分かりやすかった。プロパティ」を「スタイル要素」としておくと色々と捗る。「小数点以下の桁数」は、1〜3ぐらいにして、「エンコーディング」は「UTF-8」。「レスポンシブ」にチェックを入れるとwidthやheightが省略されるようなので、チェックを入れた場合には、CSS側で設定する必要がある。設定の問題なのかもしれないけど「書き出し」でSVG化するとワンライン(改行が削除された状態)で出力されてしまい、その後の加工が大変になる。「別名で保存」の場合には、適度に整形されていて扱いやすかった。これでSVGの作成は完了。作成したSVGをエディタで開き、ベース画像とアニメーション画像に分離する。イラストレーターでそれぞれグループ化してあれば、ベース画像とアニメーション画像はg要素で分離され、id属性にレイヤー名がセットされているはず。マスキングの場合アニメーション画像の部分をg要素ごと切り取り、HTMLの任意の場所へ貼り付ける。g要素はmask要素へ変更しid属性を付加、defs要素でラップした上でsvg要素でマークアップする。各path要素にclass属性をセットし、各path要素にあったstroke-width値をCSSで指定し、fill:none;とstroke:#fff;を全path要素へCSSであてる。アニメーション画像を切り取って残った部分は、ベース画像として利用するため、不要な部分(style要素とか、g要素もいらない)を削除した上で、svg要素にfill属性を付加し描画させたい色を指定する(ここ重要)。path要素ごとにfill属性をセットすれば、それぞれで色を切り替えることもできる。マスキングの場合、ベース画像は外部ファイルとするので、これを保存して、HTMLのsvg要素にimage要素を追加し、xlink:hrefとmask属性でアニメーション画像とベース画像をリンクさせる。あとはコードを見れば分かる。}}マスク効果の黒を透明にし白を描画色で表示するという性質を利用しているので、アニメーション画像を白くして(stroke:#fff;)、ベース画像自体に表示させたい色を指定している。クリッピングの場合クリッピングの場合は、ベース画像、アニメーション画像ともにインラインSVGとしてHTMLへ貼付する。ベース画像部分をclipPath要素で囲み、色はアニメーション画像で指定する。関連づけが必要になるので、アニメーション画像はg要素で囲んでおく。クリッピングに関しては、コードを見ればだいたい分かると思う。CSSは上記と同じなので省略。</g></svg>JavaScriptでアニメーションはじめに、JSについては以下を大いに参考にさせてもらいました。alphabet-svg使い方などSVGのアニメーションは、JSのrequestAnimationFrameで行っている。ライブラリを利用するのが手っ取り早いが、requestAnimationFrameを使いたかったのでライブラリは使用しなかった。使い方は、querySelectorAllでアニメーションさせたいSVGのpathを取得して、newしてplayAnimation()を実行すれば動く。SVGの構成なりが間違っていなければ、配置したpath順に次々自動でアニメーションを開始する。引数に要素(path要素を指定)、第二引数にスピード(数が小さい方が早い)、第三引数にpath間のインターバル(ミリ秒)phw.playAnimation();EdgeとIE11では、querySelectorAllで取得した要素(NodeList)をforEachで配列として渡せない(Arrayではないから?)ようなので、Array.fromでNodeListからArrayを生成すればいけた。アニメーションのスピードに関して、一貫して(全長で)同じ速度でアニメーションさせたかったため、一般的なアニメーションにおける時間単位の指定ではなく、ただの数値(小さいほど早い)を第二引数に指定することでアニメーションスピードを変更できるようにした。「全長で何秒」みたいな指定が理想だったんだけど、速さ・時間・距離みたいなのが苦手すぎて無理だった(もう考えたくなかった)。個人的に、newを配列に突っ込んでforEachで回してインスタンスを生成するっていうのが新たな発見だった。forEach便利すぎて使いまくってる。JavaScriptに関しては、ほぼ全ての部分ではまったし、自信ないので変なところがあったら教えてもらいたいです。終わりこれ読んで実装できる人は、これ読まなくても実装できるんじゃないかってくらいの内容ですが、あくまでも自分用のメモなのでご容赦ください。読んでいただいて間違いとかあったらお気軽に指摘していただけれると嬉しいです。MonSVGでハンドライティングアニメーションを実装する文字を書き順通りに徐々にアニメーションさせて描画する「ハンドライティングアニメーション」をSVGで実装する方法。同じようなことをやっていて、それのSVGバージョン。正確には「バブリング」とは呼ばないと思うし、ちょっと意味合いが違うかもしれないけど、CSSで子要素に与えたtransitionが親要素へ伝播し、アニメーションの挙動をおかしくさせる現象に何度か遭遇した。vol.7」に参加および登壇させていただきました。感は否めませんが、Webデザイナーとして、WordPressの開発環境にVCCWを...ABOUT長野県北部を拠点にフリーランスとして活動しています。Webサイトの制作をメインに、グラフィックデザインなどの制作も行っています。ARCHIVES2017年6月2017年4月2017年3月2017年1月2016年12月2016年9月2016年8月2016年7月2016年4月2016年3月2015年12月2015年10月2015年9月2015年6月2015年5月2015年3月2015年2月2015年1月2014年12月2014年11月2014年10月2014年9月2014年8月2014年6月2014年5月2014年4月2014年3。