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 相关文章推荐
浅谈JavaScript函数节流
Dec 09 Javascript
JavaScript类型系统之基本数据类型与包装类型
Jan 06 Javascript
jQuery实现的文字hover颜色渐变效果实例
Feb 20 Javascript
3kb jQuery代码搞定各种树形选择的实现方法
Jun 10 Javascript
jQuery实现鼠标响应式淘宝动画效果示例
Feb 13 jQuery
node+koa2+mysql+bootstrap搭建一个前端论坛
May 06 Javascript
vue监听键盘事件的快捷方法【推荐】
Jul 11 Javascript
Vue实现远程获取路由与页面刷新导致404错误的解决
Jan 31 Javascript
ES6知识点整理之模块化的应用详解
Apr 15 Javascript
vue 路由懒加载中给 Webpack Chunks 命名的方法
Apr 24 Javascript
如何在微信小程序中使用骨架屏的步骤
Jun 12 Javascript
在antd Form表单中select设置初始值操作
Nov 02 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
全国FM电台频率大全 - 22 重庆市
2020/03/11 无线电
PHP文件操作之获取目录下文件与计算相对路径的方法
2016/01/08 PHP
PHP模板引擎Smarty内建函数section,sectionelse用法详解
2016/04/11 PHP
[原创]php常用字符串输出方法分析(echo,print,printf及sprintf)
2016/07/09 PHP
Thinkphp5 如何隐藏入口文件index.php(URL重写)
2019/10/16 PHP
百度 popup.js 完美修正版非常的不错 脚本之家推荐
2009/04/17 Javascript
jQuery ajax serialize()方法的使用以及常见问题解决
2013/01/27 Javascript
js控制input框只读实现示例
2014/01/20 Javascript
使用jquery实现IE下按backspace相当于返回操作
2014/03/18 Javascript
JavaScript设计模式之策略模式实例
2014/10/10 Javascript
jQuery实现在textarea指定位置插入字符或表情的方法
2015/03/11 Javascript
JavaScript的ExtJS框架中表格的编写教程
2016/05/21 Javascript
Bootstrap 实现查询的完美方法
2016/10/26 Javascript
javascript另类方法实现htmlencode()与htmldecode()函数实例分析
2016/11/17 Javascript
使用prop解决一个checkbox选中后再次选中失效的问题
2017/07/05 Javascript
微信小程序外卖选购页实现切换分类与数量加减功能案例
2019/01/15 Javascript
利用Promise自定义一个GET请求的函数示例代码
2019/03/20 Javascript
javascrpt密码强度校验函数详解
2020/03/18 Javascript
详解Vue中的watch和computed
2020/11/09 Javascript
python3.3教程之模拟百度登陆代码分享
2014/01/16 Python
用Python和MD5实现网站挂马检测程序
2014/03/13 Python
Python制作CSDN免积分下载器
2015/03/10 Python
python email smtplib模块发送邮件代码实例
2018/04/26 Python
windows下 兼容Python2和Python3的解决方法
2018/12/05 Python
python字符串和常用数据结构知识总结
2019/05/21 Python
线程安全及Python中的GIL原理分析
2019/10/29 Python
python和php哪个更适合写爬虫
2020/06/22 Python
Python基于unittest实现测试用例执行
2020/11/25 Python
CK美国官网:Calvin Klein
2016/08/26 全球购物
如何启动时不需输入用户名与密码
2014/05/09 面试题
上海某公司.net方向笔试题
2014/09/14 面试题
《独坐敬亭山》教学反思
2014/04/08 职场文书
本科生就业推荐信
2014/05/19 职场文书
银行贷款委托书范本
2014/10/11 职场文书
《小摄影师》教学反思
2016/02/18 职场文书
创作书写之导游词实用技巧分享(干货)
2019/12/20 职场文书