こんにちは。KOUKIです。
本記事は、Udemyの「50 Projects In 50 Days – HTML, CSS & JavaScript」で学習したことを載せています。
<目次>
実装するもの
今回は、JavaScriptでRipple Effectを実装する方法を学びました。
demoは「こちら」で確認できます。
環境構築
簡単な環境構築をお願いします。
必要なファイルは、以下の通りです。
1 2 3 4 5 6 |
$ tree . ├── index.html ├── script.js └── style.css |
CSS版
ページ(HTML)の作成
最初にページを作成しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" href="style.css" /> <title>Button Ripple Effect</title> </head> <body> <button class="ripple">Click Me</button> <script src="script.js"></script> </body> </html> |
このHTMLをブラウザ上で表示すると以下のようになります。

スタイル(CSS)を装飾
次にスタイルを記述しましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); * { box-sizing: border-box; } body { background-color: #000; font-family: 'Roboto', sans-serif; display: flex; flex-direction: column; align-items: center; justify-content: center; height: 100vh; overflow: hidden; margin: 0; } button { background-color: purple; color: #fff; border: 1px purple solid; font-size: 14px; text-transform: uppercase; letter-spacing: 2px; padding: 20px 30px; overflow: hidden; margin: 10px 0; position: relative; } button:focus { outline: none; } button .circle { position: absolute; background-color: #fff; width: 100px; height: 100px; border-radius: 50%; transform: translate(-50%, -50%) scale(0); animation: scale 0.5s ease-out; } @keyframes scale { to { transform: translate(-50%, -50%) scale(3); opacity: 0; } } |
ここまで実装すると以下のようになります。

Ripple Effect効果は、以下のCSSによって実現しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
button .circle { position: absolute; background-color: #fff; width: 100px; height: 100px; border-radius: 50%; transform: translate(-50%, -50%) scale(0); animation: scale 0.5s ease-out; } @keyframes scale { to { transform: translate(-50%, -50%) scale(3); opacity: 0; } } |
「@keyframes」は、CSSのアニメーションを実装する機能です。ボタンをクリックした時に、「.circle」クラスを付与したspan要素を作成して、ボタン状に被せます。その時にこのアニメーションが実行され、波状に広がった後に消えます。
JavaScriptの実装
準備が完了したので、JavaScriptを実装していきましょう。
要素を取得する
画面操作に必要な要素を取得します。
1 2 |
// 要素を取得する const buttons = document.querySelectorAll('.ripple') |
clickイベントを登録
「CLICK ME」ボタンを押下するとエフェクトが実行されるようにclickイベントをつけましょう。
1 2 3 4 5 6 |
// 取得したbutton要素分ループ buttons.forEach(button => { button.addEventListener('click', (e) => { }) }) |
クリックの座標を取得
続いて、エフェクトの開始位置を決めるための座標を取得します。
1 2 3 4 5 6 7 8 9 |
// 取得したbutton要素分ループ buttons.forEach(button => { button.addEventListener('click', function(e) { // クリック位置の座標を取得 const x = e.clientX const y = e.clientY console.log(x, y) }) }) |
「client.X」及び「client.Y」は、マウスイベント発生時のX軸方向Y軸方向の位置を取得できます。これで、どこからエフェクトを発生させるかを制御できます。

デモでボタンを複数箇所クリックするとそこからエフェクトが始まることがわかると思います。
エフェクト発生場所の計算
次は、エフェクト発生場所の計算をします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// 取得したbutton要素分ループ buttons.forEach(button => { button.addEventListener('click', function(e) { // クリック位置の座標を取得 const x = e.clientX const y = e.clientY // buttonのView上の位置を取得 const buttonTop = e.target.offsetTop const buttonLeft = e.target.offsetLeft // エフェクト発生場所計算 const xInside = x - buttonLeft const yInside = y - buttonTop }) }) |
「e.target.offsetTop」及び「e.target.offsetLeft」にて、ボタン要素のView上の位置を取得できます。
そこから先ほど取得したクリック位置を差し引いて、「ボタン要素のどの位置をクリックしたか」を計算しています。
Ripple Effect要素を作成
最後に、Ripple Effecgt要素を作成して完了です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
// 取得したbutton要素分ループ buttons.forEach(button => { button.addEventListener('click', function(e) { // クリック位置の座標を取得 // buttonのView上の位置を取得 // エフェクト発生場所計算 // Ripple Effectを作る const circle = document.createElement('span') circle.classList.add('circle') circle.style.top = yInside + 'px' circle.style.left = xInside + 'px' this.appendChild(circle) }) }) |
おわりに
ボタンエフェクトも面白いですね。今回もCSSの知識が必要ですけど^^;
それでは、また!
JavaScriptまとめ
JavaScript ソースコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
// 要素を取得する const buttons = document.querySelectorAll('.ripple') // 取得したbutton要素分ループ buttons.forEach(button => { button.addEventListener('click', function(e) { // クリック位置の座標を取得 const x = e.clientX const y = e.clientY // buttonのView上の位置を取得 const buttonTop = e.target.offsetTop const buttonLeft = e.target.offsetLeft // エフェクト発生場所計算 const xInside = x - buttonLeft const yInside = y - buttonTop // Ripple Effectを作る const circle = document.createElement('span') circle.classList.add('circle') circle.style.top = yInside + 'px' circle.style.left = xInside + 'px' this.appendChild(circle) }) }) |
コメントを残す
コメントを投稿するにはログインしてください。