小白在远离小白道路上的第一步就是搭个博客
前言
这次的博文不是接着进行博客布置的教学了,对的,我弃坑了,也许以后会回来补
用HMTL5+canvas画东西也很好玩嘛,来来来,我们来画那种会随机动来动去的星图。先展示一个demo
demo访问地址:动态星图demo
准备
在开始这个动态星图的制作前,我希望你能对canvas和它的常用API有一定的了解,在这里给出一份速成教程,四十分钟到一小时可以看完,初步掌握canvas常用API的使用
HTML5- Canvas入门(一)
HTML5- Canvas入门(二)
HTML5- Canvas入门(三)
HTML5- Canvas入门(四)
HTML5- Canvas入门(五)
HTML5- Canvas入门(六)
HTML5- Canvas入门(七)
这一段就叫它正文好了
首先建立html文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<html>
<head>
<title>canvas star demo</title>
<style type="text/css">
body{
text-align: center;
overflow: hidden;
background: #C4C6C8;
}
</style>
</head>
<body>
<canvas id="mycanvas"></canvas>
</body>
</html>
因为我假定你已经有基础或者已经看完了我贴在上面的速成教程,这一段代码就不加以赘述了,接下来是js代码的编写
变量的定义
1 | var width = window.innerWidth, |
这一段代码设置了基本的样式和尺寸,接下来就是着手制作星团了
星团对象的定义
要完成星团对象的定义,我们可以先对想要达到的效果进行逐步分析、拆解,再对其内部属性和方法进行不断完善
- 先做一个不会动的星团,星团里的所有星星需要一个数组来存储,数组里存储的应该是星星的圆心坐标
- 需要有一个画星星的方法,就命名为
drawStar
好了 - 在demo里看到每个星星都连着其他星星,好带感,所以需要一个画线的方法,就将画线的方法命名为
drawLine
,连线的方法命名为linkStar
好了 - 每个星星的出现的位置应该是随机的,需要一个产生合适随机数的方法,但是这个方法也许不单单用来产生随机位置,还有随机半径等等,所以就钦定为
randomNum
吧 - 这里需要一个方法将上面的几个工具方法组合起来,绘制出完整的星图,不是很会起名了,就叫
initStars
好了,尽管不是很顺口 - 以上几个方法足够产生一个静态的随机星图了,要让它动起来的话,还需要一个能够让星图动起来的方法,对的,
moveStars
到这里的话,已经初步将对象里需要的方法和属性定义好了,接下来是一步步地实现
属性和各工具方法的定义
1 | var Stars = { |
到这一步,我们已经把Stars
对象里需要用到的工具方法的定义工作完成了
完成星图的静态模型
到这里,我们再整理一遍这个方法需要完成的功能:组合各个工具函数绘制出静态的星图
代码如下1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17var Stars = {
...
initStars: function(cont){
var pStars = this;
pStars.starArr = []; //初始化为空数组
cont.clearRect(0,0,cs.width,cs.height);//顺手清理画布
for(let i = 0;i < amount;i++){
pStars.starArr.push(pStars.drawStar(cont,
pStars.randomNum(width,0), //随机生成星星的横坐标
pStars.randomNum(height,0), //随机生成星星的纵坐标
pStars.randomNum(2,15) //随机生成星星的半径
));
//返回对象{x:x,y:y,r:r}到starArr
}
pStars.linkStar(); //连线
},
}
按上述步骤简单组织后,效果如图所示
如果你的和我的不一样,那你肯定哪里出问题了。。
美化
这个静态星图的效果很惊悚没错。。需要稍微美化一下。。
首先,在js代码的头部定义变量处加入1
cont.fillStyle = "rgba(0,0,0,0.05)"; //设置填充样式
接着,修改线段的颜色深浅,我们希望每条线段有不同的深浅度,最好是和线段的长度存在一定关系
先修改方法
drawLine
1
2
3
4
5
6
7
8
9drawLine: function(cxt,x,y,ex,ey,o){
//(x,y),(ex,ey)分别为线段的起点和终点坐标,o为透明度
cxt.beginPath();
cxt.strokeStyle = 'rgba(0,0,0,'+o+')';//为线段定义描边样式
cxt.moveTo(x,y);
cxt.lineTo(ex,ey);
cxt.closePath();
cxt.stroke(); //描边
}修改方法
linkStar
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15linkStar: function(){
var pStars = this; //创建指针指向调用该方法的Stars对象
for(let i = 0;i < amount;i++){
for(let j = 0;j < amount && i+j < amount;j++){
var xx = Math.abs(pStars.starArr[i+j].x - pStars.starArr[i].x),
yy = Math.abs(pStars.starArr[i+j].y - pStars.starArr[i].y),
line = Math.sqrt(xx*xx,yy*yy),
o = 1/line*7-0.009;
o= o > 0.05 ? 0.05 :o;
pStars.drawLine(cont,
pStars.starArr[i+j].x,pStars.starArr[i+j].y,
pStars.starArr[i].x,pStars.starArr[i].y,o)
}
}
}
修改之后,会呈现如下图效果
完成星图的动态模型
接下来就是制作动态星图的模型了,要实现canvas的动画效果,普遍的做法是在经过一定时间间隔后进行重绘。如此,一个较为简单且容易想到的思路就出现了,经过初始化后的静态星图模型已经将所有星星的的坐标存放于数组starArr
中,只需要在清理画布后,将数组内的坐标加上适当偏移后绘制出来,即可达到想要的动态效果。为此,我们需要在对象数组starArr
中为对象添加其他属性1
2
3
4
5
6
7
8
9
10
11var Stars = {
...
moveStars: function(){
var pStars = this;
for(let i = 0;i < amount;i++){
pStars.starArr[i].moveX = pStars.randomNum(10,-10)/40;
pStars.starArr[i].moveY = pStars.randomNum(10,-10)/40;
}
...
}
}
上面的代码已经为对象数组中的元素添加了新的属性,即偏移量,接下来就是设置定时器使星图重绘了1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19var Stars = {
...
moveStars: function(){
...
setInterval(function(){
cont.clearRect(0,0,cs.width,cs.height); //清理
for(let i = amount - 1;i >= 0;i--){
var star = pStars.starArr[i];
star.x += star.moveX;
star.y += star.moveY;
//完成偏移
star.x < 0 ? (star.x = cs.width) : (star.x > cs.width ? star.x = 0 : '');
star.y < 0 ? (star.y = cs.height) : (star.y > cs.height ? star.y = 0 : '');
Stars.drawStar(cont,star.x,star.y,star.r);
}
Stars.linkStar();
},50)
}
}
至此,就已经将对象的方法和属性全定义完啦,最后一步就是组织js函数调用这个对象
调用
1 | window.onload = function(){ |
组合之后,就能够显示出动态星图的效果啦
美化二
本来想做美化的,做成真正星星那样,但是好麻烦啊,先留着坑,有空再做好了(其实后来作者弃坑了,被繁重的学业压垮了脊梁)
全部代码
1 | <!DOCTYPE html> |
结语
1 | function Achievement(){ |