查看所有代码请去Github

本文出自 “UED” 博客:http://5344794.blog.51cto.com/5334794/1430877

<!DOCTYPE html>
<html>
<head><title>三里屯SOHO商盟</title><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"/><meta name="apple-mobile-web-app-status-bar-style" content="black"/><meta name="apple-mobile-web-app-title" content=""/><meta name="apple-touch-fullscreen" content="YES" /><meta name="apple-mobile-web-app-capable" content="yes" /><meta name="format-detection" content="telephone=no" /><meta name="HandheldFriendly" content="true" /><meta http-equiv="x-rim-auto-match" content="none" /><meta name="format-detection" content="telephone=no" /><!-- This is to force IE into the latest version mode, overriding 'compatibility' mode which breaks everything. --><meta http-equiv="X-UA-Compatible" content="IE=edge" /><link rel="apple-touch-icon-precomposed" sizes="57x57" href="" /><link rel="apple-touch-icon-precomposed" sizes="72x72" href="" /><link rel="apple-touch-icon-precomposed" sizes="114x114" href="" /><link rel="apple-touch-icon-precomposed" sizes="144x144" href="" /><link href="assets/css/reset.css" rel="stylesheet" type="text/css"><link href="assets/css/base.css" rel="stylesheet" type="text/css"><!--feature--><link href="assets/css/index.css" rel="stylesheet" type="text/css"><style type="text/css"></style>
</head>
<body><section class="doc doc--bg2" style="width: 400px;height: 400px;margin: 0 auto;border-radius: 400px;position: relative;border:1px#efefef solid;overflow: hidden;"><canvas id="canvas" style="position:absolute;top:0px;left:0px;z-index:1;"></canvas></section><script type="text/javascript">var canvas = document.getElementById('canvas');  var ctx = canvas.getContext('2d');  canvas.width = canvas.parentNode.offsetWidth;  canvas.height = canvas.parentNode.offsetHeight;//如果浏览器支持requestAnimFrame则使用requestAnimFrame否则使用setTimeout
        window.requestAnimFrame = (function(){  return  window.requestAnimationFrame       ||  window.webkitRequestAnimationFrame ||  window.mozRequestAnimationFrame    ||  function( callback ){  window.setTimeout(callback, 1000 / 60);  };  })();  //初始角度为0  var step = 0;  //定义三条不同波浪的颜色  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);  }  loop(); </script>
</body>
</html>

View Code

首先来看下效果图。

要实现这样的动画普通的CSS3是鞭长莫及了,只能使用Canvas。好在使用canvas也非常简单。

Step1.

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

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

将Canvas的宽高设定成其父元素的宽高,以充满他的父元素。也可以直接使用window.innerHeight,window.innerWidth。使其充满整个屏幕。

1
2
3
4
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)在画布的左上角。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//填充颜色
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来绘制。

1
2
3
4
5
6
7
8
9
10
11
12
13
//如果浏览器支持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中,并在绘制矩形的代码之前清空画布中所有的图形。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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);
}

接下来我们更改每一帧中的矩形的高度来模拟波浪的形态,波浪其实是在波峰与波谷之间做周期性运动。我们假设波峰与波谷间都是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坐标上。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//初始角度为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;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//初始角度为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),可以根据效果调整。

1
2
3
4
5
6
7
8
9
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个不同颜色的波浪,并且使不同波浪的角度不同就可以得到效果图中的效果了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//定义三条不同波浪的颜色
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

添加好按钮与logo的HTML代码就大功告成了。

转载于:https://www.cnblogs.com/CB/p/6094358.html

用HTML5 Canvas为网页添加动态波浪背景相关推荐

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

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

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

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

  3. html 星空效果,html5 canvas炫酷旋转银河系星空背景特效

    这是一款html5 canvas炫酷旋转银河系星空背景特效.该特效通过canvas来绘制银河系星盘,并制作星系旋转的效果,非常炫酷. 使用方法 HTML结构 该旋转银河系星空背景特效的HTML结果只需 ...

  4. Hexo博客主题Next添加动态线条背景canvas_nest

    ​欢迎光临我的博客查看最新文章: https://river106.cn Hexo 版本:5.4.0 Next版本:8.7.1 为了美化Hexo博客,可以给博客添加动态线条背景,这里使用canvas_ ...

  5. html画星空,html5 canvas绘制全屏的星空背景动画特效

    特效描述:html5 canvas绘制 全屏星空背景 动画特效.html5 canvas背景动画,星空动画.连线区域跟随鼠标移动,外加碰壁检测 代码结构 1. 引入JS 2. HTML代码 var m ...

  6. 如何在html网页添加动态特效,《让网页动起来----动态HTML》教学案例

    <<让网页动起来----动态HTML>教学案例.doc>由会员分享,可免费在线阅读全文,更多与<<让网页动起来----动态HTML>教学案例>相关文档资 ...

  7. 用html5制作机柜,基于HTML5 Canvas 点击添加 2D 3D 机柜模型

    今天又返回好好地消化了一下我们的数据容器 DataModel,这里给新手做一个典型的数据模型事件处理的例子作为参考.这个例子看起来很简单,实际上结合了数据模型中非常重要的三个事件处理的部分:属性变化事 ...

  8. HTML5 canvas画布元素 制作 动态花朵动画

    废话不多说 先上代码 <!doctype> <html> <head> <meta charset="utf-8"> </he ...

  9. 基于HTML5 Canvas 点击添加 2D 3D 机柜模型

    今天又返回好好地消化了一下我们的数据容器 DataModel,这里给新手做一个典型的数据模型事件处理的例子作为参考.这个例子看起来很简单,实际上结合了数据模型中非常重要的三个事件处理的部分:属性变化事 ...

最新文章

  1. 使用 XSL 样式表无法查看 XML 输入。请更正错误然后单击 刷新按钮,或以后重试。...
  2. MySql数据库连接超时处理
  3. java弧线_数据可视化API之弧线图实现
  4. UIView局部点击(转)
  5. ubuntu 配置python,Redis,Mysql
  6. 嵌入式系统硬件原理设计与审核
  7. 群体智能优化算法之粒子群优化算法
  8. 通篇详解-CMMM智能制造能力成熟度
  9. 西安三星电子笔试面试
  10. 学习计算机编程(IT、偏网站开发)的参考学习网址syk
  11. FB OpenGraph og:image无法提取图像(可能是https?)
  12. Beego项目打包部署到Linux服务器
  13. python数据分析处理:PUBG Finish Placement Prediction
  14. 48脚STM32内部基准电压校准ADC的一些心得记录
  15. VMware虚拟桌面
  16. 常见路由器默认登录用户名和密码(大全)
  17. React 16.8.6 版本存在内存泄露
  18. python中print()换行的问题
  19. 【稳定性day5】阿里自动压测及容量规划 - 对抗流量的必杀器
  20. 龙讯|LT9611UXC双端口MIPI DSI/CSI转HDMI2.0转换器

热门文章

  1. 解决用word修改博客后字体变大的问题
  2. 转: SQLite内建函数表
  3. 纪事:最后的足球比赛
  4. 【Java】springboot 的学习笔记 的第一天
  5. Java实现 给定三个 int 变量, 求其中的最大值和最小值
  6. python交互式解释器下载_Python解释器
  7. kafka java_Java操作Kafka
  8. freerdp 解压安装_Linux下安装FreeRDP,连接windows远程桌面的好软件 | 学步园
  9. python写数据库校验_Python:生成验证码并插入到数据库!
  10. UI设计为什么要使用Figma?