[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アニメーションは CSS か Javascript で作るんだそうです。
CSSなら、svg要素やその子要素に、transition や animateプロパティなどで変化を指定。
Javascriptの場合は、プログラミングができないと難しそうだけど、今は SVGアニメーションのための JavaScriptライブラリもたくさんあるので、ノンプログラマーでもちょっと使ってみるくらいならできそう。
今回はまず CSSを使ったドローイングアニメーションを作ってみます。
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アニメーションを作ってみます。
- 関連記事
-
- [72] デバイスに合わせた画像を表示できる picture要素
- [71] img要素の srcset属性で画像を切り替えよう
- [70-5] 複数のSVGを1つにまとめて個別に呼び出す SVGスプライト
- [70-4] JavaScriptライブラリで作るSVGモーフィングアニメーション
- [70-3] CSSだけで作る SVGのドローイングアニメーション
- [70-2] SVGフィルターを使ってみた
- [70-1] svg要素でベクターグラフィクスを埋め込もう
- (ちょっとメモ)API って何だ?(HTML5 の API について)
- (ちょっとメモ)CanvasサイズをCSS3のvw, vhで取得してみたけど...
- [69-14] Canvasのアニメーションの基本を見てみよう
- (ちょっとメモ)Canvasでグラフを自動生成する「flotr2」が便利
- [69-13] Canvasで画像データをURLとして取得しよう
- (ちょっとメモ)Canvasで画像をランダムに描くサイト背景をWordPressで使ってみた
- [69-12] Canvasをサイトの背景に使おう
- [69-11] Canvasでビットマップを操作しよう(ビットマップの明度や色調の変更)
初心者にも使いやすい(と思う)レンタルサーバー
「初心者ですがレンタルサーバーはどこがいい?」というご質問をよくいただきます。
自由にファイルをアップロードできる自分のサーバがあると便利ですよね。ローカル環境じゃなくサーバ上で試してみたい時がありますからね。
私が使っているのは、
スターサーバーや ロリポップ!
です。どちらも管理画面がわかりやすく、マニュアルも充実していて、料金も安い。どちらもライトプラン以上で WordPress が使えます。
初心者が始めやすいサーバだと思います。
ちょっと料金は高いけど、さくらのレンタルサーバや、エックスサーバー
は、やはり老舗なのでおすすめです。
両方とも高スペックでコスパが良く、老舗でユーザーが多いので、質問する場がたくさんあります。初心者だけど仕事でサーバが欲しい場合は、安心なのではないかと思います。
スポンサーリンク