You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在平移Canvas上让矩形(枪)朝向鼠标旋转?原生JS实现

解决枪围绕玩家旋转并指向鼠标的问题

核心思路

要实现枪固定在玩家身上并指向鼠标,关键是基于玩家位置定位枪的锚点,再通过Math.atan2()计算鼠标相对锚点的角度,最后以锚点为中心旋转枪。

关键步骤

  • 计算鼠标与枪锚点的相对坐标差(向量)
  • 用Math.atan2(dy, dx)获取旋转角度(注意参数顺序:纵向差在前,横向差在后)
  • 通过translate()将画布原点移到枪的锚点,再rotate()到目标角度后绘制枪

修正后的完整代码

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 800;
canvas.height = 600;

// 玩家属性
const player = {
  x: canvas.width / 2,
  y: canvas.height / 2,
  size: 30
};

// 枪属性
const gun = {
  length: 40,
  width: 8,
  offset: 20 // 枪尾部与玩家中心的横向偏移量
};

// 鼠标位置追踪
const mouse = { x: 0, y: 0 };
canvas.addEventListener('mousemove', e => {
  const rect = canvas.getBoundingClientRect();
  mouse.x = e.clientX - rect.left;
  mouse.y = e.clientY - rect.top;
});

function render() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

  // 绘制玩家(蓝色方块)
  ctx.fillStyle = 'blue';
  ctx.fillRect(
    player.x - player.size / 2,
    player.y - player.size / 2,
    player.size,
    player.size
  );

  // 计算枪的锚点位置(玩家中心右侧offset处)
  const anchorX = player.x + gun.offset;
  const anchorY = player.y;

  // 计算鼠标相对锚点的向量
  const dx = mouse.x - anchorX;
  const dy = mouse.y - anchorY;

  // 计算旋转角度(弧度)
  const angle = Math.atan2(dy, dx);

  // 绘制枪:平移到锚点 → 旋转 → 绘制 → 恢复画布状态
  ctx.save();
  ctx.translate(anchorX, anchorY);
  ctx.rotate(angle);
  ctx.fillStyle = 'gray';
  // 以锚点为起点绘制枪(枪尾在锚点,枪身沿角度方向延伸)
  ctx.fillRect(0, -gun.width / 2, gun.length, gun.width);
  ctx.restore();

  requestAnimationFrame(render);
}

render();

常见问题排查

  1. 枪脱离玩家:确保枪的锚点坐标是基于玩家坐标计算的(如anchorX = player.x + gun.offset),而非固定值
  2. 指向角度错误:检查Math.atan2()的参数顺序,必须是(纵向差, 横向差),即dy在前、dx在后
  3. 旋转中心错误:必须先通过translate()将画布原点移到枪的锚点,再执行rotate(),否则会以画布左上角为旋转中心

内容的提问来源于stack exchange,提问作者Pete21

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 22:27:41