expexp.jp

CSS , JavaScript

【CSS】【JavaScript】流体アニメーションを作りたい

目立たせたい要素にさまざまな目を引く動き(アニメーション)をさせるサイトが増えています。そこで今回は、液体のような流体アニメーションのサンプルを紹介します。

実装には、CSSと滑らかな動きを再現するためにJavaScriptを使います。gifやpngなどの画像を使わず、シンプルなコードで流用もしやすいお手軽アニメーションです。

完成形サンプル

最終的に目指す完成サンプルはこちら

サンプルでは流体(水っぽいもの液体)が無重力空間にあるかのようにむにゅむにゅな動きをしています。

流体の要素を作成

アニメーションさせる要素を作ります。幅と高さを設定するため、divなどのブロック要素が好ましいです。今回はdivに「fluid」というclassを付与しています。

HTML

<div class="fluid"></div>

SASS

CSSで流体の幅と高さを決めます。流体の色はbackgroundで指定します。今回は水色(color-sample.com)に設定しています。SASSの場合は流体の各値を変数にしておくとのちのち使い回しや修正が楽です。

// 流体の幅・高さを決め、変数へ代入
$fluid-width: 300px;
$fluid-height: 300px;

// 流体のカラーも変数へ代入
$fluid-color: #bce2e8;

// 流体アニメーションさせるclass
.fluid {
  width: $fluid-width;
  height: $fluid-height;
  background: rgba( $fluid-color, 1 );
}

JavaScript

CSSだけだと水色に四角い箱があるだけですので、JavaScript(jQuery)でむにゅむにゅ動く部分を作ります。

// 流体アニメーション設定値
const randomness = 90, // 振れ幅(例:90の場合は0〜90の値になる)
      threshold = 210; // しきい値


// 流体アニメーション関数を定義
const fluid = function(){

  // animate関数を使用
  $('.fluid').animate({
    borderTopLeftRadius: String(Math.round((Math.random()*randomness + threshold)) + 'px'),
    borderTopRightRadius:  String(Math.round((Math.random()*randomness + threshold)) + 'px'),
    borderBottomLeftRadius:  String(Math.round((Math.random()*randomness + threshold)) + 'px'),
    borderBottomRightRadius:  String(Math.round((Math.random()*randomness + threshold)) + 'px'),
  }, {
    duration: 400,
    complete: fluid
  });
}

// 流体アニメーション関数を実行
fluid();

むにゅむにゅ動く部分はborder-radiusによる角丸。それをJavaScriptのanimate関数で、border-radiusの値をランダムで変更しています。border-radiusの詳しい仕組みはこちらを参照。

durationの部分までだと、アニメーションは一回で終了してしまいますが、completeの引数に fluidを設定することでアニメーション関数がエンドレスで繰り返されます。忘れずに関数を変数へ代入してください。

JavaScriptはここまでです。あとはCSSのみで行います。

ここまでのサンプル(サンプル01)

流体を回転させる

むにゅむにゅしている流体にもうちょっとアクセント加えるため、回転させます。流体要素のclass=”fluid”にrotateを追加します。

HTML

<div class="fluid rotate"></div>

SASS

CSSで回転アニメーションを設定します。サンプルでは30秒かけて360度の回転を無限に設定しています。

// 回転アニメーション(360度回転させる)
.rotate {
  animation: rotate 30s ease 0s infinite normal both;
  @keyframes rotate {
    0% { transform: rotate( 0 ); }
    100% { transform: rotate( 360deg ); }
  }
}

ここまでのサンプル(サンプル02)

流体を伸縮させる

流体に拡大と縮小のアニメーションを加え、さらにもにょもにょさせます。流体要素を囲うdivを作り、stretchのクラスを付与します。

HTML

<div class="stretch">
  <div class="fluid rotate"></div>
</div>

SASS

囲うdivにも幅・高さを忘れず設定します。上のrotateと一緒にしてもよいのですが、管理のしやすさからclassは分けてます。伸縮の度合い変更したい場合はscaleの値を調整してください。

// 伸縮アニメーション(100%→90%くらいのあたりで伸縮させる)
.stretch {
  width: $fluid-width;
  height: $fluid-height;
  animation: stretch 1s ease 0s infinite alternate both;
  @keyframes stretch {
    0% { transform: scale( 1, 1 ); }
    100% { transform: scale( .9, .9 ); }
  }
}

ここまでのサンプル(サンプル03)

流体を透過させる

液体っぽくするため、CSSで不透明度を変更して要素を透過させます。fluidに直接記述すればいいんですけど、区別するためにopacityというclassを付与しています。

HTML

<div class="stretch">
  <div class="fluid rotate opacity"></div>
</div>

SASS

不透明度は75%に設定しています。$fluid-colorは一番初めに設定した流体のカラーです(忘れた人用)。

// 透過(不透明度変更)処理
.opacity {
  background: rgba( $fluid-color, .75 );
}

ここまでのサンプル(サンプル04)
※透過をわかりやすくするため、ダミー要素を下に追加しています。

ダミー要素なし(サンプル04B)

流体を反射させる

液体感を出すため、光の映り込みを追加します。例によってclassを追加するわけですが、fluidではなく、stretchに追加します。追加するclassはreflectとしました。別要素にした理由はrotateと同じ要素だと、反射の光が一緒に回転してしまうからです。

HTML

<div class="stretch reflect">
  <div class="fluid rotate opacity"></div>
</div>

SASS

反射する光のサンプルコード。光っぽければどんなので大丈夫です。今回は擬似要素を使用しています。

// 反射(光っぽいのを追加)
.reflect {
  position: relative;

  &::after {
    display: block;
    width: 20px;
    height: 35px;
    border-radius: 50%;
    background: rgba( white, .95 );
    box-shadow: 0 0 20px 10px rgba( white, 1 );
    content: '';
    position: absolute;
    top: 20%;
    left: 20%;
    transform: rotate( 30deg );
  }
}

ここまでのサンプル(サンプル05・透過確認用ダミー付き)

ここまでのサンプル(サンプル05B・ダミーなし)

流体のカラーをグラデーションにする

今までのものは単色の液体でしたが、より質感を求めてグラデーションを設定したサンプルを紹介します。class=”fluid”にgradationのclassを追加します。

HTML

<div class="stretch reflect">
  <div class="fluid rotate opacity gradation"></div>
</div>

SASS

グラデーションのベンダープレフィックスはジェネレータで作成した方が早いです。今回はこちらのサイトで作成しています。

// グラデーション(それっぽい雰囲気にする)
.gradation {
  /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#b3dced+0,29b8e5+100&0.75+0,0.75+100 */
  background: -moz-radial-gradient(center, ellipse cover, rgba(179,220,237,0.75) 0%, rgba(41,184,229,0.75) 100%); /* FF3.6-15 */
  background: -webkit-radial-gradient(center, ellipse cover, rgba(179,220,237,0.75) 0%,rgba(41,184,229,0.75) 100%); /* Chrome10-25,Safari5.1-6 */
  background: radial-gradient(ellipse at center, rgba(179,220,237,0.75) 0%,rgba(41,184,229,0.75) 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
  filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#bfb3dced', endColorstr='#bf29b8e5',GradientType=1 ); /* IE6-9 fallback on horizontal gradient */
}

ここまでのサンプル(サンプル06・透過確認用ダミー付き)

ここまでのサンプル(サンプル06B・ダミーなし)

流体を浮遊させる

完全に蛇足ですが、流体を上下に動かして浮遊感を出します。オマケなので要素を分けてます。classはfloatとしています。

HTML

<div class="float">
  <div class="stretch reflect">
    <div class="fluid rotate opacity gradation"></div>
  </div>
</div>

SASS

// 浮遊(上下に動かす)
.float {
  width: $fluid-width;
  height: $fluid-height;
  animation: float 1.5s linear 0s infinite alternate both;
  @keyframes float {
    0% { transform: translateY( 0 ); }
    100% { transform: translateY( -10% ); }
  }
}

ここまでのサンプル(サンプル07・透過確認用ダミー付き)

ここまでのサンプル(サンプル07B・ダミーなし)