如何实现2D场景下一个圆形围绕另一个圆形旋转?
如何实现2D场景下一个圆形围绕另一个圆形旋转?
嘿,我太懂你现在的感受了——本来想做个圆绕着另一个转的动画,结果写出来变成原地自转,完全不是想要的效果对吧?咱们来把代码改一改,核心就是用三角函数计算公转轨道上的实时位置,几步就能搞定~
首先得明确核心问题:你之前的代码只处理了单个圆的自身状态,但公转的关键是围绕中心圆的坐标,实时计算公转圆的位置。咱们用Canvas的话,靠Math.cos()和Math.sin()这两个三角函数就能轻松算出轨道上的点。
直接给你调整好的完整代码,每一步都加了注释,你一看就明白:
var w = window.innerWidth; var h = window.innerHeight; var canvas = document.createElement('canvas'); document.body.appendChild(canvas); canvas.width = w; canvas.height = h; var ctx = canvas.getContext('2d'); // 中心圆的参数:位置在画布中心,半径30 var centerX = w / 2; var centerY = h / 2; var centerRadius = 30; // 公转圆的参数:轨道半径(两个圆心的距离)100,自身半径20 var orbitRadius = 100; var planetRadius = 20; var orbitAngle = 0; // 公转的角度,每一帧递增 function animate() { // 先清空画布,不然会留下上一帧的轨迹 ctx.clearRect(0, 0, w, h); // 第一步:画中心圆 ctx.beginPath(); ctx.arc(centerX, centerY, centerRadius, 0, Math.PI * 2); ctx.fillStyle = '#333'; // 深灰色 ctx.fill(); ctx.closePath(); // 第二步:计算公转圆的实时位置 // 用三角函数把极坐标转成Canvas的笛卡尔坐标 var planetX = centerX + Math.cos(orbitAngle) * orbitRadius; var planetY = centerY + Math.sin(orbitAngle) * orbitRadius; // 第三步:画公转圆 ctx.beginPath(); ctx.arc(planetX, planetY, planetRadius, 0, Math.PI * 2); ctx.fillStyle = '#ff6347'; // 番茄红 ctx.fill(); ctx.closePath(); // 角度递增,控制公转速度——数值越小转得越慢 orbitAngle += 0.02; // 循环调用动画帧,保持流畅动画 requestAnimationFrame(animate); } // 启动动画 animate();
这里的关键就是计算公转圆位置的两行代码:Math.cos(orbitAngle)和Math.sin(orbitAngle)会根据当前角度返回-1到1之间的数值,乘以轨道半径后,再加上中心圆的坐标,就得到了公转圆每一帧的准确位置。
如果你还想让公转圆同时自转,也很简单——在画公转圆之前,给Canvas加个旋转变换就行,比如:
// 画公转圆之前先保存当前画布状态 ctx.save(); // 把坐标系原点移到公转圆的位置 ctx.translate(planetX, planetY); // 让画布自转,这里可以用和公转一样的角度,或者单独的自转角度变量 ctx.rotate(orbitAngle); // 注意:现在画圆的坐标要改成(0,0),因为坐标系已经移过去了 ctx.beginPath(); ctx.arc(0, 0, planetRadius, 0, Math.PI * 2); ctx.fillStyle = '#ff6347'; ctx.fill(); ctx.closePath(); // 恢复画布原来的状态,不影响后续绘制 ctx.restore();
这样就能同时实现公转+自转的效果啦,你可以根据需求调整轨道半径、速度、颜色这些参数,怎么顺眼怎么来~
内容来源于stack exchange




