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 相关文章推荐
JS实现的省份级联实例代码
Jun 24 Javascript
innerText 使用示例
Jan 23 Javascript
node.js应用后台守护进程管理器Forever安装和使用实例
Jun 01 Javascript
jquery实现鼠标经过显示下划线的渐变下拉菜单效果代码
Aug 24 Javascript
简要了解jQuery移动web开发的响应式布局设计
Dec 04 Javascript
JavaScript预解析及相关技巧分析
Apr 21 Javascript
js动态获取子复选项并设计全选及提交的实现方法
Jun 24 Javascript
使用vue编写一个点击数字计时小游戏
Aug 31 Javascript
JS图片放大效果简单实现代码
Sep 08 Javascript
AngularJS  双向数据绑定详解简单实例
Oct 20 Javascript
ionic cordova一次上传多张图片(类似input file提交表单)的实现方法
Dec 16 Javascript
原生js+canvas实现贪吃蛇效果
Aug 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
基于PHP编程注意事项的小结
2013/04/27 PHP
深入探讨<br />和 \r\n两者有什么区别??
2013/06/05 PHP
PHP5中GD库生成图形验证码(有汉字)
2013/07/28 PHP
让codeigniter与swfupload整合的最佳解决方案
2014/06/12 PHP
PHP框架性能测试报告
2016/05/08 PHP
Laravel框架Request、Response及Session操作示例
2019/05/06 PHP
php弹出提示框的是实例写法
2019/09/26 PHP
js实现带搜索功能的下拉框实时搜索实时匹配
2013/11/05 Javascript
抛弃Nginx使用nodejs做反向代理服务器
2014/07/17 NodeJs
js不间断滚动的简单实现
2016/06/03 Javascript
移动端js触摸事件详解
2016/09/18 Javascript
简单的渐变轮播插件
2017/01/12 Javascript
ES6中箭头函数的定义与调用方式详解
2017/06/02 Javascript
React学习之事件绑定的几种方法对比
2017/09/24 Javascript
axios如何取消重复无用的请求详解
2019/12/15 Javascript
[01:10]3.19DOTA2发布会 三代刀塔人第一代
2014/03/25 DOTA
Python自动化测试工具Splinter简介和使用实例
2014/05/13 Python
Python中的两个内置模块介绍
2015/04/05 Python
Python生成任意范围任意精度的随机数方法
2018/04/09 Python
Python迭代器与生成器基本用法分析
2018/07/26 Python
python实现RabbitMQ的消息队列的示例代码
2018/11/08 Python
浅谈pycharm的xmx和xms设置方法
2018/12/03 Python
对python的bytes类型数据split分割切片方法
2018/12/04 Python
Python中时间datetime的处理与转换用法总结
2019/02/18 Python
python实现微信防撤回神器
2019/04/29 Python
python3.x+pyqt5实现主窗口状态栏里(嵌入)显示进度条功能
2019/07/04 Python
python打印直角三角形与等腰三角形实例代码
2019/10/20 Python
Python类继承和多态原理解析
2020/02/05 Python
基于Python fminunc 的替代方法
2020/02/29 Python
pytorch  网络参数 weight bias 初始化详解
2020/06/24 Python
Django REST 异常处理详解
2020/07/15 Python
StubHub巴西:购买和出售您的门票
2016/07/22 全球购物
俄罗斯最大的在线珠宝大卖场:Nebo
2019/12/08 全球购物
介绍一下gcc特性
2015/10/31 面试题
女大学生自我鉴定
2013/12/09 职场文书
九不准学习心得体会
2016/01/23 职场文书