基于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的获取标签名的代码
Jul 16 Javascript
javascript中对Attr(dom中属性)的操作示例讲解
Dec 02 Javascript
js根据鼠标移动速度背景图片自动旋转的方法
Feb 28 Javascript
JavaScript脚本判断蜘蛛来源的方法
Sep 22 Javascript
jquery siblings获取同辈元素用法实例分析
Jul 25 Javascript
Jquery Easyui对话框组件Dialog使用详解(14)
Dec 19 Javascript
使用AngularJS2中的指令实现按钮的切换效果
Mar 27 Javascript
Javascript 实现匿名递归的实例代码
May 25 Javascript
详解node如何让一个端口同时支持https与http
Jul 04 Javascript
详解React中的组件通信问题
Jul 31 Javascript
认识jQuery的Promise的具体使用方法
Oct 10 jQuery
js+SVG实现动态时钟效果
Jul 14 Javascript
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
我的论坛源代码(九)
2006/10/09 PHP
PHP 判断常量,变量和函数是否存在
2009/04/26 PHP
php简单构造json多维数组的方法示例
2017/06/08 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
2018/02/19 PHP
PHP写API输出的时用echo的原因详解
2019/04/28 PHP
javascript forEach通用循环遍历方法
2010/10/11 Javascript
深入分析js中的constructor和prototype
2012/04/07 Javascript
js querySelector和getElementById通过id获取元素的区别
2012/04/20 Javascript
使用jquery动态加载javascript以减少服务器压力
2012/10/29 Javascript
jQuery如何取id有.的值一般的方法是取不到的
2014/04/18 Javascript
JS实现的另类手风琴效果网页内容切换代码
2015/09/08 Javascript
JavaScript获取浏览器信息的方法
2015/11/20 Javascript
js实现可控制左右方向的无缝滚动效果
2016/05/29 Javascript
AngularJS 过滤与排序详解及实例代码
2016/09/14 Javascript
js 获取图像缩放后的实际宽高,位置等信息
2017/03/07 Javascript
Angular 通过注入 $location 获取与修改当前页面URL的实例
2017/05/31 Javascript
详解ESLint在Vue中的使用小结
2018/10/15 Javascript
Vue中消息横向滚动时setInterval清不掉的问题及解决方法
2019/08/23 Javascript
利用JS代码自动删除稿件的普通弹幕功能
2019/09/20 Javascript
Python绘制并保存指定大小图像的方法
2019/01/10 Python
python 多进程队列数据处理详解
2019/12/23 Python
Python3 shelve对象持久存储原理详解
2020/03/23 Python
PIP和conda 更换国内安装源的方法步骤
2020/09/21 Python
Python创建简单的神经网络实例讲解
2021/01/04 Python
世界上最具创新性的增强型知名运动品牌:Proviz
2018/04/03 全球购物
CK巴西官方网站:Calvin Klein巴西
2019/07/19 全球购物
Dyson戴森波兰官网:Dyson.pl
2019/08/05 全球购物
Lookfantastic俄罗斯:欧洲在线化妆品零售商
2019/08/06 全球购物
英国设计师泳装、沙滩装和比基尼在线精品店:Beach Cafe
2019/08/28 全球购物
临床专业自荐信
2014/06/22 职场文书
国际贸易毕业生自荐书
2014/06/22 职场文书
信用卡工作证明模板
2014/09/14 职场文书
2014年学校教学工作总结
2014/12/06 职场文书
2015年毕业生个人自荐书
2015/03/24 职场文书
慰问信(范文3篇)
2019/10/23 职场文书
vue中使用mockjs配置和使用方式
2022/04/06 Vue.js