Web前端-按钮点击效果(水波纹)

这种效果可以由元素内嵌套canves实现,也可以由css3实现。

Canves实现

网上摘了一份canves实现的代码,略微去掉了些重复定义的样式并且给出js注释,代码如下

 

第一种方法:

html骨架代码

<a class="btn color-1 material-design" data-color="#2f5398">Press me!</a>

css代码

* {
  box-sizing: border-box;
  outline: none;
}
body {
  font-family: 'Open Sans';
  font-size: 100%;
  font-weight: 300;
  line-height: 1.5em;
  text-align: center;
}
.btn {
  border: none;
  display: inline-block;
  color: white;
  overflow: hidden;
  margin: 1rem;
  padding: 0;
  width: 150px;
  height: 40px;
  text-align: center;
  line-height: 40px;
  border-radius: 5px;
}
.btn.color-1 {
  background-color: #426fc5;
}
.btn-border.color-1 {
  background-color: transparent;
  border: 2px solid #426fc5;
  color: #426fc5;
}
.material-design {
  position: relative;
}
.material-design canvas {
  opacity: 0.25;
  position: absolute;
  top: 0;
  left: 0;
}
.container {
  align-content: center;
  align-items: flex-start;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  margin: 0 auto;
  max-width: 46rem;
}

js代码

var canvas = {},
    centerX = 0,
    centerY = 0,
    color = '',
    containers = document.getElementsByClassName('material-design')
    context = {},
    element = {},
    radius = 0,
    // 根据callback生成requestAnimationFrame动画
    requestAnimFrame = function () {
      return (
        window.requestAnimationFrame       || 
        window.mozRequestAnimationFrame    || 
        window.oRequestAnimationFrame      || 
        window.msRequestAnimationFrame     || 
        function (callback) {
          window.setTimeout(callback, 1000 / 60);
        }
      );
    } (),
    // 为每个指定元素生成canves
    init = function () {
      containers = Array.prototype.slice.call(containers);
      for (var i = 0; i < containers.length; i += 1) {
        canvas = document.createElement('canvas');
        canvas.addEventListener('click', press, false);
        containers[i].appendChild(canvas);
        canvas.style.width ='100%';
        canvas.style.height='100%';
        canvas.width  = canvas.offsetWidth;
        canvas.height = canvas.offsetHeight;
      }
    },
    // 点击并且获取需要的数据,如点击坐标、元素大小、颜色
    press = function (event) {
      color = event.toElement.parentElement.dataset.color;
      element = event.toElement;
      context = element.getContext('2d');
      radius = 0;
      centerX = event.offsetX;
      centerY = event.offsetY;
      context.clearRect(0, 0, element.width, element.height);
      draw();
    },
    // 绘制圆形,并且执行动画
    draw = function () {
      context.beginPath();
      context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
      context.fillStyle = color;
      context.fill();
      radius += 2;
      // 通过判断半径小于元素宽度,不断绘制 radius += 2 的圆形
      if (radius < element.width) {
        requestAnimFrame(draw);
      }
    };

init();

 

第二种方法:

html代码

<a class="waves ts-btn">Press me!</a>

css

.waves{
    position:relative;
    cursor:pointer;
    display:inline-block;
    overflow:hidden;
    text-align: center;
    -webkit-tap-highlight-color:transparent;
    z-index:1;
}
.waves .waves-animation{
    position:absolute;
    border-radius:50%;
    width:25px;
    height:25px;
    opacity:0;
    background:rgba(255,255,255,0.3);
    transition:all 0.7s ease-out;
    transition-property:transform, opacity, -webkit-transform;
    -webkit-transform:scale(0);
    transform:scale(0);
    pointer-events:none
}
.ts-btn{
    width: 200px;
    height: 56px;
    line-height: 56px;
    background: #f57035;
    color: #fff;
    border-radius: 5px;
}

js

document.addEventListener('DOMContentLoaded',function(){

      var duration = 750;

      // 样式string拼凑
      var forStyle = function(position){
        var cssStr = '';
        for( var key in position){
          if(position.hasOwnProperty(key)) cssStr += key+':'+position[key]+';';
        };
        return cssStr;
      }

      // 获取鼠标点击位置
      var forRect = function(target){
        var position = {
          top:0,
          left:0
        }, ele = document.documentElement;
        'undefined' != typeof target.getBoundingClientRect && (position = target.getBoundingClientRect());
        return {
            top: position.top + window.pageYOffset - ele.clientTop,
            left: position.left + window.pageXOffset - ele.clientLeft
        }
      }

      var show = function(event){
        var pDiv = event.target,
          cDiv = document.createElement('div');
        pDiv.appendChild(cDiv);
        var rectObj = forRect(pDiv),
          _height = event.pageY - rectObj.top,
          _left = event.pageX - rectObj.left,
          _scale = 'scale(' + pDiv.clientWidth / 100 * 10 + ')';
        var position = {
          top: _height+'px',
          left: _left+'px'
        };
        cDiv.className = cDiv.className + " waves-animation",
        cDiv.setAttribute("style", forStyle(position)),
        position["-webkit-transform"] = _scale,
        position["-moz-transform"] = _scale,
        position["-ms-transform"] = _scale,
        position["-o-transform"] = _scale,
        position.transform = _scale,
        position.opacity = "1",
        position["-webkit-transition-duration"] = duration + "ms",
        position["-moz-transition-duration"] = duration + "ms",
        position["-o-transition-duration"] = duration + "ms",
        position["transition-duration"] = duration + "ms",
        position["-webkit-transition-timing-function"] = "cubic-bezier(0.250, 0.460, 0.450, 0.940)",
        position["-moz-transition-timing-function"] = "cubic-bezier(0.250, 0.460, 0.450, 0.940)",
        position["-o-transition-timing-function"] = "cubic-bezier(0.250, 0.460, 0.450, 0.940)",
        position["transition-timing-function"] = "cubic-bezier(0.250, 0.460, 0.450, 0.940)",
        cDiv.setAttribute("style", forStyle(position));
        var finishStyle = {
          opacity: 0,
          "-webkit-transition-duration": duration + "ms",
          "-moz-transition-duration": duration + "ms",
          "-o-transition-duration": duration + "ms",
          "transition-duration": duration + "ms",
          "-webkit-transform" : _scale,
          "-moz-transform" : _scale,
          "-ms-transform" : _scale,
          "-o-transform" : _scale,
          top: _height + "px",
          left: _left + "px",
        };
        setTimeout(function(){
          cDiv.setAttribute("style", forStyle(finishStyle));
          setTimeout(function(){
            pDiv.removeChild(cDiv);
          },duration);
        },100)
      }
      document.querySelector('.waves').addEventListener('click',function(e){
        show(e);
      },!1);
    },!1);

 

posted @ 2020-03-22 23:21  Homegu  阅读(2925)  评论(5编辑  收藏  举报