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 火狐(firefox)不显示本地图片问题解决
Jul 05 Javascript
javascript动态添加、修改、删除对象的属性与方法详解
Jan 27 Javascript
分享jQuery网页元素拖拽插件
Dec 01 Javascript
jQuery Json数据格式排版高亮插件json-viewer.js使用方法详解
Jun 12 jQuery
详解Webpack实战之构建 Electron 应用
Dec 25 Javascript
js原生实现移动端手指滑动轮播图效果的示例
Jan 02 Javascript
JS 验证码功能的三种实现方式
Nov 26 Javascript
Vue动态组件与异步组件实例详解
Feb 23 Javascript
小程序根据手机机型设置自定义底部导航距离
Jun 04 Javascript
在微信小程序中使用vant的方法
Jun 07 Javascript
javascript面向对象三大特征之封装实例详解
Jul 24 Javascript
JS使用Chrome浏览器实现调试线上代码
Jul 23 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获取表单textarea数据中的换行问题
2010/09/10 PHP
php实时倒计时功能实现方法详解
2017/02/27 PHP
php设计模式之原型模式分析【星际争霸游戏案例】
2020/03/23 PHP
js+CSS 图片等比缩小并垂直居中实现代码
2008/12/01 Javascript
学习ExtJS table布局
2009/10/08 Javascript
Javascript 设计模式(二) 闭包
2010/05/26 Javascript
如何让DIV可编辑、可拖动示例代码
2013/09/18 Javascript
一个简单的全屏图片上下打开显示网页效果示例
2014/07/08 Javascript
node+express+ejs制作简单页面上手指南
2014/11/26 Javascript
将JavaScript的jQuery库中表单转化为JSON对象的方法
2015/11/17 Javascript
Javascript中常用类型的格式化方法小结
2016/12/26 Javascript
浅析javaScript中的浅拷贝和深拷贝
2017/02/15 Javascript
JS图片轮播与索引变色功能实例详解
2017/07/06 Javascript
js原生代码实现轮播图的实例讲解
2017/07/28 Javascript
浅谈Emergence.js 检测元素可见性的 js 插件
2017/11/18 Javascript
原生JS实现DOM加载完成马上执行JS代码的方法
2018/09/07 Javascript
TypeScript高级用法的知识点汇总
2019/12/17 Javascript
JavaScript中的相等操作符使用详解
2019/12/21 Javascript
[02:38]2018年度DOTA2最佳劣单位选手-完美盛典
2018/12/17 DOTA
python实现爬虫下载漫画示例
2014/02/16 Python
Python  pip安装lxml出错的问题解决办法
2017/02/10 Python
Python实现繁体中文与简体中文相互转换的方法示例
2018/12/18 Python
python中绕过反爬虫的方法总结
2020/11/25 Python
Python数据分析库pandas高级接口dt的使用详解
2020/12/11 Python
深入理解HTML5定时器requestAnimationFrame的使用
2018/12/12 HTML / CSS
Charlotte Tilbury美国官网:英国美妆品牌
2017/10/13 全球购物
J2EE包括哪些技术
2016/11/25 面试题
市场营销毕业生自荐信
2013/11/23 职场文书
统计岗位职责
2014/02/21 职场文书
2014年元旦促销活动方案
2014/02/22 职场文书
高中生操行评语
2014/04/25 职场文书
工作经常出错的检讨书
2014/09/13 职场文书
2014年团支部工作总结
2014/11/17 职场文书
生产设备维护保养制度
2015/08/06 职场文书
2019年手机市场的调研报告2篇
2019/10/10 职场文书
MySQL笔记 —SQL运算符
2022/01/18 MySQL