SVG、グラデーションの
アニメーション②
〜円形編。

〽️仕組み、stop-colorを差し替える。 〽️先づは普通に。。 〽️step関数をつかう。 〽️タイムラグ対策。 〽️次はロゴに使うぞ。





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

こんにちは、「ふ」です。
SVGのグラデーションシリーズ3回目は、円形グラデーション(radialGradient)をエンドレスに広げていく、というアニメーションをつくってみたいと思います。

web上で要素のbackgroundに配置するだけで、「柔らか」な主張効果が得られます。

線形グラデーションであれば、オブジェクトの外側にグラデーションベクトルを逃がすことよってエンドレスを表現できました。
しかし、円形グラデーションの場合はベクトル全体を移動させると、円アニメーションの中心がずれてしまいます。
扨(さて)、どーしたものか。

当記事はグラデーションアニメーションの「実践編その2」という位置付けでお話ししていきます。SVGのグラデーションの基本、実践編その1については⬇︎の記事を参考にしてください。

SVGのグラデーションについて。

2021.10.23
カラーストップ/オフセットとは?


SVG、グラデーションのアニメーション ①〜線形編。

2021.10.30
パターンの繰り返しとユニット切り替え。


仕組み、stop-colorを差し替える。


作戦を立てていきます。

要素に対して、円形グラデーションの塗りを適用しました。
カラーストップは、

offset0.5の位置にblanchedalmond(茹でアーモンド)
offset1の位置にdarkcyan(ダークシアン)

としています。
アニメーションで、半径を0の状態から徐々に大きくしていきます。

アニメーション進捗0の時点、グラデーションベクトルの半径は「0」の状態です。
今回はspreadMethod属性を初期値の「pad」にしておきます。
その場合、グラデーションベクトルの乗っていない部分は直近のカラーストップの色で塗りつぶされるため、要素全体はダークシアンに染まっています。

アニメーション開始後、内側の茹でアーモンドが見え始めます。

半径が大きくなるにつれ、内側の茹でアーモンドが占める面積が大きくなっていきます。

やがて内側のカラーストップが要素の外側に出てしまうと、要素自体は茹でアーモンド1色に染まっています。

この状態で、アニメーションの1ループが終了。

2ループ目、開始の瞬間です。
もちろん1ループ目と同じなのですが、グラデーションベクトルの半径は「0」、外側のカラーストップがダークシアンなので、要素も全面ダークシアンで塗りつぶされています。

しかしここで、外側と内側のストップのカラーを入れ替えるとどうなるでしょう。

「要素は外側のストップカラーで塗りつぶされる」ので、茹でアーモンドに要素が塗りつぶされます。

そしてこれは、グラデーションベクトルの大きさは違うのですが、1ループ目終了時と同じ塗りの状態です。
ここをループ間のつなぎ目とすれば、シームレスな繰り返しアニメーションができそうです。

2ループ目では、カラー入れ替えによって内側になったダークシアンが広がっていきます。

次のループが始まる瞬間に、また内外のカラーを入れ替え。これを繰り返していけば、エンドレスな円形グラデーションのアニメーションが実現します。

先づは普通に。


それでは実装していきましょう。
最初に円形グラデーションの半径を広げていくアニメーションをSVGで実装します。 元画像については単純な2色のグラデーションなので、直接コードで描いてもさほど苦労しません。もちろんベクターソフトからSVG形式で書き出してもOKです。やりやすいほうで作りましょう。

<svg viewBox="0 0 841.9 595.3"> 「「3<!-- 円形グラデーションを定義 -->」」 <radialGradient id="「「4maru」」" cx="50%" cy="50%" r="25%" gradientUnits="userSpaceOnUse"> <stop offset="0.5" style="stop-color:blanchedalmond"/> <stop offset="1" style="stop-color:darkcyan"/> </radialGradient> 「「3<!-- 長方形 -->」」 <rect x = "10%" y = "10%" width = "80%" height = "80%" fill = "url(「「4#maru」」)"/> </svg>

定義した円形(radial)グラデーションにid「maru」を指定し、長方形のfill属性を指定する際に呼び出しています。

<radialGradient>〜 </radialGradient>の中に<animate>要素を記述します。

<animate attributeName = "r" dur = "2s" from = "0%" to = "100%" repeatCount = "indefinite"; />

「to」の値ですが、内側のカラーが要素を覆い尽くす値にしていれば問題ありません。

「ふ」も実際に何度かブラウザで表示させながら調整。結果、「130%」にしました。

円形グラデーションの半径を変化させるアニメーションは、これで完成しました。
次はstop-colorの入れ替え。CSSアニメーションで実装します。

step関数をつかう。。


2つのカラーストップの色を、SVGアニメーションの1ループごとに入れ替える。
ここはgradientのアニメーション1ループの継続時間である「2s」に対して、継続時間4sのCSSアニメーションを別途用意して、中間地点の2sで差し替えることにしました。

「カラーを入れ替える」といっても、もちろん連続変化では困ります。
時間がきたら一気に入れ変わるよう、段階変化で実装したい。ここはanimation-timing-functionの「steps」を利用しましょう。

「steps」を利用すると、アニメーションを段階変化させることができます。

animation-timing-functionのstep関数について詳しく知りたい方は、こちら⬇︎の記事をご覧ください。

<stop 「「1id = "naka"」」 offset = "0.8" style = "stop-color:き・い・ろ"/> <stip 「「1id = "soto"」」 offset = "1" style = "stop-color:み・ど・り"/>

ではSVGのアニメーションに対し、CSSアニメーションを被せていきましょう。2つの<stop>要素に対してそれぞれ施すため、idを「naka」「soto」と付け加えました。

#naka { animation:naka 4s 「「1steps(2,jump-none)」」 infinite; } @keyframes naka { to { stop-color:darkcyan; } } #soto { animation:soto 4s 「「1steps(2,jump-none)」」 infinite; } @keyframes soto { to { stop-color:blanchedalmond; } }

keyframesがto(100%)で変化するように指定がされているため、「あれ?」となった方もいるかもしれません。
stepsの第1引数を2とすると、前半が開始状態、50%の位置で終了状態に切り替わります。

結果⬆︎です。
確かにストップカラーはちゃんと入れ替わっています。

だがしかし。
いまご覧になっているブラウザの状況にもよるのですが、ストップカラーの切り替え時に一瞬「ぺカッ!」とノイズのようなものが混ざる場合があります。

タイムラグ対策。


SVG内でのアニメーションとCSSアニメーションを同時進行してはいるのですが、わずかにタイムラグが出ているみたいですね。
グラデーションの次のループ開始とCSSのストップカラーの差し替えがわずかにずれ込んだため、そのような現象になるのです。

グラデーションアニメーションのループ終了直前。
要素は内側のカラーストップの色で塗りつぶされています。その間だけは外側のカラーストップに対して何か施しても、見た目は変わりません。

この短い時間のうちに、外側カラーストップの色を変更してしまいましょう。 外側のカラーストップにほんの少し「マイナスの遅れ」を付けてやります。

#soto { animation:soto 4s steps(2,jump-none) 「「1-0.1s」」 infinite; } @keyframes soto { to { stop-color:blanchedalmond; } }

animationプロパティにanimation-delayの値を追加しました。
本来animation-delayは「遅れ」を指定するプロパティなのですが、「- 0.1s」と負の値を指定することで、外側のカラーストップの色変更だけ、0.1sぶん早めました
この短い時間であれば、要素の見た目には影響ないはずです。

ストップカラーの切り替え時にノイズが入らなくなりました。
これで完成です。お疲れ様でした!

次はロゴに使うぞ。


SVGの円形グラデーションをエンドレスにアニメーションさせる方法。
見た目は単純なものですが、数々の工夫が必要でしたね。最後までお付き合いくださり、ありがとうございました。

今回はその「原型」を作成するに留まりましたが、次回はこの円形グラデアニメーションをテキストロゴに施して、いろんな表現をしていきたいと思います。楽しみにしていてください。

ではまた〜 ♪



SVGでボタンアニメーション【Web Animations API】。

2020.12.19
event.targetからオブジェクトを動かす。











「ふ」です。

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