近期刚刚接到为微信公众帐号“玩转三里屯”制作首页的任务。

考虑到页面仅仅在手机中浏览。并且手机对canvas的支持又很好,所以打算使用canvas做点不一样的动画。

首先来看下效果图。

要实现这种动画普通的CSS3是鞭长莫及了,仅仅能使用Canvas。好在使用canvas也很easy。

Step1.

新建一个画布(<canvas>)元素,并放在在全部button和logo的下方以免遮挡前面的元素。

<canvas id="canvas" style="position:absolute;top:0px;left:0px;z-index:1;"></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;

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
canvas.width = canvas.parentNode.offsetWidth;
canvas.height = canvas.parentNode.offsetHeight;

Step2.

在画布中画一个充满半个屏幕的矩形。

我们仅仅须要找到矩形的四个定点的坐标,使用Canvas的绘制路径并填充这个路径。

四个点各自是:

(0, 画布高度t/2)
(画布宽度, 画布高度t/2)
(画布宽度 画布高度t/2)
(0, 画布高度t/2)

注意:坐标的(0,0)在画布的左上角。

//填充颜色
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();

//填充颜色
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();

把之前绘制矩形的代码放到loop中。并在绘制矩形的代码之前清空画布中全部的图形。

function loop(){//清空canvasctx.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);
}

function loop(){//清空canvasctx.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);
}

接下来我们更改每一帧中的矩形的高度来模拟波浪的形态。波浪事实上是在波峰与波谷之间做周期性运动。我们如果波峰与波谷间都是50px。那么矩形的高度的变化值应该在-50px到50px之间。为了达到周期性的效果我们採用正弦函数sin(x),由于无论x值怎么变化sin(x)的值始终在-1与1之间。我们新建一个变量 var step =0 使其在每一帧中自增,表示每一帧角度添加一度,并用Math.sin()取他的正弦值。JS中的sin使用的弧度值,我们须要把step转换成弧度值,var angle = step*Math.PI/180; 取角度的正弦值乘以50得到了矩形高度的变化量。

将变化量加在矩形的左上与右上两个顶点的y坐标上。

//初始角度为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

将矩形的顶上的边变成曲线。

在上面的代码中我们用lineTo来绘制矩形的边,为了要绘制曲线我们须要

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.bezierCurveTo(canvas.width /2, canvas.height/2+deltaHeight-50, canvas.width / 2, canvas.height/2+deltaHeightRight-50, canvas.width,canvas.height/2+deltaHeightRight);
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();
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

一个波浪画好了。我们仅仅须要同一时候画3个不同颜色的波浪,而且使不同波浪的角度不同就能够得到效果图中的效果了。

//定义三条不同波浪的颜色
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

加入好button与logo的HTML代码就大功告成了。

查看全部代码请去Github

如有问题或者建议请微博@UED天机。

我会及时回复

也能够收藏天机的官网,http://ued.sexy/  常常更新最新的教程。

======

相关阅读

1.css3动态背景

用Canvas为网页加入动态背景相关推荐

  1. Canvas实现网页星空背景粒子动效跟随光标

    目  录 1. 设计思路 2. 星空背景图片 3. 页面代码 4. 效果图 1. 设计思路 1. 利用样式插入星空背景图片: 2.设置窗口改变时自动修改画布大小(自适应): 3. 编写随机函数(随机数 ...

  2. 用Canvas为网页添加动态背景

    用Canvas为网页添加动态背景 作者:uedtianji 最近刚刚接到为微信公众帐号"玩转三里屯"制作首页的任务.考虑到页面只在手机中浏览,而且手机对canvas的支持又非常好, ...

  3. html5粒子形成图案,html5 canvas粒子形成下雪背景的效果

    本篇文章给大家带来的内容是关于html5 canvas粒子形成下雪背景的效果,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. canvas粒子形成下雪背景 body{ margin: ...

  4. 网页动态背景——随鼠标变换的动态线条(鼠标蜘蛛网特效)

    网页动态背景--随鼠标变换的动态线条 效果图如下 代码如下: <!DOCTYPE HTML> <html> <head> <meta http-equiv=& ...

  5. 通过Canvas画布制作黑客帝国背景

    通过Canvas画布制作黑客帝国背景 电影介绍 先推荐一下这部电影 <黑客帝国>是由华纳兄弟公司发行的系列动作片,该片由沃卓斯基兄弟执导,基努·里维斯.凯莉·安妮·莫斯.劳伦斯·菲什伯恩等 ...

  6. c语言烟花生日快乐图片,html5 canvas生日快乐文字烟花背景动画特效代码下载

    特效描述:生日快乐 文字烟花 背景动画.html5基于canvas绘制酷炫的烟花动画,支持文字烟花适用于生日快乐主题网页动态背景特效. 代码结构 1. 引入JS 2. HTML代码 var canva ...

  7. 打印网页时背景图片的问题

    当我们打印一个网页时,默认情况下,网页的背景图片是不会被打印出来的 这与我们的打印代码无关,需要设置IE便可,如下图: 转载于:https://www.cnblogs.com/blodfox777/a ...

  8. HTML5+canvas激流勇进网页游戏源码

    介绍: HTML5+canvas激流勇进网页游戏,游戏玩法:使用左键.右键和上箭头键移动. 网盘下载地址: http://kekewangLuo.cc/qn9O6AvpNW10 图片:

  9. html网页左侧背景,CSS设置html网页背景图片 CSS设置网页背景颜色

    CSS设置网页背景图片 CSS设置网页背景颜色技术教程篇 本篇DIVCSS5以布局思想介绍使用CSS设置实现网页背景技巧为主,希望对DIV CSS爱好者有帮助.通常对网页设置背景直接对body设置背景 ...

最新文章

  1. 剑指offer:面试题18. 删除链表的节点
  2. 可以用for循环直接删除ArrayList的特定元素吗?可能会出现什么问题?怎样解决?
  3. GetSafeHwnd()函数
  4. 算法--06年华为面试:求两个数组的最小差值(Java实现)
  5. bzoj4514[Sdoi2016]数字配对
  6. 基于WebStorm, React和Ant.Design开发WebAppDemo
  7. R语言学习 - 非参数法生存分析
  8. Codevs 1205 单词反转(Vector以及如何输出string)
  9. .net String Formatter 格式转换
  10. 42表盘直径是从哪测量_万用表测量电容容量的方
  11. windows下的mujoco环境搭建
  12. 五大车载操作(VOS)系统
  13. 程序设计python_Python程序设计—车万翔
  14. balser相机IP设置
  15. Scanf函数,取地址符和字符数组的联系
  16. 利用重力加速度传感器,获取芯片相对水平位置的角度
  17. python第五次作业——潘芊睿
  18. 外置存储权限在哪打开_安卓手机外置sd卡的权限怎么打开?
  19. 知识图谱学习|报告总结|肖仰华: 知识图谱下半场-机遇与挑战
  20. python爬取pubmed的文献_使用python來調用pubmed API快速整理文獻

热门文章

  1. 帝云CMS内容管理系统DiYunCMS v4.3.12
  2. 查看oracle 锁定用户名,oracle用户名被锁定
  3. 微信独立精彩互换抢红包系统源码ThinkPHP开源版
  4. 如何防止WordPress博客内容被恶意复制的教程
  5. ManualResetEvent详解
  6. 用C#读取XML文档
  7. 谈谈C#中的三个关键词new , virtual , override
  8. asp.net页面回传与js调用服务端事件,Postback的原理
  9. YouTube怎么判断影片内含侵权内容? 解析Content ID内容识别系统的原理及功能
  10. 调整谷歌reCAPTCHA大小 How to resize the Google noCAPTCHA reCAPTCHA