Edited at

クリックで波紋を出すエフェクト(Ripple Effect)実装メモ

More than 3 years have passed since last update.


はじめに

2014年に発表されたマテリアルデザインのアニメーションの一つとして、Ripple Effectという波紋が広がるような演出があります。今回cssとjsで実装してみたので、それのメモです。

<こんな感じ>

ripple.gif


実際の動き

http://nekoneko-wanwan.github.io/demo/mouse-action/click/

※cssのプレフィックスは書いていないので動かない環境もあります



html



  • div.rippleがクリック範囲の要素、spanがエフェクトの要素です。

  • ここではspanを直接書いていますが、jsの方でDOM生成しても良いかと思います。


ripple.html

<div class="ripple">

<span class="ripple__effect is-orange"></span>
</div>


javascript


  • エフェクト要素をクリックした座標を中心とした位置に移動させます。

  • エフェクトのアニメーション自体はcssで表現しています。

  • エフェクトを発動させるためのclassを付け替えます。


ripple.js

$(function() {

var $clickable = $('.ripple');

/* mousedownだと直ぐに発動し、clickだとマウスボタンを離した時に発動する */
$clickable.on('mousedown', function(e) {
var _self = this;
var x = e.offsetX;
var y = e.offsetY;

var $effect = $(_self).find('.ripple__effect');
var w = $effect.width();
var h = $effect.height();

/* クリックした座標を中心とする */
$effect.css({
left: x - w / 2,
top: y - h / 2
});

/* jsではclassの付け替えをするだけ */
if (!$effect.hasClass('is-show')) {
$effect.addClass('is-show');

/*
* エフェクトアニメーションが終わったらclassを削除する
* ここでは、単純にcssで設定するdurationと時間を合わせているだけですが
* keyframes終了のイベント(AnimationEnd)が取れるかと思うので、それで対応した方が良いかも
*/

setTimeout(function() {
$effect.removeClass('is-show');
}, 750);
}
return false;
});

});



css


  • エフェクトアニメーションの設定を行ないます。


プレフィックスは省略しています



ripple.css

/* クリックできる要素 */

.ripple {
/* エフェクトに直接関係はない */
margin: 20px;
background-color: #f7f7f7;
height: 100px;
width: 200px;
text-align: center;
line-height: 100px;
cursor: pointer;

/* 必須 */
overflow: hidden;
position: relative;
}

/* エフェクト要素 */
.ripple__effect {
/* 値の変更はエフェクト形体・サイズ・スピードに影響する */
width: 150px;
height: 150px;

/* 必須 */
position: absolute;
border-radius: 100%;
pointer-events: none;
transform: scale(0);
opacity: 0;
}

/* エフェクト要素の色を指定 */
.ripple__effect.is-orange { background: #f1c40f;}
.ripple__effect.is-blue { background: #4aa3df;}
.ripple__effect.is-black { background: #999;}

/* classが付与されたらアニメーションを実行 */
.ripple__effect.is-show {
animation: ripple 0.75s ease-out;
}

/* アニメーションの定義 */
@keyframes ripple {
from {
opacity: 1;
}
to {
transform: scale(2);
opacity: 0;
}
}