js点击按钮实现水波纹效果代码(CSS3和Canves)


Posted in Javascript onSeptember 15, 2016

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

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

 js点击按钮实现水波纹效果代码(CSS3和Canves)

这种效果可以由元素内嵌套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();

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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
解决extjs grid 不随窗口大小自适应的改变问题
Jan 26 Javascript
javascript数组操作(创建、元素删除、数组的拷贝)
Apr 07 Javascript
深入分析JQuery和JavaScript的异同
Oct 23 Javascript
使用jQuery仿苹果官网焦点图特效
Dec 23 Javascript
JavaScript中利用各种循环进行遍历的方式总结
Nov 10 Javascript
详解vue-router和vue-cli以及组件之间的传值
Jul 04 Javascript
jquery根据name取得select选中的值实例(超简单)
Jan 25 jQuery
vue中动态绑定表单元素的属性方法
Feb 23 Javascript
详解如何使用webpack打包JS
Jun 21 Javascript
解决vue项目中页面调用数据 在数据加载完毕之前出现undefined问题
Nov 14 Javascript
JavaScript实现栈结构Stack过程详解
Mar 07 Javascript
js实现浏览器打印功能的示例代码
Jul 15 Javascript
Node.js connect ECONNREFUSED错误解决办法
Sep 15 #Javascript
Bootstrap精简教程中秋大放送
Sep 15 #Javascript
AngularJS 指令的交互详解及实例代码
Sep 14 #Javascript
jQuery实现带遮罩层效果的blockUI弹出层示例【附demo源码下载】
Sep 14 #Javascript
什么是JavaScript注入攻击?
Sep 14 #Javascript
jQuery实现可拖拽的许愿墙效果【附demo源码下载】
Sep 14 #Javascript
再谈javascript注入 黑客必备!
Sep 14 #Javascript
You might like
php split汉字
2009/06/05 PHP
php中使用接口实现工厂设计模式的代码
2012/06/17 PHP
php批量更改数据库表前缀实现方法
2013/10/26 PHP
Laravel实现自定义错误输出内容的方法
2016/10/10 PHP
php生成网页桌面快捷方式
2017/05/05 PHP
PHP实现的pdo连接数据库并插入数据功能简单示例
2019/03/30 PHP
JavaScript中判断函数是new还是()调用的区别说明
2011/04/07 Javascript
打豆豆小游戏 用javascript编写的[打豆豆]小游戏
2013/01/08 Javascript
angularjs表格分页功能详解
2016/01/21 Javascript
js HTML5手机刮刮乐代码
2020/09/29 Javascript
nodejs入门教程四:URL相关模块用法分析
2017/04/24 NodeJs
js中的事件委托或是事件代理使用详解
2017/06/23 Javascript
详解Angular路由之路由守卫
2018/05/10 Javascript
解决在vue项目中webpack打包后字体不生效的问题
2018/09/01 Javascript
微信小程序实现的日期午别医生排班表功能示例
2019/01/09 Javascript
基于vue实现滚动条滚动到指定位置对应位置数字进行tween特效
2019/04/18 Javascript
JS前端基于canvas给图片添加水印
2020/11/11 Javascript
[50:01]Ti4 冒泡赛第二天 NEWBEE vs Titan
2014/07/15 DOTA
[33:39]DOTA2上海特级锦标赛C组小组赛#2 LGD VS Newbee第二局
2016/02/27 DOTA
详解Python的Django框架中Manager方法的使用
2015/07/21 Python
【Python】Python的urllib模块、urllib2模块批量进行网页下载文件
2016/11/19 Python
解决pycharm无法调用pip安装的包问题
2018/05/18 Python
在python中利用GDAL对tif文件进行读写的方法
2018/11/29 Python
python执行精确的小数计算方法
2019/01/21 Python
Python 列表中的修改、添加和删除元素的实现
2020/06/11 Python
tensorflow 2.1.0 安装与实战教程(CASIA FACE v5)
2020/06/30 Python
html5 Canvas实现图片旋转的示例
2018/01/15 HTML / CSS
护理专业毕业生推荐信
2013/10/31 职场文书
国际商务专业职业生涯规划书范文
2014/01/17 职场文书
五一活动标语
2014/06/30 职场文书
世界读书日的活动方案
2014/08/20 职场文书
公司授权委托书范本
2014/09/18 职场文书
2014新生大学四年计划书
2014/09/21 职场文书
2015年七夕情人节感言
2015/08/03 职场文书
redis cluster支持pipeline的实现思路
2021/06/23 Redis
Java代码规范与质量检测插件SonarLint的使用
2022/08/05 Java/Android