canvas 粒子运动之运动的小星星

已被阅读 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)的线;

/net/upload/image/20210320/96fe82e0-b689-488a-9f67-aa73eedd4d10.png

二 绘画一个五角星

绘画五角星,首先要知道五角星的绘画原理;五角星可以看作由十个点依次连接而成;所以求得他们的坐标即可;五角星用内部和外部两个圆辅助,将凸起的五个点与圆心连接,很容易知道内部的五个角度是72°,每个凹点将他们分成36°;所以求每个点的坐标如下图

/net/upload/image/20210320/35b6ff1f-a384-45ea-bddd-cec005d822cc.jpg

突起点和凹点每次加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();//显示上面的画笔结果
                                            
                                        

/net/upload/image/20210320/3f4e88ee-2763-40a0-9833-ee5753dfe189.png

三 绘制多个五角星

绘制多个,我们遍历生成即可;为了方便我们定义一个生成五角星的构造函数;

                                            
// 绘制五角星构造函数
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之间,有正有负,不然星星会向一个方向移动

/net/upload/image/20210320/1fc65741-0153-4689-b5ba-d27e1a0c8706.png

四 让所有星星动起来

动起来的原理很简单,就是每次更新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);
                                            
                                        

/net/upload/image/20210320/ac743f1c-c8c6-4e4b-ade6-7441e41e6536.gif

星星动起来了,但是会逐渐的消失;这是因为星星中心的点位置再不断加位移的过程中超出了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);
                                            
                                        

/net/upload/image/20210320/7d8d7ea3-b0d7-4c38-bd2d-61123f4d0ca1.gif

碰到边界的星星,位移量变成另一个方向的;就会出现反弹的效果,这样我们运动的星星就完成了;全部代码

                                            
<!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号