实现步骤
1. 中心圆形与随机圆形
- 在 Canvas 中心绘制一个固定圆形。
- 在画布其他地方随机生成 5 个圆形,记录每个圆形的初始位置。
2. 鼠标点击事件
- 获取鼠标点击坐标,并计算与中心圆形之间的距离和角度。
3. 圆形反向移动
- 5 个随机圆形根据中心点为参考,向反方向移动。
- 使用
Math.atan2
计算移动的角度,并用Math.cos
和Math.sin
更新圆形的位置。
4. 动画与停止
- 使用
requestAnimationFrame
实现动画,逐帧更新圆的位置。 - 当所有圆形的移动距离达到目标值时,停止动画。
案例代码实现
<canvas id="myCanvas" width="600" height="400" style="border:1px solid #000;"></canvas>
<script>
const canvas = document.getElementById("myCanvas");
const ctx = canvas.getContext("2d");
// 初始化画布中心坐标
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
const centerX = canvasWidth / 2;
const centerY = canvasHeight / 2;
// 定义中心圆形
const centerCircle = {
x: centerX,
y: centerY,
radius: 20,
color: "blue",
};
// 场景中随机生成 5 个圆形
const sceneCircles = [];
for (let i = 0; i < 5; i++) {
sceneCircles.push({
x: Math.random() * canvasWidth, // 随机 x 坐标
y: Math.random() * canvasHeight, // 随机 y 坐标
radius: 15,
color: "red",
speed: 3, // 移动速度
targetX: null, // 目标 x 坐标
targetY: null, // 目标 y 坐标
moving: false, // 是否在移动
});
}
// 绘制中心圆形
function drawCenterCircle() {
ctx.beginPath();
ctx.arc(centerCircle.x, centerCircle.y, centerCircle.radius, 0, 2 * Math.PI);
ctx.fillStyle = centerCircle.color;
ctx.fill();
}
// 绘制场景圆形
function drawSceneCircles() {
sceneCircles.forEach((circle) => {
ctx.beginPath();
ctx.arc(circle.x, circle.y, circle.radius, 0, 2 * Math.PI);
ctx.fillStyle = circle.color;
ctx.fill();
});
}
// 更新圆形的位置
function moveSceneCircles() {
sceneCircles.forEach((circle) => {
if (!circle.moving) return;
// 计算剩余距离
const dx = circle.targetX - circle.x;
const dy = circle.targetY - circle.y;
const distance = Math.sqrt(dx * dx + dy * dy);
// 如果距离小于速度,直接停止
if (distance < circle.speed) {
circle.x = circle.targetX;
circle.y = circle.targetY;
circle.moving = false;
return;
}
// 根据角度计算下一步移动
const angle = Math.atan2(dy, dx);
circle.x += circle.speed * Math.cos(angle);
circle.y += circle.speed * Math.sin(angle);
});
}
// 动画循环
function animate() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight); // 清除画布
drawCenterCircle();
drawSceneCircles();
moveSceneCircles();
requestAnimationFrame(animate);
}
// 鼠标点击事件
canvas.addEventListener("click", (event) => {
// 获取鼠标点击的坐标
const rect = canvas.getBoundingClientRect();
const mouseX = event.clientX - rect.left;
const mouseY = event.clientY - rect.top;
// 计算点击位置与中心圆的距离和角度
const dx = mouseX - centerCircle.x;
const dy = mouseY - centerCircle.y;
const distance = Math.sqrt(dx * dx + dy * dy);
const angle = Math.atan2(dy, dx);
// 为每个场景圆形设置目标点(反方向)
sceneCircles.forEach((circle) => {
circle.targetX = circle.x - distance * Math.cos(angle);
circle.targetY = circle.y - distance * Math.sin(angle);
circle.moving = true; // 开启移动
});
});
// 初始绘制并启动动画
drawCenterCircle();
drawSceneCircles();
animate();
</script>
标签:canvas,场景,const,ctx,圆形,dx,circle,移动,Math From: https://blog.csdn.net/lixin5456985/article/details/144298497