請啟用 Javascript 查看內容

Vue3 自定義指令應用 - Ripple Effect

 ·  ☕ 1 分鐘

Ripple Effect

使用 Vue 自定義指令實現類似 Material Design Button 的 Ripple Effect。

實作

1. 指令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const EVENT = 'mousedown';

const ripple = {
  mounted(el) {
    el.addEventListener(EVENT, createRipple);
  },
  unmounted(el) {
    el.removeEventListener(EVENT, createRipple);
  },
};

2. createRipple

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function createRipple(event) {
  const target = event.currentTarget;
  const { top, left } = target.getBoundingClientRect();
  const { clientWidth, clientHeight } = target;
  const diameter = Math.sqrt(clientWidth ** 2 + clientHeight ** 2);
  const radius = diameter / 2;
  const localX = event.clientX - left;
  const localY = event.clientY - top;

  const ripple = document.createElement('span');
  ripple.setAttribute('class', 'v-ripple');
  ripple.setAttribute(
    'style',
    `
      width: ${diameter}px;
      height: ${diameter}px;
      left: ${localX - radius}px;
      top: ${localY - radius}px;
    `,
  );

  ripple.addEventListener('animationend', removeRipple);
  target.appendChild(ripple);
}

3. removeRipple

1
2
3
4
5
function removeRipple(event) {
  const ripple = this;
  ripple.remove();
  ripple.addEventListener('animationend', removeRipple);
}

4. CSS animation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
.v-ripple {
  position: absolute;
  background-color: currentColor;
  border-radius: 50%;
  opacity: 0.2;
  transform: scale(0);
  animation: v-ripple-animation 0.6s linear;
}

@keyframes v-ripple-animation {
  to {
    opacity: 0;
    transform: scale(4);
  }
}

CodePen


竹白
作者
竹白
前端筆記

文章目錄