SVGで棒グラフのアニメーション。

〽️SVGをflexに配置。 〽️途中までは並走。 〽️コーディング。 〽️HTMLの部品としてのSVG。





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

こんにちは、「ふ」です。
SVGアニメーション、今回は「棒グラフ」に挑戦しましょう。

アニメーションのイメージですが、最初は各グラフの棒を並走させます。

各項目の「棒」は、それぞれの規定値に達したところでストップ。それより大きい値の物だけがその後も伸び続ける、というものです。

SVGをflexに配置。


先づはSVGでグラフの棒を作ります。単なる長方形なので、描画ソフトを使わずにコードで直接作成しました。

■ HTML

<body> <svg viewBox = "0 0 20 5"> <rect y = "40%" width = "100%" height = "20%" fill = "#db86b3"/> </svg>

幅などはお好みで。もちろんVectornatorなどの描画ソフトから作成しても問題ありません。
作成した「グラフの棒」と、項目名には<p>要素を使ってグラフをレイアウトしていきましょう。

■ HTML

<div class = "「「1soto」」"> bb<div class = "「「5koumoku」」"> bbbb<p>項目1</p> bb</div> bb<div class = "「「5bou」」"> bbbb<svg viewBox = "0 0 30 5"> bbbb<rect y = "40%" width = "100%" height = "20%" fill = "#db86b3"/> bbbb</svg> bb</div> </div>

グラフ全体を「id:soto」とし、<p>要素と<svg>を配置する領域をそれぞれ「id:koumoku」「id:bou」としました。

flexboxを使ってレイアウトしていきます。

.soto { display:flex;「「1 ・・①」」 width:80%; margin:0 auto; } .koumoku { width:20%; display:flex; align-items:center;「「1 ・・②」」 } .koumoku p { width:100%;「「1 ・・③」」 text-align:right; padding-right:1em; } .bou { width:80%; display:flex; align-items:center;「「1 ・・②」」 } .bou svg { width:100%; }


① 項目とグラフを横並びにするため、flexを指定。

② 領域内で<p>と<svg>を上下センタリングさせるための処理。それぞれの領域もflex化し、並びの照準を「center」にしています。

③ 項目名は領域内で右寄せにしたい。text-alignを効かせられるようにするためには、widthを指定してやる必要があります。


項目1

項目2

項目3

同じものを3つ作成して並べました。
「ふ」はCSS職人ではないので、レイアウトには少し苦労しましたよ、フフフ。

途中までは並走。


SVGの「棒グラフ」をアニメーションさせていくのですが、単に「到達点」まで伸ばしていくだけであれば、普通にwidthを変化させてやれば済むこと。
しかし今回、到達するまでは棒グラフは「並走」、つまり同じ調子で伸びていくようにしたい。
その仕組みについて考えてみます。

各SVGの中に、グラフ棒と同じ位置・サイズの長方形を配置した、clipPathを作成。

棒グラフ自体は、CSSを使ってwidth:0%→100%になるアニメーションを施します。

アニメーションしている棒グラフごと、先程用意したclipPathでクリップ。

この状態でCSSを使い、各SVGに置いたclipPathの長方形要素を目的の幅に変化させます。

これで。途中までは並走しつつ、到達点以降の部分は非表示になる棒グラフが実装できます。

コーディング。


では実際にコーディングしていきましょう。先程書いたコードのうち、SVGの部分を以下のように書き換えます。

■ HTML

<svg viewBox = "0 0 30 5"> <clipPath id = "clip1">「「1 ・・①」」 <rect id = "rect1" y = "40%" width = "100%" height = "20%"/> 「「1 ・・②」」 </clipPath> <g clip-path = "url(#clip1)">「「1 ・・③」」 <rect class = "bar" y = "40%" width = "100%" height = "20%" fill = "#db86b3"/> 「「1 ・・④」」 </g> </svg>

① clipPathを定義。参照のためにid「clip1」としています。

② clipPathの中には棒グラフと同じ長方形を配置。後ほどCSSでwidthを指定するので、id「rect1」とします。

③ ①のclipPathで「アニメーションしている棒グラフ」をクリップしています。
ここで<rect>要素に直接clipPathを指定すると、「アニメーション」はクリップされません。そのため、<rect>要素をグループ化し、その<g>要素に対して指定するようにしましょう。

今回はCSSではなく、SVG内部でclipPathを指定しています。表記の際、

要素として宣言する場合:
clipPath ←キャメルケース

属性値に使う場合:
clip-path ←ケバブケース

となる点に注意してください。

④ 棒グラフ実体の長方形はアニメーションさせるため、class名「bar」としておきます。



<svg viewBox = "0 0 30 5"> <clipPath id = "「「1clip2」」"> <rect id = 「「1"rect2"」」 y = "40%" width = "100%" height = "20%"/> </clipPath> <g clip-path = "url(「「1#clip2」」)"> <rect class = "bar" y = "40%" width = "100%" height = "20%" fill = "#db86b3"/> </g> </svg> <svg viewBox = "0 0 30 5"> <clipPath id = "「「1clip3」」"> <rect id = 「「1"rect3"」」 y = "40%" width = "100%" height = "20%"/> </clipPath> <g clip-path = "url(「「1#clip3」」)"> <rect class = "bar" y = "40%" width = "100%" height = "20%" fill = "#db86b3"/> </g> </svg>

2つ目と3つ目のSVGも同様に書き換えておきます。ただしHTMLにインラインで表記しているため、clipPathとその中のrectのidはユニークなものにしておいてください。CSSや属性で参照した際に汚染するのを防ぐためです。
2つ目は「clip2」「rect2」、3つ目は「clip3」「rect3」としました。

では棒グラフにアニメイションを仕込みます。

■ CSS

.bar { animation:bar 2s ease-out infinite; } @keyframes bar { from { width:0%; } to { width:100%; } }

棒グラフの長方形に、width0→100%となるアニメーションを指定。長方形自体はclass参照にしているので、timing指定とkeyframeを1組記述するだけでOKです。



項目1

項目2

項目3

仕上げに各clipPathに使用している長方形にアクセス。グラフの「到達点」としたいところに、widthを指定しましょう。

■ CSS

#rect1 { 「「1width:50%」」; } #rect2 { 「「1width:100%」」; } #rect3 { 「「1width:20%;」」 }

項目1

項目2

項目3

できました!
1度作っておけば、CSSで「rect1〜3」のwidthを書き換えるだけで、好きな「到達点」を指定することができます。お疲れ様でした。

HTMLの部品としてのSVG。


最後までお読みくださり、ありがとうございました。
今回のSVGアニメーションのサンプルは、これまで紹介してきたものと大きく違うところがありました。それは、「SVGをHTMLの部品として使用する」という点です。

普段は<p>などのHTML要素とは分離して、あくまで「挿入画像」としてSVGを扱ってきました。しかし今回は<p>と<svg>を同じflexレイアウトの中に含めてしまっています。

「あれ?テキスト部分もベクターで作ってしまえば、レイアウトも楽だったのでは?」と思った方もいるでしょう。
しかしそのテキストの内容がSEO面で認識させたいキーワードだった場合。SVG画像ではなく、通常のHTML要素として表示させたいところです。ということで、敢えてCSSを使ってレイアウトしてみました。

「HTMLの部品として」。SVGのこういった使い方もなかなか奥が深そうです。他にも試してみたくなってきた「ふ」なのでした。
ではまた〜 ♩



SVGアニメーション、 回転の中心を指定する。

2021.03.09
座標を取得して%変換。


SVG アニメーション、カメラのシャッターを再現。

2021.04.11
「アニメーションごと」重ねていく。


ページめくりアニメーション 作り方。

2021.02.02
画像を読み込むだけで実装。












「ふ」です。

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