読者です 読者をやめる 読者になる 読者になる

webhack / 猫とウェブ技術が好き

javascriptやcssやHTML5とかサーバーサイドの技術やプロジェクトマネジメントとかウェブに関するマーケティングとかWEBを取り巻く全般を好きに書くブログ

水滴がみずたまりに落ちて広がるCSS3エフェクト

CSS3 ウェブデザイン


CSS3だけでアニメーションするエフェクトが最近増えてきて楽しいですね。

いつも紹介するだけだと面白みに欠けるので今回から実装上のポイントを説明していきますね。

  • 落ちる水滴は2つに分かれています。.dropと.drop:beforeで水滴下の丸部分と、水滴上の垂れてきている部分を表示しています。
  • 水滴が垂れるように見える部分はdrop:beforeで丸の上に三角形をくっついています。
  • 落ちるスピードと、水が広がるスピードを2秒が揃えれらています。
  • 無限にループさせるためanimation-iteration-count: infinite;を指定します。
  • 水滴は画面外から落ちてくるように見せるため、TOPの初期位置を表示範囲上部にします。

CSS内で使われているcubic-bezier(三次ベジュ曲線)についてはcubic-bezier.comを試して自分の手で描画してみると良く分かると思います。自然な曲線が描けますね。

CODEPENの元ネタ

codepen.io


はてなブログのこの記事に組み込んだCSSは以下の通りです。

<style>

.drop {
  position: relative;
	width: 20px;
	height: 20px;
  top: -30px;
  margin: 0 auto;
	background: #FFF;
	-moz-border-radius: 20px;
	-webkit-border-radius: 20px;
	border-radius: 20px;
  -moz-animation-name: drip;
  -webkit-animation-name: drip;
  animation-name: drip;
  -moz-animation-timing-function: cubic-bezier(1,0,.89,.19);
  -webkit-animation-timing-function: cubic-bezier(1,0,.89,.19);
  animation-timing-function: cubic-bezier(1,0,.89,.19);
  -moz-animation-duration: 2s;
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
  -moz-animation-iteration-count: infinite;
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}

.drop:before {
  content: "";
  position: absolute;
  width: 0;
	height: 0;
	border-left: 10px solid transparent;
	border-right: 10px solid transparent;
	border-bottom: 30px solid rgba(255,255,255,1);
  top: -22px;
}

.wave {
  position: relative;
  opacity: 0;
  top: 0;
	width: 2px;
	height: 1px;
  border: #FFF 7px solid;
	-moz-border-radius: 300px / 150px;
	-webkit-border-radius: 300px / 150px;
	border-radius: 300px / 150px;
  -moz-animation-name: ripple;
  -webkit-animation-name: ripple;
  animation-name: ripple;
  -moz-animation-delay: 2s;
  -webkit-animation-delay: 2s;
  animation-delay: 2s;
  -moz-animation-duration: 2s;
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
  -moz-animation-iteration-count: infinite;
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}

.wave:after {
  content: "";
  position: absolute;
  opacity: 0;
  top: -5px;
  left: -5px;
	width: 2px;
	height: 1px;
  border: #FFF 5px solid;
	-moz-border-radius: 300px / 150px;
	-webkit-border-radius: 300px / 150px;
	border-radius: 300px / 150px;
  -moz-animation-name: ripple-2;
  -webkit-animation-name: ripple-2;
  animation-name: ripple-2;
  -moz-animation-duration: 2s;
  -webkit-animation-duration: 2s;
  animation-duration: 2s;
  -moz-animation-iteration-count: infinite;
  -webkit-animation-iteration-count: infinite;
  animation-iteration-count: infinite;
}

@keyframes ripple {
    from {
      opacity: 1;
    }
    to {
      width: 600px;
      height: 300px;
      border-width: 1px;
      top: -100px;
      opacity: 0;
    }
}

@keyframes ripple-2 {
    0% {
      opacity: 1;
    }
    50% {
      opacity: 0;
    }
  100% {
    width: 200px;
    height: 100px;
    border-width: 1px;
    top: 100px;
    left: 200px;
  }
}

@keyframes drip {
    to {
      top: 190px;
    }
}
</style>

<div style="width: 600px; height: 350px; min-height: 350px; background-color: #3498DB;  overflow: hidden;">
  <div style="top: -60px;" class="drop"></div>
  <div style="margin: 175px auto;" class="wave"></div>
</div>