• Web制作
  • blurを使ったグラデーションを作成し、アニメーションさせる

blurを使ったグラデーションを作成し、アニメーションさせる

今回、背景にグラデーションを設定し、それをアニメーションさせるサンプルを作ってみました。

こちらのサンプル画像では、画質を結構落としているので、グラデーションがブロックになっている部分があります。よろしければ、こちらのサンプルページを確認してください。

サンプルページ – blurを使ったグラデーションを作成し、アニメーションさせる

さて、このようなアニメーションを設置する場合、canvasタグにシェーダー言語を使うのが一番だと思います。ですが、使い方が結構難しく、簡単に実装できるとは言いづらいです。
そこで、今回は代用として、一般的なCSSとアニメーションを組み合わせて、似たようなものを作ってみました。

今回の仕組みについて

今回のサンプルでは、背景に色を設定したタグを配置し、blurを使ってぼかしています。そうすることで、グラデーションに似た効果を得ることができます。
そして、その上に別のタグを用意して、テキストなどを配置しています。

背景タグの準備

さて、早速背景となるタグについて考えていきます。まず、色が一色では、変化がわかりづらいので、複数の色を使いたいと思います。そこで、背景となるタグを配置し、さらにgridを設定します。そして、色を設定するための四つのタグを、追加で配置します。空タグになってしまうのは、しょうがないですね。

また、追加するタグのサイズは、等分で問題ないのですが、今回は個々に大きさを変える(グリッドを変える)ことで、ちょっとしたズレを加えています。

<style>
body {
    width: 100%;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    font-family: 'Shippori Mincho', serif;
    color: #555;
}

.container {
    width: 400px;
    height: 400px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.bg {
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-columns: 40% 35% 25%;
    grid-template-columns: 40% 25% 35%;
}

.bg__box1 {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
    z-index: 10;
    background-color: hsl(14, 100%, 86%);
}

.bg__box2 {
    grid-column: 2 / 4;
    grid-row: 1 / 3;
    z-index: 9;
    background-color: hsl(63, 100%, 83%);
}

.bg__box3 {
    grid-column: 1 / 3;
    grid-row: 2 / 4;
    z-index: 8;
    background-color: hsl(108, 100%, 82%);
}

.bg__box4 {
    grid-column: 2 / 4;
    grid-row: 2 / 4;
    z-index: 7;
    background-color: hsl(192, 100%, 80%);
}
</style>

<div class="container">
    <div class="bg">
        <div class="bg__box1"></div>
        <div class="bg__box2"></div>
        <div class="bg__box3"></div>
        <div class="bg__box4"></div>
    </div>
</div>

ブラウザで確認すると、このような見た目になります。

そして、gridを設定したタグに対して、blurを設定します。数字は、大きめの方が良いと思います。
また、今回のサンプルでは、gridを設定したタグを背面に潜り込ませるため、親タグを用意しpositionを使用しています。試していないので、どうなるかわかりませんが、もしも親タグにblurを設定してしまうと、文字部分もぼやけてしまいそうな気がします。

<style>
body {
    width: 100%;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    font-family: 'Shippori Mincho', serif;
    color: #555;
}

.container {
    width: 400px;
    height: 400px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.bg {
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-columns: 40% 35% 25%;
    grid-template-columns: 40% 25% 35%;
    filter: blur(30px);
}

.bg__box1 {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
    z-index: 10;
    background-color: hsl(14, 100%, 86%);
}

.bg__box2 {
    grid-column: 2 / 4;
    grid-row: 1 / 3;
    z-index: 9;
    background-color: hsl(63, 100%, 83%);
}

.bg__box3 {
    grid-column: 1 / 3;
    grid-row: 2 / 4;
    z-index: 8;
    background-color: hsl(108, 100%, 82%);
}

.bg__box4 {
    grid-column: 2 / 4;
    grid-row: 2 / 4;
    z-index: 7;
    background-color: hsl(192, 100%, 80%);
}
</style>

<div class="container">
    <div class="bg">
        <div class="bg__box1"></div>
        <div class="bg__box2"></div>
        <div class="bg__box3"></div>
        <div class="bg__box4"></div>
    </div>
</div>

こちらもブラウザで確認すると、このような見た目になります。

アニメーションの設定

次に、色が変化するようにアニメーションを設定します。今回はわかりやすくするため、バラバラの色を使っていますが、もちろん同系色で揃えても大丈夫ですし、そちらの方がきれいになりそうです。

また、アニメーションをループさせたいので、transitionではなくanimationを使用しています。あと、アニメーションの秒数をずらし、ちょっとランダムに変化しているような雰囲気も加えています。

<style>
body {
    width: 100%;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    font-family: 'Shippori Mincho', serif;
    color: #555;
}

.container {
    width: 400px;
    height: 400px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.bg {
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-columns: 40% 35% 25%;
    grid-template-columns: 40% 25% 35%;
    filter: blur(30px);
}

.bg__box1 {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
    z-index: 10;
    animation: box1 linear 6s infinite;
}

@keyframes box1 {
    0% {
        background-color: hsl(14, 100%, 86%);
    }

    33% {
        background-color: hsl(14, 100%, 80%);
    }

    66% {
        background-color: hsl(15, 100%, 94%);
    }

    100% {
        background-color: hsl(14, 100%, 86%);
    }
}

.bg__box2 {
    grid-column: 2 / 4;
    grid-row: 1 / 3;
    z-index: 9;
    animation: box2 linear 4s infinite;
}

@keyframes box2 {
    0% {
        background-color: hsl(63, 100%, 83%);
    }

    33% {
        background-color: hsl(63, 100%, 71%);
    }

    66% {
        background-color: hsl(62, 100%, 95%);
    }

    100% {
        background-color: hsl(63, 100%, 83%);
    }
}

.bg__box3 {
    grid-column: 1 / 3;
    grid-row: 2 / 4;
    z-index: 8;
    animation: box3 linear 8s infinite;
}

@keyframes box3 {
    0% {
        background-color: hsl(108, 100%, 82%);
    }

    33% {
        background-color: hsl(108, 100%, 74%);
    }

    66% {
        background-color: hsl(108, 100%, 91%);
    }

    100% {
        background-color: hsl(108, 100%, 82%);
    }
}

.bg__box4 {
    grid-column: 2 / 4;
    grid-row: 2 / 4;
    z-index: 7;
    animation: box4 linear 7s infinite;
}

@keyframes box4 {
    0% {
        background-color: hsl(192, 100%, 80%);
    }

    33% {
        background-color: hsl(192, 100%, 69%);
    }

    66% {
        background-color: hsl(191, 100%, 93%);
    }

    100% {
        background-color: hsl(192, 100%, 80%);
    }
}
</style>

<div class="container">
    <div class="bg">
        <div class="bg__box1"></div>
        <div class="bg__box2"></div>
        <div class="bg__box3"></div>
        <div class="bg__box4"></div>
    </div>
</div>

今回のサンプルでは色だけを変更していますが、拡大・縮小や位置を変化させると、もっと面白い効果になると思います。

テキスト用タグの配置

最後に、テキスト用のタグを、上に配置します。

最終版のHTML

<style>
body {
    width: 100%;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    font-family: 'Shippori Mincho', serif;
    color: #555;
}

h1 {
    font-family: 'Lobster';
    font-size: 1.6rem;
    text-align: center;
    margin-bottom: 1rem;
}

p{
    margin-bottom: 1rem;
}

.container {
    width: 400px;
    height: 400px;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.bg {
    width: 100%;
    height: 100%;
    display: grid;
    grid-template-columns: 40% 35% 25%;
    grid-template-columns: 40% 25% 35%;
    filter: blur(30px);
}

.bg__box1 {
    grid-column: 1 / 3;
    grid-row: 1 / 3;
    z-index: 10;
    animation: box1 linear 6s infinite;
}

@keyframes box1 {
    0% {
        background-color: hsl(14, 100%, 86%);
    }

    33% {
        background-color: hsl(14, 100%, 80%);
    }

    66% {
        background-color: hsl(15, 100%, 94%);
    }

    100% {
        background-color: hsl(14, 100%, 86%);
    }
}

.bg__box2 {
    grid-column: 2 / 4;
    grid-row: 1 / 3;
    z-index: 9;
    animation: box2 linear 4s infinite;
}

@keyframes box2 {
    0% {
        background-color: hsl(63, 100%, 83%);
    }

    33% {
        background-color: hsl(63, 100%, 71%);
    }

    66% {
        background-color: hsl(62, 100%, 95%);
    }

    100% {
        background-color: hsl(63, 100%, 83%);
    }
}

.bg__box3 {
    grid-column: 1 / 3;
    grid-row: 2 / 4;
    z-index: 8;
    animation: box3 linear 8s infinite;
}

@keyframes box3 {
    0% {
        background-color: hsl(108, 100%, 82%);
    }

    33% {
        background-color: hsl(108, 100%, 74%);
    }

    66% {
        background-color: hsl(108, 100%, 91%);
    }

    100% {
        background-color: hsl(108, 100%, 82%);
    }
}

.bg__box4 {
    grid-column: 2 / 4;
    grid-row: 2 / 4;
    z-index: 7;
    animation: box4 linear 7s infinite;
}

@keyframes box4 {
    0% {
        background-color: hsl(192, 100%, 80%);
    }

    33% {
        background-color: hsl(192, 100%, 69%);
    }

    66% {
        background-color: hsl(191, 100%, 93%);
    }

    100% {
        background-color: hsl(192, 100%, 80%);
    }
}

.content {
    position: absolute;
    width: 95%;
    height: 95%;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: #fff;
    border-top-left-radius: 36px;
    border-bottom-right-radius: 36px;
    padding: 36px;
}
</style>

<div class="container">
    <div class="bg">
        <div class="bg__box1"></div>
        <div class="bg__box2"></div>
        <div class="bg__box3"></div>
        <div class="bg__box4"></div>
    </div>
    <div class="content">
        <header>
            <h1>Gradient Animation Sample</h1>
        </header>
        <section>
            <p>背景のグラデーションを、アニメーションさせているサンプルです。</p>
            <p>
                この手の装飾を行う場合は、canvasタグにシェーダー言語を使う方が、細かな調整ができます。
                ただ、いろいろなことができる分、使いこなすのが難しいです。
            </p>
            <p>
                そこで、CSSのanimationやblurを組み合わせて、それっぽい動きの再現したのが、このサンプルです。</p>
        </section>
    </div>
</div>

今回は、blurでグラデーションを作成し、それをアニメーションさせるサンプルを考えてみました。ぱっと見は難しめの表現ですが、基本的なCSSで何とかなりました。ただ、もっと表現を豊かにするには、シェーダー言語や数式の知識が必須です。自分でも、その部分をもっと深めていく予定です。

関連記事