基于JS+Canves实现点击按钮水波纹效果


Posted in Javascript onSeptember 15, 2016

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

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

基于JS+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中输入验证中一个不错的效果
Aug 21 Javascript
js使用eval解析json实例与注意事项分享
Jan 18 Javascript
JavaScript字符串对象charAt方法入门实例(用于取得指定位置的字符)
Oct 17 Javascript
vue指令以及dom操作详解
Mar 04 Javascript
vue.js指令v-model使用方法
Mar 20 Javascript
Vue报错:Uncaught TypeError: Cannot assign to read only property’exports‘ of object’#‘的解决方法
Jun 17 Javascript
妙用Angularjs实现表格按指定列排序
Jun 23 Javascript
javascript ES6 新增了let命令使用介绍
Jul 07 Javascript
JS实现身份证输入框的输入效果
Aug 21 Javascript
jQuery实现购物车的总价计算和总价传值功能
Nov 28 jQuery
webpack4 配置 ssr 环境遇到“document is not defined”
Oct 24 Javascript
JS实现选项卡插件的两种写法(jQuery和class)
Dec 30 jQuery
js点击按钮实现水波纹效果代码(CSS3和Canves)
Sep 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
You might like
关于Intype一些小问题的解决办法
2008/03/28 PHP
几个有用的php字符串过滤,转换函数代码
2012/05/01 PHP
php之XML转数组函数的详解
2013/06/07 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
2013/07/05 PHP
php模拟ping命令(php exec函数的使用方法)
2013/10/25 PHP
codeigniter集成ucenter1.6双向通信的解决办法
2014/06/12 PHP
PHP串行化与反串行化实例分析
2016/12/27 PHP
详解Yii2.0 rules验证规则集合
2017/03/21 PHP
TP(thinkPHP)框架多层控制器和多级控制器的使用示例
2018/06/13 PHP
PHP实现的分解质因数操作示例
2018/08/01 PHP
Javascript 写的简单进度条控件
2008/01/22 Javascript
解决iframe的frameborder在chrome/ff/ie下的差异
2010/08/12 Javascript
如何实现修改密码时密码框显示保存到cookie的密码
2013/12/10 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
2016/05/24 Javascript
深入理解事件冒泡(Bubble)和事件捕捉(capture)
2016/05/28 Javascript
javascript日期比较方法实例分析
2016/06/17 Javascript
SelecT下拉框选中和取值的解决方法
2016/11/22 Javascript
jQuery鼠标悬停内容动画切换效果
2017/04/27 jQuery
详解搭建es6+devServer简单开发环境
2018/09/25 Javascript
使用 electron 实现类似新版 QQ 的登录界面效果(阴影、背景动画、窗体3D翻转)
2018/10/23 Javascript
vue分页插件的使用方法
2019/12/25 Javascript
JavaScript如何实现监听键盘输入和鼠标监点击
2020/07/20 Javascript
python使用心得之获得github代码库列表
2014/06/25 Python
Python sys.argv用法实例
2015/05/28 Python
20招让你的Python飞起来!
2016/09/27 Python
Python图像滤波处理操作示例【基于ImageFilter类】
2019/01/03 Python
Python实现的插入排序,冒泡排序,快速排序,选择排序算法示例
2019/05/04 Python
python 两个数据库postgresql对比
2019/10/21 Python
Python数据可视化:箱线图多种库画法
2019/11/06 Python
python多线程实现同时执行两个while循环的操作
2020/05/02 Python
小结Python的反射机制
2020/09/28 Python
金智子午JAVA面试题
2015/09/04 面试题
爱国主义教育活动总结
2014/05/07 职场文书
校园文明标语
2014/06/13 职场文书
房屋租赁授权委托书范本
2014/09/20 职场文书
pycharm debug 断点调试心得分享
2021/04/16 Python