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

10 篇文章 0 订阅
1 篇文章 0 订阅

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

import { NgModule, Directive, AfterViewInit, ElementRef, OnDestroy } from '@angular/core';
import { CommonModule } from '@angular/common';

@Directive({
  selector: '[nk-ripple]',
  host: {
    'class': 'nk-ripple nk-element'
  }
})
export class Ripple implements AfterViewInit, OnDestroy {

  constructor(
    public el: ElementRef,
  ) {
    
  }

  animationListener: any;
  mouseDownListener: any;
  createShade() {
    let el = document.createElement('span')
    el.classList.add('nk-ink')
    this.animationListener = this.onAnimationEnd.bind(this);
    el.addEventListener('animationend', this.animationListener); 

    this.el.nativeElement.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.nativeElement.clientWidth; // 宿主标签宽度
    let inkHeight = this.el.nativeElement.clientHeight; // 宿主标签高度
    ink.style.width = Math.max(inkWidth,inkHeight) + 'px'
    ink.style.height = Math.max(inkWidth,inkHeight) + 'px'
    
    let offset = this.el.nativeElement.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.nativeElement.addEventListener('mousedown', this.mouseDownListener);
  }
  ngOnDestroy() {
    this.clearMemory();
  }
  clearMemory() {
    let ink = this.getInk();
    if (ink) {
        this.el.nativeElement.removeEventListener('mousedown', this.mouseDownListener);
        ink.removeEventListener('animationend', this.animationListener);
        this.el.nativeElement.removeChild(ink); 
    }
  }
  getInk() {
    for (let i = 0; i < this.el.nativeElement.children.length; i++) {
      if (this.el.nativeElement.children[i].className.indexOf('nk-ink') !== -1) {
        return this.el.nativeElement.children[i];
      }
    }
    return null;
  }
  onAnimationEnd() {
    
    this.getInk().classList.remove('nk-ink-active')
  }
}

@NgModule({
  imports: [CommonModule],
  exports: [Ripple],
  declarations: [Ripple]
})
export class RippleModule { }
.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);
  }
}

使用方式: 

<button nk-ripple >
  <span> √ </span>
</button>

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

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

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

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

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

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

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

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值