按钮点击效果(水波纹)

按钮点击效果(水波纹)

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

先看看效果吧,如下图(录制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);

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/108879.html原文链接:https://javaforall.net

(0)
上一篇 2021年9月17日 下午5:00
下一篇 2021年9月17日 下午5:00


相关推荐

  • 拒绝从网络访问这台计算机里边的东西删,无法删除访问被拒绝 电脑显示这几个字要怎么办…

    拒绝从网络访问这台计算机里边的东西删,无法删除访问被拒绝 电脑显示这几个字要怎么办…电脑方便了人类的生活 电脑的快捷高效使得人们越来越依赖它 但是大家对于电脑的一些功能和一些简单的故障处理并没有掌握 大家是不是玩电脑的时候总有一些弄不懂的问题呢 今天小编就带大家看一下怎样解决无法删除访问被拒绝 无法删除访问被拒绝有好多原因 并不是电脑坏了 只需要你动动手 就可以解决无法删除访问被拒绝的问题了 第一部份在删除某个文件时 系统有时会给出各种各样的提示 反正就是死活不让删 造成这种

    2026年3月17日
    0
  • java通讯_Java socket详解

    java通讯_Java socket详解刚给大家讲解 Javasocket 通信后 好多童鞋私信我 有好多地方不理解 看不明白 特抽时间整理一下 详细讲述 Javasocket 通信原理和实现案例 整个过程楼主都是通过先简单明了的示例让大家了解整个基本原理 后慢慢接近生产实用示例 先概况后脉络给大家梳理出来的 所有涉及示例都可以直接拷贝运行 楼主才疏学浅 如有部分原理错误请大家及时指正 整理和总结了一下大家常遇到的问题 1 客户端 sock

    2026年3月16日
    2
  • Ubuntu安装GCC编译器

    Ubuntu安装GCC编译器没有gcc啊如何安装gccapt-getinstallbuild-essential

    2022年7月24日
    17
  • linux网络配置出现E325,linux下vi操作出现E325: ATTENTION的解决方法

    linux网络配置出现E325,linux下vi操作出现E325: ATTENTION的解决方法MyBatis,动态传入表名,字段名的解决办法转载:http://luoyu-ds.iteye.com/blog/1517607今天做项目,遇到的问题就是需求修改数据表的记录,而且字段名都不是固定的,也就是说是需要通过参数传入的,本来这也不是…JavaScript–事件模型(转)在各种浏览器中存在三种事件模型:原始事件模型(originaleventmodel),DOM2事件模型…

    2022年5月19日
    43
  • GridView中DropDownList的事件

    GridView中DropDownList的事件 GridView中DropDownList的事件   1.获取事件所在GridView的行索引:   可以通过一下代码获得:  protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)    {        DropDownList drp = sender as DropDow

    2025年10月31日
    5
  • 手把手教你使用YOLOV5训练自己的目标检测模型-口罩检测-视频教程

    手把手教你使用YOLOV5训练自己的目标检测模型大家好,这里是肆十二(dejahu),好几个月没有更新了,这两天看了一下关注量,突然多了1k多个朋友关注,想必都是大作业系列教程来的小伙伴。既然有这么多朋友关注这个大作业系列,并且也差不多到了毕设开题和大作业提交的时间了,那我直接就是一波更新。这期的内容相对于上期的果蔬分类和垃圾识别无论是在内容还是新意上我们都进行了船新的升级,我们这次要使用YOLOV5来训练一个口罩检测模型,比较契合当下的疫情,并且目标检测涉及到的知识点也比较多,这次的内容除了可以作为大家

    2022年4月17日
    47

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号