基于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 相关文章推荐
JavaScript 常见对象类创建代码与优缺点分析
Dec 07 Javascript
jquery实现心算练习代码
Dec 06 Javascript
jquery模拟按下回车实现代码
Sep 20 Javascript
ie支持function.bind()方法实现代码
Dec 27 Javascript
jquery控制页面部分刷新的方法
Jun 24 Javascript
JS判断当前页面是否在微信浏览器打开的方法
Dec 08 Javascript
js跨域资源共享 基础篇
Jul 02 Javascript
基于js实现checkbox批量选中操作
Nov 22 Javascript
Angular1.x自定义指令实例详解
Mar 01 Javascript
vue.js todolist实现代码
Oct 29 Javascript
实例分析vue循环列表动态数据的处理方法
Sep 28 Javascript
javascript实现对话框功能警告(alert 消息对话框)确认(confirm 消息对话框)
May 07 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
星际争霸 Starcraft 编年史
2020/03/14 星际争霸
5.PHP的其他功能
2006/10/09 PHP
如何对PHP程序中的常见漏洞进行攻击(上)
2006/10/09 PHP
怎样去阅读一份php源代码
2009/08/21 PHP
php查看当前Session的ID实例
2015/03/16 PHP
thinkphp配置文件路径的实现方法
2016/08/30 PHP
仿服务器端脚本方式的JS模板实现方法
2007/04/27 Javascript
仿中关村在线首页弹出式广告插件(jQuery版)
2012/05/03 Javascript
jquery 按钮状态效果 正常、移上、按下
2013/08/12 Javascript
JSON 数字排序多字段排序介绍
2013/09/18 Javascript
Jquery利用mouseenter和mouseleave实现鼠标经过弹出层且可以点击
2014/02/12 Javascript
JavaScript实现自动跳转文本功能
2017/05/25 Javascript
Vue实现web分页组件详解
2017/11/28 Javascript
javascript少儿编程关于返回值的函数内容
2018/05/27 Javascript
jQuery实现图片上传预览效果功能完整实例【测试可用】
2018/05/28 jQuery
opencv 识别微信登录验证滑动块位置
2018/08/07 Javascript
详解vue-video-player使用心得(兼容m3u8)
2019/08/23 Javascript
Vue computed 计算属性代码实例
2020/04/22 Javascript
[36:29]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 LGD vs TNC
2018/04/02 DOTA
python实现bucket排序算法实例分析
2015/05/04 Python
Python的shutil模块中文件的复制操作函数详解
2016/07/05 Python
使用Python脚本和ADB命令实现卸载App
2017/02/10 Python
OpenCV HSV颜色识别及HSV基本颜色分量范围
2019/03/22 Python
Python 获取 datax 执行结果保存到数据库的方法
2019/07/11 Python
python 实现一个反向单位矩阵示例
2019/11/29 Python
opencv之为图像添加边界的方法示例
2019/12/26 Python
解决pycharm中导入自己写的.py函数出错问题
2020/02/12 Python
css背景图片的背景裁切、背景透明度、背景变换等效果运用
2012/12/24 HTML / CSS
使用html5新特性轻松监听任何App自带返回键的示例
2018/03/13 HTML / CSS
俄罗斯眼镜网: optikaworld
2016/07/31 全球购物
Melijoe英国官网:法国儿童时尚网站
2016/11/18 全球购物
新西兰珠宝品牌:Michael Hill
2017/09/16 全球购物
学习党的群众路线剖析材料
2014/10/09 职场文书
教师考核评语大全
2014/12/31 职场文书
邀请书格式范文
2015/02/02 职场文书
小学生组织委员竞选稿
2015/11/21 职场文书