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

  • Post author:
  • Post category:vue


之前做的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);
  }
}

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


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


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


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


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


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


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


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


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




版权声明:本文为lijiahui_原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。