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 相关文章推荐
基于jquery封装的一个js分页
Nov 15 Javascript
JavaScript中数组的排序、乱序和搜索实现代码
Nov 30 Javascript
js事件绑定快捷键以ctrl+k为例
Sep 30 Javascript
javascript设计模式--策略模式之输入验证
Nov 27 Javascript
js实现的奥运倒计时时钟效果代码
Dec 09 Javascript
基于jquery实现动态竖向柱状条特效
Feb 12 Javascript
js仿拉勾网首页穿墙广告效果
Mar 08 Javascript
JS获取数组中出现次数最多及第二多元素的方法
Oct 27 Javascript
Vue仿支付宝支付功能
May 25 Javascript
详解angular如何调用HTML字符串的方法
Jun 30 Javascript
Vue press 支持图片放大功能的实例代码
Nov 09 Javascript
vue改变循环遍历后的数据实例
Nov 07 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
欧美媒体选出10年前最流行的17部动画
2017/01/18 日漫
在字符串中把网址改成超级链接
2006/10/09 PHP
使用laravel根据用户类型来显示或隐藏字段
2019/10/17 PHP
XmlUtils JS操作XML工具类
2009/10/01 Javascript
多浏览器支持的右下角浮动窗口
2010/04/01 Javascript
javascript 使td内容不换行不撑开
2012/11/29 Javascript
基于jquery中children()与find()的区别介绍
2013/04/26 Javascript
javascript 弹出的窗口返回值给父窗口具体实现
2013/11/23 Javascript
使用AngularJS中的SCE来防止XSS攻击的方法
2015/06/18 Javascript
js中unicode转码方法详解
2015/10/09 Javascript
JS实现的表格行鼠标点击高亮效果代码
2015/11/27 Javascript
vue 通过下拉框组件学习vue中的父子通讯
2017/12/19 Javascript
JavaScript基础心法 数据类型
2018/03/05 Javascript
javascript实现拖拽碰撞检测
2020/03/12 Javascript
JavaScript中的全局属性与方法深入解析
2020/06/14 Javascript
详解Vue中的MVVM原理和实现方法
2020/07/15 Javascript
[33:09]完美世界DOTA2联赛循环赛 Forest vs DM BO2第二场 10.29
2020/10/29 DOTA
在Python中使用Mako模版库的简单教程
2015/04/08 Python
Python的爬虫包Beautiful Soup中用正则表达式来搜索
2016/01/20 Python
python使用pyqt写带界面工具的示例代码
2017/10/23 Python
python爬取淘宝商品详情页数据
2018/02/23 Python
Python使用pickle模块报错EOFError Ran out of input的解决方法
2018/08/16 Python
详解django2中关于时间处理策略
2019/03/06 Python
PyQt5实现简易电子词典
2019/06/25 Python
在Python中os.fork()产生子进程的例子
2019/08/08 Python
python 图片二值化处理(处理后为纯黑白的图片)
2019/11/01 Python
Python多线程操作之互斥锁、递归锁、信号量、事件实例详解
2020/03/24 Python
使用Python将Exception异常错误堆栈信息写入日志文件
2020/04/08 Python
python中如何使用虚拟环境
2020/10/14 Python
计算机软件专业求职信
2014/06/10 职场文书
2014年民政局关于保密工作整改措施
2014/09/19 职场文书
2015团员个人年度总结
2015/11/24 职场文书
导游词之西江千户苗寨
2019/12/24 职场文书
golang json数组拼接的实例
2021/04/28 Golang
速龙x4-860k处理器相当于i几
2022/04/20 数码科技
基于docker安装zabbix的详细教程
2022/06/05 Servers