先绘制一个小球
小球的大小,颜色等定义
ball.js
class Ball {
constructor(props) {
this.x = 0;
this.y = 0;
this.r = 20;
//设置小球的横向速度和纵向速度
this.vx = 0;
this.vy = 0;
//横向缩放倍数
this.scaleX = 1;
//纵向缩放倍数
this.scaleY = 1;
this.strokeStyle = 'rgba(1,0,0,0)';
this.fillStyle = 'rgba(57,119,224)'
this.alpha = 1
Object.assign(this, props);
return this;
}
render(ctx) {
let { x, y, r, scaleX, scaleY, fillStyle, strokeStyle, alpha } = this;
ctx.save();
ctx.translate(x, y);
ctx.scale(scaleX, scaleY);
ctx.strokeStyle = strokeStyle;
ctx.fillStyle = fillStyle;
ctx.globalAlpha = alpha;
ctx.beginPath()
ctx.arc(0, 0, r, 0, 2 * Math.PI);
ctx.fill();
ctx.stroke();
ctx.restore();
return this
}
}
工具类
utils.js
let C = {};
//获取鼠标在元素上的坐标
C.getOffset = function(ele){
let mouse = {x: 0,y: 0};
ele.addEventListener('mousemove',function(e){
let {x,y} = C.eventWrapper(e);
mouse.x = x;
mouse.y = y;
})
return mouse;
};
//坐标系转换
C.eventWrapper = function (ev){
let {pageX,pageY,target} = ev;
let {left,top} = target.getBoundingClientRect();
return {x: pageX - left,y:pageY - top};
};
//角度转弧度
C.toRad = function (angle){
return angle * Math.PI / 180;
};
//弧度转角度
C.toAngle = function(rad){
return rad * 180 / Math.PI
};
//封装一下生成随机数
//两个参数,第一个是数组,第二个是是否是整数
C.rp = function(arr,int){
const max = Math.max(...arr);//调用:C.rp([10,20],true);有true传的就是随机的整数,没有传的就是随机的小数
const min = Math.min(...arr);
//...将数组展开
const num = Math.random()*(max-min)+min;
return int ? Math.round(num):num;
};
//生成随机数颜色
C.createColor = function(){
return `rgb(${C.rp([55,255],true)},${C.rp([55,255],true)},${C.rp([55,255],true)})`;
}
越界处理
小球碰到边界会反弹
源码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
body,html {
margin:0;
height:100%;
}
#canvas{
box-shadow: 4px 4px 12px rgba(0, 0, 0, 0.5);
position: absolute;
top: 10%;
left: 5%;
}
</style>
<body>
<canvas id="canvas"></canvas>
<script src="/js/ball.js"></script>
<script src="/js/utils.js"></script>
<script>
const canvas = document.getElementById('canvas')
const ctx=canvas.getContext('2d');
let W = canvas.width = 800;
let H = canvas.height = 600;
let balls=[];
for(let i=0;i<10;i++){
balls.push(new Ball({
r:C.rp([30,70]),
vx:C.rp([-5,5]),
vy:C.rp([-6,7])
}))
}
function ballMove(ball){
ball.x+=ball.vx;
ball.y+=ball.vy;
//越接处理
if(ball.x-ball.r<=0){
ball.x=ball.r;
ball.vx*=-1;
}
if(ball.x+ball.r>=W){
ball.x=W-ball.r;
ball.vx*=-1
}
if(ball.y-ball.r<=0){
ball.y=ball.r;
ball.vy*=-1;
}
if(ball.y+ball.r>=H){
ball.y=H-ball.r;
ball.vy*=-1
}
ball.render(ctx)
}
(function move(){
window.requestAnimationFrame(move);
ctx.clearRect(0,0,W,H);
balls.forEach(ballMove)
})()
</script>
</body>
</html>
\