Canvas—小球动画
前言:该动画就是逐帧改变小球位置,主要实现分为三部分:边界回弹判定,计算小球位置,绘制小球
边界回弹判定
判定分为上下左右四个方向,就是将入射角改变为反射角
这里要提到一点,角度是顺时针从0到360度的,与常识中的相反
// 边界判定
function arriveBorder(ball){
var d = ball.d;
if (ball.x < (ball.r)) { // 左
ball.d = d > 180? 360 - (d - 180) : (180 - d);
ball.x = (1 + ball.r);
}else if (ball.x > (width - ball.r)) { // 右
ball.d = d > 180? 360 - (d - 180) : (180 - d);
ball.x = (width - ball.r - 1);
}else if (ball.y <= (0 + ball.r)) { // 上
ball.d = 360 - d;
ball.y = (0 + ball.r);
}else if(ball.y >= (height - ball.r)) { // 下
ball.d = 360 - d;
ball.y = (height - ball.r);
console.log(ball.d);
}
return ball;
}
计算小球位置
根据小球的速度,计算“单位时间内”小球x,y的变化
// 计算小球移动的位置
function move(ball){
// 弧长
var l = 2 * Math.PI / 360 * ball.d;
ball.x = parseInt(ball.x + Math.cos(l) * ball.v);
ball.y = parseInt(ball.y + Math.sin(l) * ball.v);
return ball;
}
绘制小球
根据小球的具体属性绘制小球的大小,位置
// 绘制小球
function drawBall(ball){
ctx.beginPath();
ctx.fillStyle = ball.color; // 填充颜色
ctx.arc(ball.x,ball.y,ball.r,0,Math.PI*2,true); // 圆
ctx.shadowBlur=3; // 阴影绘制
ctx.shadowColor="#333"; // 阴影绘制
ctx.closePath();
ctx.fill();
}
形成动画
首先初始化数据
// 初始化数据
function init(){
var aroundL = width / 2 - 100;
var aroundR = width / 2 + 100;
var aroundT = height / 2 - 100;
var aroundB = height / 2 + 100;
var maxR = 30; // 随机生成半径的最大值
var minR = 15; // 随机生成半径的最小值
var maxV = 8; // 最大v
var minV = 3; // 最小v
var maxD = 150; // 最大角度
var minD = 30; // 最小角度
for (var i = 0; i < 50; i++) {
var ball = {};
ball.x = parseInt(Math.random()*(aroundR-aroundL+1)+aroundL);
ball.y = parseInt(Math.random()*(aroundB-aroundT+1)+aroundT);
ball.r = parseInt(Math.random()*(maxR-minR+1)+minR);
ball.v = parseInt(Math.random()*(maxV-minV+1)+minV);
ball.d = Math.floor(Math.random() * (maxD - minD)) + minD;
ball.color = colors[parseInt(Math.random()*(colors.length))];
balls.push(ball);
}
setInterval(drawAnimation, 1000 / 60);
// window.requestAnimationFrame(drawAnimation());
}
利用setInterval()方法不断绘制一帧
// 绘制一帧
function drawAnimation(){
ctx.clearRect(0,0,width,height);
for (var i = 0; i < balls.length; i++) {
balls[i] = move(arriveBorder(balls[i]));
drawBall(balls[i]);
}
// window.requestAnimationFrame(drawAnimation());
}
至此整个动画的流程就完了
完整代码后台回复 小球动画 获得
动画绘制公众号原文,有视频展示 齿轮动画原文
欢迎关注骚扰,一起分享技术,探讨生活。