您好,登录后才能下订单哦!
最近刚刚接到为微信公众帐号“玩转三里屯”制作首页的任务。考虑到页面只在手机中浏览,而且手机对canvas的支持又非常好,所以打算使用canvas做点不一样的动画。
要实现这样的动画普通的CSS3是鞭长莫及了,只能使用Canvas。好在使用canvas也非常简单。
Step1.
<canvas id="canvas" ></canvas>
将Canvas的宽高设定成其父元素的宽高,以充满他的父元素。也可以直接使用window.innerHeight,window.innerWidth。使其充满整个屏幕。
var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); canvas.width = canvas.parentNode.offsetWidth; canvas.height = canvas.parentNode.offsetHeight;
//填充颜色 ctx.fillStyle = "rgba(0,222,255, 0.2)"; //开始绘制路径 ctx.beginPath(); //左上角 ctx.moveTo(0, canvas.height/2); //右上角 ctx.lineTo(canvas.width, canvas.height/2); //右下角 ctx.lineTo(canvas.width, canvas.height); //左下角 ctx.lineTo(0, canvas.height); //左上角 ctx.lineTo(0, canvas.height/2); //闭合路径 ctx.closePath(); //填充路径 ctx.fill();
运行代码:
Step3.
让矩形动起来。要做动画我们需要持续的清空画布并重新绘制新的矩形,就像电影每秒播放24张图片。我们新建一个loop函数,用来绘制每一帧的图像,并使用requestAnimFrame来告诉浏览器每一帧都要使用loop来绘制。
//如果浏览器支持requestAnimFrame则使用requestAnimFrame否则使用setTimeout window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function( callback ){ window.setTimeout(callback, 1000 / 60); }; })(); function loop(){ requestAnimFrame(loop); } loop();
function loop(){ //清空canvas ctx.clearRect(0,0,canvas.width,canvas.height); //绘制矩形 ctx.fillStyle = "rgba(0,222,255, 0.2)"; ctx.beginPath(); ctx.moveTo(0, canvas.height/2); ctx.lineTo(canvas.width, canvas.height/2); ctx.lineTo(canvas.width, canvas.height); ctx.lineTo(0, canvas.height); ctx.lineTo(0, canvas.height/2); ctx.closePath(); ctx.fill(); requestAnimFrame(loop); }
//初始角度为0 var step = 0; function loop(){ ctx.clearRect(0,0,canvas.width,canvas.height); ctx.fillStyle = "rgba(0,222,255, 0.2)"; //角度增加一度 step++; //角度转换成弧度 var angle = step*Math.PI/180; //矩形高度的变化量 var deltaHeight = Math.sin(angle) * 50; ctx.beginPath(); //在矩形的左上与右上两个顶点加上高度变化量 ctx.moveTo(0, canvas.height/2+deltaHeight); ctx.lineTo(canvas.width, canvas.height/2+deltaHeight); ctx.lineTo(canvas.width, canvas.height); ctx.lineTo(0, canvas.height); ctx.lineTo(0, canvas.height/2+deltaHeight); ctx.closePath(); ctx.fill(); requestAnimFrame(loop); }
将右上顶点的变化值改为角度的余弦,使其左右不同步。var deltaHeightRight = Math.cos(angle) * 50;
//初始角度为0 var step = 0; function loop(){ ctx.clearRect(0,0,canvas.width,canvas.height); ctx.fillStyle = "rgba(0,222,255, 0.2)"; //角度增加一度 step++; //角度转换成弧度 var angle = step*Math.PI/180; //矩形高度的变化量 var deltaHeight = Math.sin(angle) * 50; //矩形高度的变化量(右上顶点) var deltaHeightRight = Math.cos(angle) * 50; ctx.beginPath(); ctx.moveTo(0, canvas.height/2+deltaHeight); //右上顶点 ctx.lineTo(canvas.width, canvas.height/2+deltaHeightRight); ctx.lineTo(canvas.width, canvas.height); ctx.lineTo(0, canvas.height); ctx.lineTo(0, canvas.height/2+deltaHeight); ctx.closePath(); ctx.fill(); requestAnimFrame(loop); }
运行代码:
Step4
bezierCurveTo(cpX1, cpY1, cpX2, cpY2, x, y)
函数。绘制的起点是矩形的左上顶点,结束点为右上顶点。bezierCurveTo函数的参数中(cpX1,cpY1)与(cpX2,cpY2)分别是起点与结束点的控制点,(x,y)为结束点。我们将两个控制点的x值设定在画布的正中心,y值在起始点与终点的y值上面减去50;(canvas.width /2, canvas.height/2+deltaHeight-50),(canvas.width / 2,canvas.height/2+deltaHeightRight-50),可以根据效果调整。
ctx.beginPath(); ctx.moveTo(0, canvas.height/2+deltaHeight); //ctx.lineTo(canvas.width, canvas.height/2+deltaHeightRight); //画曲线 ctx.bezierCurveTo(canvas.width /2, canvas.height/2+deltaHeight-50, canvas.width / 2, canvas.height/2+deltaHeightRight-50, canvas.width, canvas.height/2+deltaHeightRight); ctx.lineTo(canvas.width, canvas.height); ctx.lineTo(0, canvas.height); ctx.lineTo(0, canvas.height/2+deltaHeight); ctx.closePath();
运行代码:
Step5
//定义三条不同波浪的颜色 var lines = ["rgba(0,222,255, 0.2)", "rgba(157,192,249, 0.2)", "rgba(0,168,255, 0.2)"]; function loop(){ ctx.clearRect(0,0,canvas.width,canvas.height); step++; //画3个不同颜色的矩形 for(var j = lines.length - 1; j >= 0; j--) { ctx.fillStyle = lines[j]; //每个矩形的角度都不同,每个之间相差45度 var angle = (step+j*45)*Math.PI/180; var deltaHeight = Math.sin(angle) * 50; var deltaHeightRight = Math.cos(angle) * 50; ctx.beginPath(); ctx.moveTo(0, canvas.height/2+deltaHeight); ctx.bezierCurveTo(canvas.width /2, canvas.height/2+deltaHeight-50, canvas.width / 2, canvas.height/2+deltaHeightRight-50, canvas.width, canvas.height/2+deltaHeightRight); ctx.lineTo(canvas.width, canvas.height); ctx.lineTo(0, canvas.height); ctx.lineTo(0, canvas.height/2+deltaHeight); ctx.closePath(); ctx.fill(); } requestAnimFrame(loop); }
运行代码:
Step6
查看所有代码请去Github
如有问题或者建议请微博@UED天机。我会及时回复
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
开发者交流群:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。