【vue3】按钮点击涟漪(波纹)特效 - 指令封装

10 篇文章 0 订阅
6 篇文章 0 订阅

 之前做的angualr项目封装的涟漪特效指令,现在改为vue3写法。(因为迁移过来的,只做了最小的改动供vue3使用)

感觉写法上有优化建议的,欢迎留言讨论交流、学习!

function getOptions() {
  return {
    el: null,
    animationListener: null,
    mouseDownListener: null,
    createShade() {
      let el = document.createElement('span')
      el.classList.add('nk-ink')
      this.animationListener = this.onAnimationEnd.bind(this);
      el.addEventListener('animationend', this.animationListener);
  
      this.el.appendChild(el);
      return el
    },
    onMouseDown(event) {
      let ink = this.getInk()
      if (!ink) {
        ink = this.createShade()
      }
      ink.classList.remove('nk-ink-active')
  
      let inkWidth = this.el.clientWidth; 
      let inkHeight = this.el.clientHeight;
      ink.style.width = Math.max(inkWidth,inkHeight) + 'px'
      ink.style.height = Math.max(inkWidth,inkHeight) + 'px'
      
      
      let offset = this.el.getBoundingClientRect()
      ink.style.left = event.clientX - offset.left + document.body.scrollTop - Math.max(inkWidth,inkHeight)/2 + 'px'
      ink.style.top = event.clientY - offset.top + document.body.scrollLeft - Math.max(inkWidth,inkHeight)/2 + 'px'
      
      
      ink.classList.add('nk-ink-active')
  
    },
    ngAfterViewInit() {
      this.mouseDownListener = this.onMouseDown.bind(this)
      
      this.el.addEventListener('mousedown', this.mouseDownListener); // 增加鼠标按下事件
    },
    clearMemory() {
      let ink = this.getInk();
      if (ink) {
          this.el.removeEventListener('mousedown', this.mouseDownListener);
          ink.removeEventListener('animationend', this.animationListener);
          this.el.removeChild(ink);
      }
    },
    getInk() {
      for (let i = 0; i < this.el.children.length; i++) {
        if (this.el.children[i].className.indexOf('nk-ink') !== -1) {
          return this.el.children[i];
        }
      }
      return null;
    },
    onAnimationEnd() {
      this.getInk().classList.remove('nk-ink-active')
    }
  }
}



export default {
  name: 'ripple',
  directive: {
    mounted(el, binding, vnode, prevVnode) {
      let options = getOptions()
      el.classList.add('nk-ripple')
      options.el = el
      options.ngAfterViewInit()
      el._clearMemory = options.clearMemory.bind(options)
    },
    beforeUnmount(el, binding, vnode, prevVnode) {
      el._clearMemory();
    }
  }
}

/*
 * QQ交流群:522976012  ,欢迎来玩。
 * 聚焦vue3,但不限于vue,任何前端问题,究其本质,值得讨论,研究与学习。
*/



.nk-ripple {
  // 这是 绑定指令的 标签
  overflow: hidden;
  position: relative;
}

.nk-ink {
  // 这是遮罩标签
  // display: flex;
  position: absolute;
  background: rgba(255, 255, 255, 0.5);
  border-radius: 100%;
  transform: scale(0);
}

.nk-ink-active {
  // 这是点击后添加的标签
  animation: ripple 0.4s linear; // 涟漪效果速度
}

.nk-ripple-disabled .nk-ink {
  display: none !important;
}

@keyframes ripple {  
  100% {
      opacity: 0;
      transform: scale(2.5);
  }
}

深圳找工作中,有没有内推的大佬啊 ~~~

提示此文章质量较低,请凑够行数!

提示此文章质量较低,请凑够行数!

提示此文章质量较低,请凑够行数!

提示此文章质量较低,请凑够行数!

提示此文章质量较低,请凑够行数!

提示此文章质量较低,请凑够行数!

提示此文章质量较低,请凑够行数!

提示此文章质量较低,请凑够行数!


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值