1. 圆形绘制
在画布中心绘制一个圆形,并初始化圆形的坐标和半径。
2. 鼠标点击事件
为 Canvas 添加鼠标点击事件,记录点击的目标坐标。
3. 移动逻辑
- 使用
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;
// 圆的初始属性
let circle = {
x: canvasWidth / 2, // 圆心初始 x 坐标
y: canvasHeight / 2, // 圆心初始 y 坐标
radius: 20, // 圆的半径
color: "blue", // 圆的颜色
speed: 3, // 移动速度
moving: false, // 是否正在移动
targetX: null, // 目标点 x 坐标
targetY: null // 目标点 y 坐标
};
// 绘制圆形
function drawCircle() {
ctx.clearRect(0, 0, canvasWidth, canvasHeight); // 清除画布
ctx.beginPath();
ctx.arc(circle.x, circle.y, circle.radius, 0, 2 * Math.PI);
ctx.fillStyle = circle.color;
ctx.fill();
}
// 计算圆的下一步位置
function moveCircle() {
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);
// 根据角度计算 x 和 y 方向的位移
circle.x += circle.speed * Math.cos(angle);
circle.y += circle.speed * Math.sin(angle);
}
// 动画循环
function animate() {
moveCircle();
drawCircle();
requestAnimationFrame(animate);
}
// 添加鼠标点击事件
canvas.addEventListener("click", (event) => {
// 获取鼠标点击坐标
const rect = canvas.getBoundingClientRect(); // 获取画布位置
const mouseX = event.clientX - rect.left;
const mouseY = event.clientY - rect.top;
// 设置目标点为点击位置,并开启移动
circle.targetX = mouseX;
circle.targetY = mouseY;
circle.moving = true;
});
// 初始绘制并启动动画
drawCircle();
animate();
</script>
代码结构
1. 数据结构
circle
对象包含了圆形的所有关键属性:
- 坐标:
x
,y
。 - 目标位置:
targetX
,targetY
。 - 状态:
moving
用于控制动画。 - 运动参数:
speed
表示圆移动的速度。
2. 逻辑说明
2.1 鼠标点击事件
- 点击时获取鼠标相对于 Canvas 的坐标。
- 设置目标点为鼠标点击的坐标,并将
moving
设置为true
。
2.2 角度计算
- 使用
Math.atan2(dy, dx)
计算圆心与目标点之间的角度。 - 用三角函数计算 x 和 y 的增量,保证圆沿直线方向移动。
2.3 动画更新
- 动画由
requestAnimationFrame
驱动,每帧更新圆的坐标并重新绘制。 - 当圆接近目标点时,停止动画。
动画效果特点
-
平滑移动:
- 使用逐帧更新,确保圆在屏幕上平滑移动。
- 利用
Math.atan2
保证了移动方向的准确性。
-
自然停止:
- 距离判断
if (distance < circle.speed)
,当圆心与目标点的距离小于速度时,停止动画。
- 距离判断
-
实时交互:
- 鼠标点击触发事件,更新目标点位置,随时重新移动圆形。