Edited at

【JavaScript,CSS】ボタンの波紋を実装する


まずはじめに

シンプルさを重視。ボタンをクリックしたときに、波紋が発生するデザインを考えてみました。

一般に Ripple Effect と呼ばれ、Google の Material Design にも採用されています。


See the Pen
QWLaapR
by MF3PGM (@masa_mf3rs)
on CodePen.


この記事の対象者

JavaScriptの基礎を学習したい人。デザインが好きな人などなど。いろいろな海外のサイトを研究した中で、比較的わかりやすい実装方法を紹介します。


1. HTML

今回はbuttonタグを使用します。


HTML

<button id= "btn" >CLICK ME</button>



2. CSS

まず、#btnでボタンを、.rippleで波紋のデザインを指定します。また、波紋のアニメーションもここで作成します。


CSS

#btn{

/*ボタンのデフォルトのデザインをリセット*/
border: none;
outline: none;
/*position: relative; は必須*/
position: relative;
height: 47px;
width: 150px;
border-radius: 3px;
display: block;
margin: 100px auto;
color: white;
background-color: #448AFF;
box-shadow: 0.9px 1.0px 2px rgba(0,0,0,0.2);
font-size: 14px;
letter-spacing: 0.03em;
/*波紋のはみ出しを消す*/
overflow: hidden;
}

.ripple {
/*position: absolute; は必須*/
position: absolute;
background-color: white;
width: 20px;
height: 20px;
border-radius: 50%;
/*今回はアニメーションの名前,変化の時間,繰り返し回数*/
animation: rippleEffect 1200ms 1;
opacity: 0;
}
@keyframes rippleEffect {
from {
transform: scale(1);
opacity: 0.45;
}
to {
transform: scale(50);
opacity: 0;
}
}



3. JavaScript

参考資料よりもシンプルにしました。

まず、クリックした位置を計算し、波紋の位置を決めます。それができたら、ボタンがクリックされるたびに波紋であるdivを生成します

☞ 波紋の位置について(難しいのはここだけ)

.page  ページ全体の左上からのイベント発生場所の水平位置を返す

.offset  要素の左上からの水平位置を返す

element.setAttribute(name, value);  既にある要素に新しい属性を追加、または変更する


JavaScript

// #btnを取得

let rippleElement = document.getElementById("btn");
rippleElement.onclick = function(e) {
// 今回のthisはボタンを意味する
// X,Y、つまりボタンの左上の角からの距離を求める
//(ボタンの中にdivを生成させるため)
let X = e.pageX - this.offsetLeft;
let Y = e.pageY - this.offsetTop;
// divを生成する
let rippleDiv = document.createElement("div");
// divのデザイン
rippleDiv.classList.add('ripple');
// divの位置を.setAttributeで指定
rippleDiv.setAttribute("style","top:"+Y+"px; left:"+X+"px;");
// divをボタンに入れる
rippleElement.appendChild(rippleDiv);
//divを削除する(このコードは任意です)
setTimeout(function() {
rippleDiv.remove();
},1200);
}


おわりに

初めてQitaに記事を投稿してみました。僕自身JavaScriptを学習し始めて3か月くらいしか経っていませんが、この記事が皆様にお役に立てれば幸いです。


参考サイト

Material Design Ripple Effect In Pure JavaScript