已被阅读 1305 次 | 文章分类:javascript | 2021-03-20 00:37
本节利用canvas绘制一些会动的小星星;首先画一个小五角星,然后画多个;最后让多个小星星动起来;canvas就是javascript中的内置库,本质是javascript
一 canvas绘画原理
canvas绘画,跟普通画画一样;需要一根画笔和一张画布即可;基本代码如下;其他的语法课参照一些入门网站
// 定义canvas
let canvas=document.createElement('canvas');
canvas.width=600;
canvas.height=600;
document.body.append(canvas);
// 获取画布,定义画布大小和颜色
let ctx=canvas.getContext('2d');
ctx.fillStyle="gray";
ctx.fillRect(0,0,500,500);
// 定义绘画的路径
ctx.beginPath();
ctx.lineTo(0,0);
ctx.lineTo(100,500);
ctx.closePath();
// 落笔
ctx.stroke();
其中lineTo()方法是定义画笔位置,stroke是执行画笔过程;跟定义函数和调用函数一个道理;如果只定义不调用是不生效的;上面代码画一条(0,0)点到(100,500)的线;
二 绘画一个五角星
绘画五角星,首先要知道五角星的绘画原理;五角星可以看作由十个点依次连接而成;所以求得他们的坐标即可;五角星用内部和外部两个圆辅助,将凸起的五个点与圆心连接,很容易知道内部的五个角度是72°,每个凹点将他们分成36°;所以求每个点的坐标如下图
突起点和凹点每次加72°就可以求出其他剩余的八个点;计算代码如下: 定义了中心点坐标,大小圆半径大小;
let centerX=250,centerY=250,R=200,r=110;
ctx.beginPath()
for(let i=0;i<5;i++){
let angle0=18+i*72,angle1=54+i*72;
ctx.lineTo(Math.cos(angle0*Math.PI/180)*R+centerX,-Math.sin(angle0*Math.PI/180)*R+centerY);
ctx.lineTo(Math.cos(angle1*Math.PI/180)*r+centerX,-Math.sin(angle1*Math.PI/180)*r+centerY);
}
ctx.closePath();//闭合当前点和第一个
ctx.stroke();//显示上面的画笔结果
三 绘制多个五角星
绘制多个,我们遍历生成即可;为了方便我们定义一个生成五角星的构造函数;
// 绘制五角星构造函数
function star(ctx,r,R,x,y,rotate){
this.ctx=ctx;
this.r=r;
this.R=R;
this.x=x;
this.y=y;
this.ctx.beginPath();
for(let i=0;i<5;i++){
let angle0=18+i*72-rotate,angle1=54+i*72-rotate;
this.ctx.lineTo(Math.cos(angle0*Math.PI/180)*this.R+this.x,-Math.sin(angle0*Math.PI/180)*this.R+ this.y);
this.ctx.lineTo(Math.cos(angle1*Math.PI/180)* this.r+this.x,-Math.sin(angle1*Math.PI/180)* this.r+ this.y);
}
this.ctx.lineWidth="1";
this.ctx.fillStyle = "red";
this.ctx.strokeStyle = "green";
this.ctx.closePath();//闭合当前点和第一个点
this.ctx.stroke();//显示上面的画笔结果
}
然后定义随机数函数,遍历随机生成40个五角星
//获取固定范围的随机值
function getRandom(min,max){
return Math.random()*(max-min)+min
}
let objs=[];
for(let i=0;i<40;i++){
let obj={};
obj.x=getRandom(100,500),
obj.y=getRandom(100,500)
obj.rotate=getRandom(0,180);
obj.speedX = getRandom(-2,2);
obj.speedY=getRandom(-2,2);
objs.push(obj)
let star1=new star(ctx,5,12, obj.x, obj.y, obj.rotate);
}
在绘制五角星时,可以看到多了一个参数,那就是rotate,如果没有该参数,绘制的40个五角星,每个五角星五角的朝向都会一样,所以加个随机的旋转角度;而其中speedX参数,是后面我们更改星星位置的位移值,这里也可以理解为速度,位移取-2到2之间,有正有负,不然星星会向一个方向移动
四 让所有星星动起来
动起来的原理很简单,就是每次更新40个星星的位置,canvas中的表现就是每次清空画布,然后重画更新位置后的星星
setInterval(() => {
ctx.clearRect(0,0,600,600)
ctx.fillStyle="gray";
ctx.fillRect(0,0,600,600)
for(let i=0;i<40;i++){
objs[i].x=objs[i].x+objs[i].speedX
objs[i].y= objs[i].y+objs[i].speedY
let star1=new star(ctx,5,12, objs[i].x, objs[i].y,objs[i].rotate);
}
}, 10);
星星动起来了,但是会逐渐的消失;这是因为星星中心的点位置再不断加位移的过程中超出了canvas范围,所以需要判断,如果超出范围,让它的
setInterval(() => {
ctx.clearRect(0,0,500,500)
ctx.fillStyle="balck";
ctx.fillRect(0,0,500,500)
for(let i=0;i<40;i++){
objs[i].x=objs[i].x+objs[i].speedX
objs[i].y= objs[i].y+objs[i].speedY
if( objs[i].x>500){
objs[i].speedX-=getRandom(1,2)
}
if( objs[i].x<0){
objs[i].speedX+=getRandom(1,2)
}
if( objs[i].y>500){
objs[i].speedY-=getRandom(1,2)
}
if( objs[i].y<0){
objs[i].speedY+=getRandom(1,2)
}
let star1=new star(ctx,5,12, objs[i].x, objs[i].y,objs[i].rotate);
}
}, 10);
碰到边界的星星,位移量变成另一个方向的;就会出现反弹的效果,这样我们运动的星星就完成了;全部代码
<!DOCTYPE html>
<html>
<head>
<title>运动的星星</title>
</head>
<body>
</body>
<script>
// 定义canvas
let canvas=document.createElement('canvas');
canvas.width=500;
canvas.height=500;
document.body.append(canvas);
// 获取画布,定义画布大小和颜色
let ctx=canvas.getContext('2d');
ctx.fillStyle="gray";
ctx.fillRect(0,0,500,500);
// 绘制五角星构造函数
function star(ctx,r,R,x,y,rotate){
this.ctx=ctx;
this.r=r;
this.R=R;
this.x=x;
this.y=y;
this.ctx.beginPath();
for(let i=0;i<5;i++){
let angle0=18+i*72-rotate,angle1=54+i*72-rotate;
this.ctx.lineTo(Math.cos(angle0*Math.PI/180)*this.R+this.x,-Math.sin(angle0*Math.PI/180)*this.R+ this.y);
this.ctx.lineTo(Math.cos(angle1*Math.PI/180)* this.r+this.x,-Math.sin(angle1*Math.PI/180)* this.r+ this.y);
}
this.ctx.lineWidth="1";
this.ctx.strokeStyle = "white";
this.ctx.closePath();//闭合当前点和第一个点
this.ctx.stroke();//显示上面的画笔结果
}
//获取固定范围的随机值
function getRandom(min,max){
return Math.random()*(max-min)+min
}
let objs=[];
for(let i=0;i<40;i++){
let obj={};
obj.x=getRandom(0,500),
obj.y=getRandom(0,500)
obj.rotate=getRandom(0,180);
obj.speedX = getRandom(-2,2);
obj.speedY=getRandom(-2,2);
objs.push(obj)
let star1=new star(ctx,5,12, obj.x, obj.y, obj.rotate);
}
setInterval(() => {
ctx.clearRect(0,0,500,500)
ctx.fillStyle="black";
ctx.fillRect(0,0,500,500)
for(let i=0;i<40;i++){
objs[i].x=objs[i].x+objs[i].speedX
objs[i].y= objs[i].y+objs[i].speedY
if( objs[i].x>500){
objs[i].speedX-=getRandom(1,2)
}
if( objs[i].x<0){
objs[i].speedX+=getRandom(1,2)
}
if( objs[i].y>500){
objs[i].speedY-=getRandom(1,2)
}
if( objs[i].y<0){
objs[i].speedY+=getRandom(1,2)
}
let star1=new star(ctx,5,12, objs[i].x, objs[i].y,objs[i].rotate);
}
}, 10);
</script>
</html>
QQ:3410192267 | 技术支持 微信:popstarqqsmall
Copyright ©2017 xiaobaigis.com . 版权所有 鲁ICP备17027716号