BLOG

CSSだけで波アニメーション

ひらの

こんにちはひらのです。

久々のブログ…
実は何を書こうかずっと悩んでいました。

世間では「史上最速の梅雨明けなるか!?」なんてニュースをやっていたりして
気が付けばクーラーを入れる生活になってたりします。

そこで今回は…

Webブラウザ×涼

として、お家でブラウザを眺めるだけで
ちょっと涼しくなるかもしれない…波のアニメーション

そんなCSSをご紹介します

まずは完成形

See the Pen wave by hirano (@_y_hirano) on CodePen.

このアニメーションでは svgcanvasJS は使っていません。

Webページの背景やボタンの背景に使用すると見た目にも楽しい装飾になるかもしれません。

それではここからは中身について解説して行きます。

HTMLはdivひとつ!

今回のサンプルのHTMLはdivひとつで作成することができます。

<div class="wave"></div>

CSSを設定するためにclassだけつけておきます。

CSSの設定

まずは、先ほどclassをつけたDIV要素に枠の設定をします。

.wave {
  position: relative;
  width: 100vw;
  height: 100vh;
  margin: 0 auto;
  overflow: hidden;
}

枠は widht: 100vw;height: 100vh; として画面いっぱいにサイズを指定します。

この後、波の設定で位置を指定したいので position: relative; を指定しておきます。
そして、エリア外の表示を見えなくするために overflow: hidden; も入れておきます。

波本体

次に、波の本体部分を設定します。

先ほどのcssの中に疑似要素で波になる要素を作成します。

.wave {
    ...中略...
    &::before {
        position: absolute;
        top: 50%;
        left: -50%;
        width: 200%;
        aspect-ratio: 1 / 1;
        transform-origin: center center;
        content: "";
    }
}

まずは
width: 200%; で親要素の2倍の幅を指定します。

この要素は正方形にしたいので、 aspect-ratio: 1 / 1;アスペクト比1:1にします。

そうした疑似要素を position: absolute; で配置します。
親要素の一番下の辺の左右の中央 を基準点にしたいので
transform-origin: center center; を指定したうえで、TOPとLEFTの位置を決めます。

このままでは見た目で分からないので波っぽい見た目を付けます

.wave {
    ...中略...
    &::before {
        position: absolute;
        top: 50%;
        left: -50%;
        width: 200%;
        aspect-ratio: 1 / 1;
        transform-origin: center center;
        background-image: linear-gradient(90deg, #0083cf 0%, #76e5e1 50%, #bbe6ff 100%);
        border-radius: 50% 50% / 50% 80%;
        content: "";
    }
}

グラデーションの背景と角丸を設定しました。

色は波っぽい色を適当に付けました。
皆さんお好きな色を指定してください。
ピンクや黄色なんかを設定するとメルヘン仕様にもできるかもしれません。

角丸の設定は「/」を使って四方をちょこっと複雑に設定します。

border-radiusの設定

分かりやすいように、4つの値をそれぞれ異なる値にして解説します。

border-radius: 100px 75px / 150px 50px;

この設定の場合場合…
次のように設定されています。

こうすることで通常の角丸よりも複雑な形状を設定できるようになります。

今回の波の例では次のような円形が少し崩れたような形にしました。

アニメーションで動かす

疑似要素で作った要素をアニメーションで動かして波っぽく見せていきます

.wave {
  ...中略...
  &::before {
    position: absolute;
    top: 50%;
    left: -50%;
    width: 200%;
    aspect-ratio: 1 / 1;
    background-image: linear-gradient(90deg, #0083cf 0%, #76e5e1 50%, #bbe6ff 100%);
    border-radius: 50% 50% / 50% 80%;
    transform-origin: center center;
    transition: top 2s ease;
    animation: anime linear 12s infinite;
    content: "";
  }
@keyframes anime {
  from {
		transform: rotate(0);
	}
	to {
		transform: rotate(360deg);
	}
}

アニメーションの呼び出しは animation: anime linear 12s infinite; です。
12秒で1周するアニメーションにしました。

肝心のアニメーションはキーフレームを使って
要素の角度を360度回転するように設定しています。

たったこれだけで終わりです。

どうして波っぽく見えるのか

ただ回転しているだけのアニメーションで
なぜ波のように見えるのか…

種明かしです

.wave の要素は、こちらの図の黒いエリアだけが見えるようになっています。
その要素よりも大きなサイズで疑似要素を作成しています。

見える範囲の下の方に少しだけ被るような位置に疑似要素を配置し、
グルグルと360度回転をさせます。

疑似要素は先ほどの border-radius で歪な形にしていたので、
見える範囲を限定にすることで、波の動きの様に見えてきます。

まとめ

以上がCSSだけで波っぽく見せる方法でした。

CSSだけで波っぽく見せることができるのはお手軽で良いですね。

これでブラウザでサクッと夏っぽく涼しげなアニメーションを楽しむことできますね(=゚ω゚)ノ

この方法は見えるエリアよりも倍近く大きな疑似要素を常に動かすため、
巨大すぎる範囲や、一度にたくさんの要素でアニメーションを実施するとブラウザの挙動が遅くなる場合がありますので
実際に使うときはパフォーマンスなどにご注意ください。