ripple.js 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. /**
  2. * 水波纹节点对象池
  3. */
  4. const ripplePool = [];
  5. /**
  6. * 点击水波纹
  7. * [参考](https://juejin.cn/post/7047782205002612773)
  8. * @param event 点击事件
  9. * @param target 点击目标
  10. */
  11. export default function ripple(event, target) {
  12. /**
  13. * 水波纹动画节点
  14. */
  15. let node;
  16. // 从对象池里面拿取节点
  17. if (ripplePool.length > 1) {
  18. node = ripplePool.shift();
  19. }
  20. else {
  21. node = document.createElement("div");
  22. node.className = "ripple";
  23. }
  24. /** 点击目标矩阵尺寸 */
  25. const rect = target.getBoundingClientRect();
  26. /** 当前自定义颜色值 */
  27. const color = target.getAttribute("color");
  28. /** 波纹大小 */
  29. let size = Math.max(rect.width, rect.height);
  30. // 设置最大范围
  31. if (size > 200)
  32. size = 200;
  33. // 设置大小
  34. node.style.height = node.style.width = size + "px";
  35. // 默认是白色透明
  36. node.style.backgroundColor = color || "rgba(255, 255, 255, .45)";
  37. // 这里必须输出节点后再设置位置,不然会有问题
  38. target.appendChild(node);
  39. const touches = event.touches;
  40. const y = touches ? touches[0].clientY : event.clientY;
  41. const x = touches ? touches[0].clientX : event.clientX;
  42. const top = y - rect.top - (node.offsetHeight / 2);
  43. const left = x - rect.left - (node.offsetWidth / 2);
  44. // console.log(top, left);
  45. node.style.top = top + "px";
  46. node.style.left = left + "px";
  47. function end() {
  48. node.removeEventListener("animationend", end);
  49. // console.log("动画结束", node);
  50. target.removeChild(node);
  51. ripplePool.push(node);
  52. }
  53. node.addEventListener("animationend", end);
  54. }