博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用HTML5 Canvas为网页添加动态波浪背景
阅读量:5890 次
发布时间:2019-06-19

本文共 5696 字,大约阅读时间需要 18 分钟。

本文出自 “” 博客:

 

    三里屯SOHO商盟    
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

你可能感兴趣的文章
【吉光片羽】短信验证
查看>>
gitlab 完整部署实例
查看>>
GNS关于IPS&ASA&PIX&Junos的配置
查看>>
影响企业信息化成败的几点因素
查看>>
SCCM 2016 配置管理系列(Part8)
查看>>
struts中的xwork源码下载地址
查看>>
ABP理论学习之仓储
查看>>
我的友情链接
查看>>
CentOS图形界面和命令行切换
查看>>
HTML5通信机制与html5地理信息定位(gps)
查看>>
加快ALTER TABLE 操作速度
查看>>
PHP 程序员的技术成长规划
查看>>
python基础教程_学习笔记19:标准库:一些最爱——集合、堆和双端队列
查看>>
js replace,正则截取字符串内容
查看>>
作业2
查看>>
nginx的信号量
查看>>
云im php,网易云IM
查看>>
DEFERRED_SEGMENT_CREATION
查看>>
Ada boost学习
查看>>
开源 java CMS - FreeCMS2.3字典管理
查看>>