⬆︎SVGついてのまとめページ、CSSアニメーションの基本コーナーはこちら。
こんにちは、「ふ」です。
今回はSVGを使って<h2>などの見出しを巻物風に表示させる、アニメーションを作っていきます。
見た目の表現だけであれば、テキストと巻物の中身を1つの画像として準備し、動かすことも考えられます。
しかし。
テキストも画像にしてしまった場合、見出しの数だけ別の画像を用意する必要が出てきます。また、<h2>などでは重要なキーワードを盛り込ませる場合も多いでしょう。テキストを画像データの中に組み込んでしまうと、せっかくの強調したい語句を検索エンジンに伝えることができなくなってしまいます。
そのため<h2>などのタグの意味はそのままに、そこに巻物部分のSVGを溶け込ませてしまいます。その上でアニメーション。
そうすることで強調したいキーワードを検索エンジンに伝えつつ、また画面幅の変化に対しても形を崩さずに表示することができます。
巻物自体はSVGで作成するので、色などのデザインについては後から思い通りに変更することができます。
早速、作っていきましょう。
ここでは3つの要素を作成します。
@1@ 巻物が広がった部分(見返し←というそうです)と、端っこの竹(発装←というそうです)
@2@ <h2>の見出しテキスト
@3@ 巻いてある部分(表紙←というそうです)と、軸の部分
@1@と@3@については、SVGでガリガリ書いていきます。
<div class = "area"> </div>
<div>領域を用意して、class名を「area」としました。
この中に3つの要素を配置していきます。
<svg class = 「「5"usirosvg"」」 width = "100%" height = "100%"> 「「3<!-- 見返し -->」」 <rect class = 「「5"mikaesi"」」 width = "100%" height = "100%" fill = "beige" stroke = "green" stroke-width = "10"/> 「「3<!-- 発装 -->」」 <rect class = 「「5"hatu"」」 width = "1%" height = "110%" x = "100.5%" y = "-5%" fill = "burlywood"/> </svg>
.area svg { overflow:visible; }
先づ最背面に配置する、見返しと発装の部分をSVGで作成します。
SVGはviewBoxを定義せず、widthとheightを100%とします。こうすることで親の「.area」の幅や高さが変わっても、それに合わせてSVG領域がぴったりと収まるようになります。
内部要素についても「.area」の可変に対応できるように、stroke-width(線幅)以外はすべて相対値の「%」で指定していきましょう。
見返しにはSVG領域いっぱいの線幅の太い長方形、発装には細長い長方形を作りました。
CSSの指定。
発装の長方形は「x = "100.5%」「height = "110%"」というように、親SVGの領域からはみ出してしまっています。そこでSVG自体のoverflowを「visible」とし、はみ出した部分も表示できるようにしておきます。
セレクタを「.area svg」としたのは、後ほど作成する軸の部分もはみ出しが発生するためです。そこで「.area」内のsvg要素に関しては一括で「はみ出しOK」ということにしました。
<div class = "h2soto"> <h2>まきものまきもの</h2> </div>
.h2soto h2 { padding:1em; text-align:center; }
見出し部分には<h2>を使いました。
ここでのポイントは、<h2>を親要素で囲んでおくことです。この親要素「h2soto」を使って、<h2>をアニメーションさせたときの可視範囲を指定します。
ここはお好みですが、CSSで少し内部の余白を取り、中央揃えにしています。
表紙と軸の部分です。2つの細長いrect(長方形)を重ね合わせます。
SVGでは後に記述したものが前面に表示されるため、軸の部分を先に記述。表紙の長方形とセンターが合うように、xの位置を調整しています。
現在のwebでの表示です。
上から順番に要素が並んでいますが、positionプロパティを使ってこれらを重ね合わせます。重ね順としては前面から「.maesvg → h2 → .urasvg」となるように指定します。
.area { position:relative; } .maesvg,.usirosvg { position:absolute; top:0; } .usirosvg { z-index:-1; }
position:absoluteを使うために、親要素である「.area」をrelativeに指定。
次に2つのSVGをposition:absoluteとします。absoluteを指定した要素は最前面に配置されるため、「.maesvg」についてはこれで問題ありません。「usirosvg」については最背面に持っていきたいので、z-indexで調整します。
3つの要素が希望していた順番で重なりました。
ところで、SVGで描画した長方形たちの高さが縮んでしまっているような....
それは、<svg>要素をviewBox指定なしでwebに埋め込んだとき、heightがデフォルトで150pxになるからです。そのあとposition:absoluteとしたことで、heightが具体的に決められている<h2>領域ぴったりに収まった、ということです。
それでは確認しながらアニメーションを実装していきましょう。
「巻物が開いていく」表現をするにあたって、動かしたいのは3つのパーツです。
@1@ 発装。左から右へと移動
@2@ h2。左から右へと移動
@3@ 見返し。水平方向の大きさを0→100%に。
@1@@2@については、1つのキーフレームにまとめることができます。
CSSで動かしてみます。
.hatu,.h2soto h2 { animation:idou 2s ease-in-out alternate infinite; } @keyframes idou { from { transform:translateX(-100%); } }
キーフレームについてですが、開始時(from)の状態を水平方向-100%とすることで、左から定位置へと要素が流れてくるようになります。
現在の状態⬆︎です。左から右へと動いてはいるものの、<h2>のテキストが巻物内に収まらずにはみ出してしまっていますね💧
<h2>を親要素「h2soto」で囲んでおいたのは、この問題に対処するためです。
「h2soto」のoverflowを調整してやることで解決します。
.h2soto { overflow:「「1hidden」」; }
親要素からはみ出した部分を非表示に指定しました。
<h2>のはみ出しが解消できていますね。
あとは見返し部分もアニメーションさせましょう。
.mikaesi { animation:kakudai 2s ease-in-out alternate infinite; } @keyframes kakudai { from { transform:scaleX(0%); } }
見返しの長方形についてもtranslateXを使い、左から流し込んでもよかったのですが、overflowの指定が面倒なのでscaleX(水平方向の拡大縮小)を採用しました。
タイミング関連の指定は「idou」とズレてしまわないよう、同一の指定を施しておきます。
「巻物h2」がこれで完成です。お疲れ様でした ♪
最後までお読みくださり、ありがとうございます。
今回はHTMLタグの意味付けを生かしつつ、SVGで装飾→アニメーションさせる手順について紹介してきました。
装飾についてはSVGを使用していますので、あとは自由にお好みのデザインに仕上げてください。
IntersectionObserverを使いこなす(理解編)。
2022.01.30
「動いているだけのアニメーション」の先へと進もう。
記事中ではプレビューしやすいようにアニメーションを繰り返し状態にしていますが、「スクロールで表示されたときに巻物を開く」実装をしたいと思った方もいるかもしれません。
その際にはJavaScriptのIntersectionObserverを利用すると便利です。⬆︎の記事で紹介していますので、ぜひ参考にしてください。
あるいは今後、「ふ」のほうでチュートリアル記事を発信するかもしれません。お楽しみに。
ではまた〜 ♫
IntersectionObserver、複数の要素や発生位置に対応する(実践編)。
2022.02.06
スクロールに応じたアニメーションを実践。
CSS+JavaScript、スクロールに合わせて要素をふわっと浮かばせる。
2022.03.01
複数や時間差にも対応。
swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。