[70-3] CSSだけで作る SVGのドローイングアニメーション

最終更新日:2017年11月16日  (初回投稿日:2017年03月28日)

SVGはベクター画像なので、アニメーションにしても滑らかで美しく、サイズも軽めです。
ということで今回は、SVGアニメーションを作ってみます。

SMILってのもあるけど、将来廃止されるかもしれない...

SVGアニメーションのために SMIL(スマイル)というモノがあります。

SMIL(Synchronized Multimedia Integration Language)
XMLベースのアニメーションのための言語。<animate>要素などを使ってSVGアニメーションを作れます。(参考 - SMIL Animation - W3C Recommendation 04-September-2001

ですが、これを IEは一度もサポートしたことが無く、Edgeでもサポートする予定が無いそうです。
そして Google(Chrome)でもサポートを廃止する予定(2015年4月)と宣言したり、やっぱりそれを保留する(2016年8月)ことにしたり。SMILサポートへの要望が多かったり、CSS や JavaScript(Web Animations)では今は充分な代替にならないため、一時保留にしたそうです。

一応 W3Cでは SMILは標準仕様なのですが、Microsoftがサポートする予定がなく、Googleも代替えの手法が充分使えるようになればサポートしなくなりそう。
対応ブラウザが少なければ将来廃止になる可能性もあり、今から SMILを始めるのもなあと躊躇するような時期です。けっこう複雑な動きをプログラマーじゃなくても作れておもしろそうですけどね。

SMILを使わないのであれば SVGアニメーションCSSJavascript で作るんだそうです。
CSSなら、svg要素やその子要素に、transition や animateプロパティなどで変化を指定。
Javascriptの場合は、プログラミングができないと難しそうだけど、今は SVGアニメーションのための JavaScriptライブラリもたくさんあるので、ノンプログラマーでもちょっと使ってみるくらいならできそう。

今回はまず CSSを使ったドローイングアニメーションを作ってみます。

本日のINDEX
  1. CSSによるドローイングアニメーション
    1. 線画アニメーションの原理
    2. パスの長さの測り方(Illustrator)
  2. 応用でチェックボックスやラジオボタンにアニメーションをつける
  3. 同じようなドローイングアニメが作れるJSライブラリ

CSSによるドローイングアニメーション

ラインを描いていくアニメーションです。
こんなかんじ。
長方形にマウスオーバーしてください。(PCのみ。スマホの方はゴメン)

HTML(SVGは Illustratorで描画してコピペしただけ)

<svg id="hello" version="1.1" xmlns="http://www.w3.org/2000/svg" width="305px" height="110px">
<rect fill="#F6FAF6" width="305" height="110"/>
<path fill="none" stroke="#47ACA8" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" 
d="(長いので略)"/>
</svg>

CSSはこちら

svg#hello path {
	stroke-dasharray: 863.03;  /*←破線の線分(パスの全長と同じ値にする)*/
	stroke-dashoffset: 863.03;  /*←破線の始まる位置をずらす(パスの全長と同じ値にする)*/
	transition: stroke-dashoffset 2.5s ease-out}  /*←破線の始まる位置のみアニメーションにします*/
svg#hello:hover {cursor:pointer}     
svg#hello:hover path{stroke-dashoffset:0}  /*←破線の始まる位置を0にします*/

SVGの破線のプロパティ「stroke-dasharray(破線の線分の長さ)」と「stroke-dashoffset(破線の始まる位置をずらす)」を使っています。
アニメーションはCSSの「transition」プロパティ(時間的変化)によって作っています。

線画アニメーションの原理

描いたパスをパスと同じ長さの線分の破線(点線)にして、その破線の始まる位置を変えることで、見えない状態から見える状態へ変化させるというのが原理です。(変化は transitionプロパティを使用)
何言ってんだか、わけがわかりませんよね。順を追って説明します。

stroke-dasharray は破線の線分と空きを指定します。ストローク(線)のダッシュ(破線)のarray(配列)ね。
stroke-dasharray: 20 10; だったら、線分が20px、空きが10px の破線ってことです。
値が1つだけの stroke-dasharray: 20; なら、線分も空きも同じ20px の破線ということ。

stroke-dashoffset は、破線の線分の開始位置をオフセットする(ずらす)指定です。
stroke-dashoffset: 20 なら、破線の線分の開始位置を20pxオフセット(マイナス20pxに)すること。

ではまず、stroke-dasharray: パスの長さ にして、破線の線分がパスと同じ長さのものを作ります。

通常は、破線の線分が始まるのは、パスの始まりの地点です。

これを stroke-dashoffset: パスの長さ にすると、線分の始まる位置がパスの長さぶん左にずれるので、実際のパスは「破線の空き」の部分になって見えなくなります。

stroke-dashoffset: 0 にすると、通常に戻るのでパスが見える状態になります。

こんなかんじで「パスが見えない」「見える」の2つの状態を transitionプロパティでアニメーションにしているんですね。

ちなみに、stroke-dashoffset: −(マイナス)パスの長さ からの stroke-dashoffset: 0 にすれば、パスが逆進行で描かれるアニメーションになります。

CSS

svg#hello path {
	stroke-dasharray: 863.03;
	stroke-dashoffset: -863.03;  /*←ここをマイナスにしただけ*/
	transition: stroke-dashoffset 2.5s ease-out}
svg#hello:hover {cursor:pointer}     
svg#hello:hover path{stroke-dashoffset:0}

この原理を最初に公開したのが Jake Archibald氏だそうで、この人のサイトに、原理がひと目で分かるデモが用意されています。英語ですが、とてもわかりやすいので見てみてください。
Animated line drawing in SVG - JakeArchibald.com

パスの長さの測り方(Illustrator)

CSSの「stroke-dasharray」と「stroke-dashoffset」にはパスの長さを書く必要があります。
適当な数値を(ちょっと多めに)入れても動くけど、ちゃんと線分の長さを測るのがベスト。

Illustratorなら簡単に線の長さを知ることができます
ウィンドウ>ドキュメント情報>オブジェクトを開き、長さを図りたいパスを選択するとパスの全長が表示されます。

応用でチェックボックスやラジオボタンにアニメーションをつける

上記のドローイングアニメーションを、チェックボックスラジオボタンに使ってみます。
これらの要素なら、擬似クラス「:checked」を使ってアニメーションを開始させられます。

ドローイングアニメーションのチェックボックス

まずはチェックボックス。チェックしてみてください。

HTMLはこちら。
<li>要素の中にチェックボックスと<label>要素を、<label>要素の中に<svg>を仕込んでいます。
SVGのパスは、いつものように Illustratorで描いて出力したものですが、線の色・太さ・先端の丸みなどの指定は CSSでまとめて指定するので削除しています。
Illustrator上では一応 24×24px で描きましたが、後でCSSでサイズ調整するので適当でいいです。

HTML

<form id="svgCbox">
<ul>
<li>
 <input type="checkbox" id="check1">
 <label for="check1">Check box1
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="(長いので略)"/>
  </svg>
 </label>
</li>
<li>
 <input type="checkbox" id="check2">
 <label for="check2">Check box2
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="(長いので略)"/>
  </svg>
 </label>
</li>
<li>
 <input type="checkbox" id="check3">
 <label for="check3">Check box3
  <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path d="(長いので略)"/>
  </svg>
 </label>
</li>
</ul>
</form>

CSSはこちらです。
疑似要素「::before」で <label>要素の前に SVGを囲む枠を作っています。(12・19行目)
<svg>は、親(祖父?)である<li>に対して「position: absolute」で位置を指定(34行目)
SVGのパスは、色・太さ・先端の形などをまとめて指定(36〜41行)
破線の長さや開始点も指定して(42・43行)アニメーションの準備をしています。
アニメーションで変化させたいモノには「transitionプロパティ」を指定しています(23・28・44行)
最後に擬似クラス「:checked」を使って、チェックした時の変化を指定しています(46〜48行)

#svgCbox ul {padding-left:0}
#svgCbox ul li{
	list-style: none;
	position: relative;
	margin-bottom: 10px}
#svgCbox input[type="checkbox"]{
	display: none !important;
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none}
#svgCbox input[type="checkbox"],
#svgCbox label::before{
	position: relative;
	display: inline-block;
	top:7px;
	width: 28px;
	height: 28px;
	margin-right: 10px}
#svgCbox label::before{
	content: '';
	border: 2px solid #999;
	border-radius: 3px;
	transition: border 0.2s}
#svgCbox label{
	cursor: pointer;
	font-size:20px;
	color: #999;
	transition: color 0.2s}
#svgCbox svg{
	width:24px;
	height:24px;
	left:4px;
	top:12px;
	position:absolute;
	z-index:1}
#svgCbox svg path{
	fill:none;
	stroke:#000;
	stroke-width:2px;
	stroke-linecap:round;
	stroke-linejoin:round;
	stroke-dasharray:40;
	stroke-dashoffset:40;
	transition: stroke-dashoffset 0.2s}
#svgCbox input[type="checkbox"]:focus{outline:rgba(0,0,0,0)}
#svgCbox input[type="checkbox"]:checked ~ label::before{border: 2px solid #000}
#svgCbox input[type="checkbox"]:checked ~ label{color: #000}
#svgCbox input[type="checkbox"]:checked ~ label svg path{stroke-dashoffset:0}

CSSのセレクタについて。
input[type="checkbox"] という「 [ ] 」で囲むのは「属性セレクタ」と言い、属性の内容で指定できるセレクタ。このサンプルなら「<input>要素のtype属性がcheckboxなやつ」という意味です。
他に例えば a[href="http://◯◯.com/"](<a>要素でhref属性がコレなやつ)とかいろいろ使えます。

input[type="checkbox"]:checked の「:checked」は「UI要素状態擬似クラス」と言い、チェックボックスやラジオボタンが選択された状態を指定します。これは CSS3 からできたセレクタです。

input[type="checkbox"]:checked ~ label は、2つのセレクタが「 ~ 」でつながれていますが、
これは「間接セレクタ」と呼ばれるもの。同じ親の中の兄弟要素のを指定するセレクタです。
弟とは、兄の後に登場するヤツ。間に他の兄弟があってもOK。
隣接セレクタ(要素 + 要素)のように兄の直後に登場した弟にも適用されます。
今回の例なら「type属性がcheckboxな<input>要素がチェックされた時の弟の<label>要素」を指しています。
これめっちゃ便利ですね。チェックされたチェックボックスだけでなく、そのあとの<label>までセレクタにできるなんて。これも CSS3 からできたセレクタです。

ドローイングアニメーションのラジオボタン

同じ要領でラジオボタンも作れます。

ラジオボタンは「name属性」が必須。無いと正常に動作しません。
CSSで ◯ を作るのは「border-radius: 50%」とすればOK。
その他はチェックボックスのコードと同じ要領です。

同じようなドローイングアニメが作れるJSライブラリ

SVGのパスのドローイングアニメーションを簡単に作れる JavaScriptライブラリがけっこうたくさんありますので、3つほどピックアップ。
パスの全長を測ったり、細かいCSSの指定をしなくてもいいので、複雑なパスの図形のときはこっちのほうが手っ取り早いですね。

jQuery DrawSVG

jQuery と DrawSVG を HTMLに読み込ませて使います。
パスのアニメーションだけでなく、応用で画像をパスで塗りながら表示するエフェクトも作れます。

Lazy Line Painter

同じく jQuery を使います。この↑ページの下部にある「コンバータ」に SVGファイルをドラッグ&ドロップすればコードが作られるので簡単。

Vivus

これは vivus.js 単独で動きます。 vivus.js をHTMLに読み込み、SVGに付けた idを紐付けるスクリプトを書くだけ。

次回予告

今回は、CSSだけを使った SVGのドローイングアニメーションの紹介でした。
アニメーションの部分はCSSのtransitionプロパティで作るだけでしたね。
次回は JavaScriptライブラリを使った SVGアニメーションを作ってみます。

関連記事
このエントリーをはてなブックマークに追加

やる気を保つためにランキングに参加しています。
応援してくださると すっごいやる気を出します! (笑)

初心者にも使いやすい(と思う)レンタルサーバー

「初心者ですがレンタルサーバーはどこがいい?」というご質問をよくいただきます。
自由にファイルをアップロードできる自分のサーバがあると便利ですよね。ローカル環境じゃなくサーバ上で試してみたい時がありますからね。
私が使っているのは、 スターサーバーロリポップ!です。どちらも管理画面がわかりやすく、マニュアルも充実していて、料金も安い。どちらもライトプラン以上で WordPress が使えます。
初心者が始めやすいサーバだと思います。

ちょっと料金は高いけど、さくらのレンタルサーバや、エックスサーバー は、やはり老舗なのでおすすめです。
両方とも高スペックでコスパが良く、老舗でユーザーが多いので、質問する場がたくさんあります。初心者だけど仕事でサーバが欲しい場合は、安心なのではないかと思います。

スポンサーリンク

コメントの投稿

ご注意:メールアドレスは書かないで
「コメントを送信する」ボタンを押した後の「確認画面」で、メールアドレス・URL などを入力できるようになっており、メールアドレス・URL は、そのままオートリンクになる仕様です。
当方でメールアドレスだけ削除することも、メールアドレスを非公開にすることもできません
メールアドレスは書かないでください。詳しくはこちらにまとめましたのでご覧ください。

スポンサーリンク
最新記事
Category
オススメの本
Links
Calendar
11 | 2023/12 | 01
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -
Archive
Profile

yuki★hata

Author : yuki★hata
せめて月1回の更新をめざします~。

メールフォームはこちら

スポンサーリンク
スポンサーリンク
Copyright © ほんっとにはじめてのHTML5とCSS3 All Rights Reserved.