开发者社区> 野兽''> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

按钮点击效果(水波纹)

简介: 近来看到个不错的按钮点击效果,当点击时产生一次水波涟漪效果,挺好玩的,于是简单的实现了下(没考虑低版本浏览器兼容问题) 先看看效果吧,如下图(录制gif软件有点渣,看起来卡卡的...) 这种效果可以由元素内嵌套canves实现,也可以由css3实现。
+关注继续查看

近来看到个不错的按钮点击效果,当点击时产生一次水波涟漪效果,挺好玩的,于是简单的实现了下(没考虑低版本浏览器兼容问题)

先看看效果吧,如下图(录制gif软件有点渣,看起来卡卡的...)

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

Canves实现

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

html代码

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

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;
}
View Code

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();
View Code

CSS3实现

接下来就是纯手打的代码了...觉得还是css3实现的方便些,可能是css写习惯了...

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);

就这些,原理也简单,获取点击位置 >  添加样式   顺便,中秋快乐~

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
使用jquery中实现按回车触发按钮事件和点击提交按钮触发的是一个事件
使用jquery中实现按回车触发按钮事件和点击提交按钮触发的是一个事件
6 0
autojs按钮不可点击
牙叔教程 简单易懂
269 0
vue中在父组件点击按钮触发子组件的事件
vue中在父组件点击按钮触发子组件的事件
364 0
第六章:按钮点击(5)
保存瞬态数据假设你在SimplestKeypad程序中输入了一个重要的数字,并且你的系统崩溃了 - 可能是打了电话。 稍后,您关闭手机,有效终止该程序。下次运行SimplestKeypad时会发生什么? 你以前输入的长串数字是否应该被丢弃? 还是应该看起来好像该程序从您最后离开的状态恢复? 当然,对于像SimplestKeypad这样的简单演示程序来说并不重要,但在一般情况下,用户希望移动应用程序能够准确记住他们上次与程序进行交互时所做的事情。
770 0
WinForm点击按钮在对应的panel里画图
  panel在form1里,button在form1上方,panel在下面。   主要是在button1的click时间获取panel的画笔。   下面的不行,在panel里获取画笔,然后传到button1,根本不行,因为程序的逻辑是,先点击button1加载数据,关键是怎么调用panel1_Paint方法,不知道如何调用,那就没办法同时获取panel的画笔,同理,因为此时在panel1化数据的话还没有点击button1加载数据,所以dataProject是null,而且图形根本出不来,加一个判断就ok了。
1030 0
点击按钮显示谷歌地图
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.
671 0
+关注
野兽&#39;&#39;
只要是代码就好
文章
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载