如何在Canvas中实现地球绕太阳旋转?含地月日三星系统动画需求
嘿,这个迷你太阳系的需求超有意思!我来帮你把这个动画效果完整实现出来,结合你给出的部分drawSun代码,咱们一步步搞定:
核心实现思路
要实现天体的环绕效果,核心就是利用角度递增+圆周坐标计算:
- 用
requestAnimationFrame创建流畅的动画循环 - 为地球绕太阳、月球绕地球分别设置角度变量,每次循环让角度缓慢增加
- 通过三角函数
Math.cos()和Math.sin()计算每个天体在当前角度下的位置(公式:x = 中心X + 轨道半径 * cos(弧度角度),y = 中心Y + 轨道半径 * sin(弧度角度))
完整代码实现
HTML部分
<canvas id="solarSystem" width="800" height="600"></canvas>
JavaScript部分
const canvas = document.getElementById('solarSystem'); const context = canvas.getContext('2d'); // 定义天体参数 const sunRadius = 150; const earthOrbitRadius = 250; const earthRadius = 30; const moonOrbitRadius = 50; const moonRadius = 10; // 旋转角度变量(初始为0,弧度制) let earthRotationAngle = 0; let moonRotationAngle = 0; // 绘制太阳(基于你给出的代码完善) function drawSun() { const centerX = canvas.width / 2; const centerY = canvas.height / 2; context.beginPath(); context.arc(centerX, centerY, sunRadius, 0, 2 * Math.PI, false); context.fillStyle = '#FDB813'; // 太阳黄色 context.fill(); context.strokeStyle = '#FFA500'; context.lineWidth = 3; context.stroke(); } // 绘制地球 function drawEarth(x, y) { context.beginPath(); context.arc(x, y, earthRadius, 0, 2 * Math.PI, false); context.fillStyle = '#1E90FF'; // 地球蓝色 context.fill(); context.strokeStyle = '#0066CC'; context.lineWidth = 2; context.stroke(); } // 绘制月球 function drawMoon(x, y) { context.beginPath(); context.arc(x, y, moonRadius, 0, 2 * Math.PI, false); context.fillStyle = '#C0C0C0'; // 月球灰色 context.fill(); context.strokeStyle = '#808080'; context.lineWidth = 1; context.stroke(); } // 动画循环函数 function animate() { // 清除画布,准备下一帧绘制 context.clearRect(0, 0, canvas.width, canvas.height); // 1. 绘制太阳(固定在画布中心) drawSun(); const sunCenterX = canvas.width / 2; const sunCenterY = canvas.height / 2; // 2. 计算地球当前位置:绕太阳旋转 const earthX = sunCenterX + earthOrbitRadius * Math.cos(earthRotationAngle); const earthY = sunCenterY + earthOrbitRadius * Math.sin(earthRotationAngle); drawEarth(earthX, earthY); // 3. 计算月球当前位置:绕地球旋转 const moonX = earthX + moonOrbitRadius * Math.cos(moonRotationAngle); const moonY = earthY + moonOrbitRadius * Math.sin(moonRotationAngle); drawMoon(moonX, moonY); // 增加角度,控制旋转速度(数值越小转得越慢) earthRotationAngle += 0.01; moonRotationAngle += 0.03; // 月球转得比地球快 // 循环调用,实现持续动画 requestAnimationFrame(animate); } // 启动动画 animate();
关键细节说明
- 旋转速度控制:通过调整
earthRotationAngle和moonRotationAngle的增量值,可以改变天体的旋转快慢,比如月球的增量设为0.03,比地球的0.01快,符合真实天体的运动比例 - 画布清除:每次动画循环开始时用
clearRect清除整个画布,避免前一帧的图形残留 - 坐标计算逻辑:地球的中心是太阳的位置,月球的中心是地球的当前位置,这样就能实现“月球绕地球,地球绕太阳”的嵌套环绕效果
内容的提问来源于stack exchange,提问作者Aleks339
相关产品推荐
相关产品推荐

