按钮点击的水波效果

1,898 阅读1分钟

image

实现思路:水波效果可以用一个 span 来模拟,动画效果是缩放从 0 到大于零的值(比如 4),同时透明度从 1 到 0。点击 button 后,我们把这个 span 添加到 button 里即可。

HTML

结构比较简单,我们用 div 来表示 button:

<div class="button">
  Click Me
</div>

CSS

给 div 加点样式,让它看起来像个 button:

image

.button {
  margin-left: 100px;
  position: relative;
  width: 100px;
  padding: 8px 10px;
  border: 1px solid lightgray;
  border-radius: 5px;
  cursor: pointer;
  overflow: hidden;
  user-select: none;
}

定义水波样式,默认 scale 为 0:

.ripple {
  position: absolute;
  border-radius: 50%;
  transform: scale(0);
  animation: ripple 600ms linear;
  background-color: rgba(30, 184, 245, 0.7);
}

水波动画:

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

javascript

点击按钮时,生成水波效果,先把结构加上:

function playRipple(event) {
  // TODO:生成水波效果
}

// 为 button 添加点击事件
document
  .querySelector('.button')
  .addEventListener('click', event => {
    playRipple(event);
  })

我们看一下水波如何生成,为了方便理解,可以结合图来看,其中黑点表示鼠标点击的位置,蓝色的圆是点击后水波默认大小的圆,** ?**就表示要计算的 circle.style.left:

image

function playRipple(event) {
  const button = event.currentTarget;
  const buttonRect = button.getBoundingClientRect();
  
  const circle = document.createElement("span");
  // 圆的直径
  const diameter = Math.max(button.clientWidth, button.clientHeight);
  // 圆的半径
  const radius = diameter / 2;

  // 计算 ripple 的位置
  circle.style.width = circle.style.height = `${diameter}px`;
  circle.style.left = `${event.clientX - (buttonRect.left + radius)}px`;
  circle.style.top = `${event.clientY - (buttonRect.top + radius)}px`;
  // 添加 ripple 样式
  circle.classList.add("ripple"); 
  // 移除已存在的 ripple
  removeRipple(button);
  // 将 ripple 添加到 button 上
  button.appendChild(circle);
}

// 移除 ripple
function removeRipple(button) {
  const ripple = button.querySelector(".ripple");

  if (ripple) {
    ripple.remove();
  }
}

看下效果: image

总结

又水了一篇文章😂,如果对你有启发,欢迎点赞、评论。

参考

css-tricks.com/how-to-recr…