Vue3版本 水波纹特效 (亲测有效 开箱即用)

看下图 最终效果就是这样滴 

步骤一:创建一个waves.ts文件(直接复制即可 在vue3项目保证可以用)没用ts的话就直接把语法声明去掉即可

// 水波纹类
class Ripple {
  el: HTMLElement
  rippleColor: string
  animationListener: any
  mouseDownListener: any

  constructor(config: any) {
    this.el = config.el
    this.rippleColor = config.color || 'rgba(0, 0, 0, .35)'
  }

  // 创建水波纹动画节点并插入
  createRieEl() {
    const el = document.createElement('span')
    el.classList.add('ani_ripple')
    // 添加动画监听
    this.animationListener = this.onAnimationEnd.bind(this)
    el.addEventListener('animationend', this.animationListener)
    this.el.appendChild(el)
    return el
  }

  // 初始化水波纹动画
  init() {
    // 添加点击事件监听
    this.mouseDownListener = this.onMouseDown.bind(this)
    // 增加鼠标按下事件
    this.el.addEventListener('mousedown', this.mouseDownListener)
  }

  // 点击事件
  onMouseDown(e: any) {
    let riEl: any = this.getRieEl()
    if (riEl) {
      // 删除旧节点为了频繁点击动画刷新
      this.el.removeChild(riEl)
    }
    riEl = this.createRieEl()
    // 取宽和高较大的值作为水波纹大小
    const max = Math.max(this.el.clientWidth, this.el.clientHeight)
    const style = {
      left: e.offsetX - max / 2 + 'px',
      top: e.offsetY - max / 2 + 'px',
      width: max + 'px',
      height: max + 'px',
      position: 'absolute',
      transform: 'scale(0)',
      pointerEvents: 'none',
      borderRadius: '100%',
      backgroundColor: this.rippleColor,
      animation: 'ripple 1s ease-out'
    }
    Object.assign(riEl.style, style)
  }

  // 查找是否已经有了水波纹动画节点
  getRieEl() {
    if (this.el.children.length === 0) return null
    for (const i in this.el.children) {
      if (this.el.children[i].className?.includes('ani_ripple')) {
        return this.el.children[i]
      }
    }
    return null
  }

  // 清除水波纹动画及其节点
  clearRie() {
    const riEl = this.getRieEl();
    if (riEl) {
      this.el.removeEventListener('mousedown', this.mouseDownListener)
      riEl.removeEventListener('animationend', this.animationListener)
      this.el.removeChild(riEl)
    }
  }

  // 动画结束事件--暂时可以不用,也可以添加判断:结束之前不可重复动画
  onAnimationEnd() {
  }
}
import type { Directive, DirectiveBinding } from "vue"
interface elType extends HTMLElement {
  _clearRipple: Function
}
// ------指令用法,在页面中导入文件,直接const vRipple = ripple即可
// 按钮水波纹效果指令
export const ripple: Directive = {
  mounted(el: elType, binding: DirectiveBinding) {
    const options = new Ripple({ el })
    options.init()
    // 绑定水波纹清除事件
    el._clearRipple = options.clearRie.bind(options)
  },
  beforeUnmount(el, binding, vnode, prevVnode) {
    el._clearRipple()
  }
}

步骤二:在需要使用的页面进行引入你创建的waves.ts路径同时注册指令

import { ripple } from '@/directives/waves/waves' //这是我的路径

// 自定义水波纹指令

const vRipple = ripple//这个常量名就是后面页面会使用的指令名 可以随便命名

步骤三:在style标签里面创建css动画

@keyframes ripple {

  100% {

    -webkit-transform: scale(3);

    transform: scale(3);

    opacity: 0;

  }

}

步骤四:给被绑定的元素添加溢出隐藏和设置绝对定位属性

  position: relative;

  overflow: hidden;

步骤五:元素使用自定义指令(大功告成)

<div class="box" v-ripple></div>

 下图是使用页面的截图主要红框标注的地方即可 不然会导致水波纹定位不准确

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值