〽️しくみ。 〽️素材作成。 〽️複製、アニメーション。。 〽️CSS講座(笑)。 〽️randomの指標を増やすもよし。
⬆︎SVGついてのまとめページ、CSSアニメーションの基本コーナーはこちら。
こんにちは、「ふ」です。
今回のSVGアニメーションは「動く集中線」を作ります。
webサイトで「パンパカパーン」な時に使いましょう。
実はこの動く集中線、アニメーション自体はすごく単純なことをやっています。久しぶりに短い記事になるかもしれません(笑)
集中線を描くのは、ベクター画像の性質を使えば簡単にできます。
細長い三角形を1つ作っておき、少しずつ回転させながら複製していきます。
そしてアニメーションは、不透明度0→1をくり返しているだけなのですが、1つ1つの3角形に対してランダムにanimation-delay(遅れ)を発生させます。これで集中線が動いているように見せることができます。
素材として用意するのは、1つの細長い3角形だけです。ベクターソフトで作るもよし、コードで直接描画するのも対して苦になりません。
イラレやVectornatorで、直接描画した場合。
細長3角形を描き、逆さまにします。アートボードの中心から適度に距離をとりましょう。
細長三角形の幅などは自由ですが、このあとコードで回転させながら複製していきます。
viewBox(アートボード)の対角線に重なったときにアートボードから途切れない大きさにしましょう。
この形をイメージしてコードで直接書いても構いません。
記述例がこちら⬇︎。
<svg viewBox = "0 0 400 300"> <「「1polygon」」 points = "200 130, 210 -200, 190 -200"/> </svg>
コードでも簡単に描画することができます。SVGで3角形を含む「多角形」は<polygon>要素で表現されます。
コードだけでもちゃちゃっと作成できました。
では細長三角を複製・アニメーションさせていきましょう。
その前に少しだけSVGコードを編集します。
■ HTML
<svg 「「1id = "soto"」」 > 「「4<defs>」」 <polygon 「「1id = "sankaku" class = "sen"」」 points = "200 130, 210 -200, 190 -200"/> 「「4</defs>」」 </svg>
複製した細長三角の配置先として参照できるよう、svgにid名「soto」を付けておきます。
polygon(細長三角)にはJavaScriptで取得するためのid名「sankaku」と、CSSでアニメーションさせるためのclass名「sen」を指定しました。
<defs>はdefinte(定義)という意味です。この<defs>タグで囲まれた内容はあくまでどこかで参照するための「定義」として扱われ、実際に描画されることはありません。
複製した時にマスターのpolygonも表示されていると少しややこしくなるので、「非表示」にする目的で<defs>を使いました。
これを10°ずつ回転させながら複製していきます。
transformを使うので、変形の基準を中央にしておきましょう。
■ CSS
.sen { transform-origin:center; }
それではJavaScriptで複製します。
■ JavaScript
「「3//外側のSVGを取得」」 const soto = document.getElemntById("soto"); 「「3//細長3角形を取得」」 const sankaku = document.getElementById("sankaku"); 「「3//10°ずつ増やしていく角度を宣言しておく」」 let kakudo = 0; 「「3//10°ずつなので、36回複製する」」 for(i = 0;i<=35;i++) { 「「3//細長3角を複製」」 let clone = sankaku.cloneNode(true);「「1...①」」 「「3//transformで角度を付けていく」」 clone.style.transform = "rotate(" + String(kakudo) + "deg)"; 「「3//外側のSVG要素に追加」」 soto.appendChild(clone);「「1...②」」 「「3//角度を10°増やす」」 kakudo += 10;「「1...③」」 }
① cloneNodeメソッドで細長3角を複製しています。引数の(true)は、子孫要素も含めて複製する場合に、このように記述します。
最新のブラウザではtrueの場合は引数を省略できる、と仕様書にありましたが、現状は記述しておいたほうが無難です。
② ポイントは、<defs>の中身である<polygon>のみを取り出して複製・svgに追加しているところです。こうすることによって定義部分の要素は描画されることなく、複製→追加されたものだけが実際に描画されることに成増。
③ 角度を追加する変数「kakudo」を使って、for文を繰り返すごとに10°ずつその値を増やしていきます。
現在の状態がこちら⬆︎。回転/複製ができています。
ここに不透明度を変えるCSSアニメーションを指定します。
■ CSS
.sen { transform-origin:center; animation:sen 0.5s alternate infinite; } @keyframes sen { to { opacity:0; } }
複製した細長三角の1つ1つにアニメーションが施されました。
仕上げです。1本ごとのアニメーションにランダムなanimation-delayを掛けます。複製したcloneのstyle属性に、ランダムな遅れを指定しましょう。
さっきのfor文の中に追加します。
■ JavaScript
for(i =0;i<=35;i++) { let clone = indiv.cloneNode(true); clone.style.transform = "rotate(" + String(skakudo) + "deg)"; 「「1clone.style.animationDelay = String(Math.random()) + "s";」」 gaib.appendChild(clone); skakudo += 10; }
JavaScript内にCSSのプロパティを記述する際は、「animationDelay」とキャメルケースになる点に注意してください。
できました!
あとはタイミングや色、線の数など、お好みで調整してくださいね。2種類の集中線を重ねてみる、というのも面白いかもです。
■ center.png
集中線のアニメーションが完成したので、実際に真ん中に要素をおいてみます。
⬆︎のちょっとダサい画像、「center.png」で試してみます。この画像のid名は「centerelm」としました。
■ HTML
「「1<div class = "mannaka">」」 bb<img 「「5id = "centerelm"」」 src = "center.png"> bb<svg id = "soto"> bbbb 〜 略 〜 bb</svg> 「「1</div>」」
集中線のSVGと真ん中におきたい要素を1つの<div>要素の中に配置します。
集中線の真ん中に要素を配置しましょう。CSSでよく使われるposition:relativeとabsのセットで行います。
■ CSS
.mannaka { position:relative; } #centerelm { position:absolute; }
absoluteを指定した要素の中央寄せは次の手順でおこないます。
top,leftを50%に指定。
この「50%」は親要素(黄色)の「mannaka」に対する比率で反映されます。すると子要素(青)の左上が親要素の中央に揃います。
次にtransform:translateでx,y方向ともに-50%ずつ移動。
ここでの「-50%」は、子要素自身の大きさに対する比率だと解釈されます。それにより、子要素と親要素の中心が一致します。
CSSを追加します。
#centerelm { bbposition:absolute; bb「「1top:50%; bbleft:50%; bbtransform:translate(-50%,-50%);」」 }
要素によけいなmargin,paddingがついているとうまくいかないので注意してください。
集中線を前面に重ねたい場合は、svg要素にposition:relativeを指定してz-indexを調整します。
■ CSS
#soto { position:relative; z-index:3; }
集中線が前面に回り込みました。
パンパカパーンの対象がテキストの場合は可読性を考え、真ん中の空洞を調整したりしたほうが良さそうです。
最後までお読みくださり、ありがとうございました。
今回はSVGを使った「集中線アニメーション」を作ってみました。比較的簡単に実装できましたね。
集中線のアニメーションはYouTubeでもよく見かけます。あちらに関しては線の幅や位置もランダムに発生させているみたいです。興味ある方はMath.randomを使って歪ませてみてください。
ではまた〜 🎵
SVGでボタンアニメーション【Web Animations API】。
2020.12.19
event.targetからオブジェクトを動かす。
swift、web、ガジェットなど。役立つ情報や観ていてたのしいページを書いていきたいと思います。