太阳系模型
效果

参考code
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自适应居中太阳系模型</title>
<style>
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
background: linear-gradient(135deg, #0f2027, #203a43, #2c5364);
font-family: Arial, sans-serif;
overflow: hidden;
}
.container {
position: relative;
width: 90vw;
max-width: 1200px;
height: 90vh;
max-height: 800px;
display: flex;
justify-content: center;
align-items: center;
}
canvas {
display: block;
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
box-shadow: 0 0 30px rgba(0, 100, 255, 0.4);
border-radius: 8px;
}
.title {
position: absolute;
top: 20px;
left: 0;
right: 0;
text-align: center;
color: white;
font-size: 24px;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.7);
z-index: 10;
}
</style>
</head>
<body>
<div class="container">
<div class="title">太阳系模型</div>
<canvas id="solarSystem"></canvas>
</div>
<script>
// 获取canvas元素和上下文
const canvas = document.getElementById('solarSystem');
const ctx = canvas.getContext('2d');
// 设置canvas大小为容器大小
function setCanvasSize() {
const container = document.querySelector('.container');
canvas.width = container.clientWidth;
canvas.height = container.clientHeight;
}
// 初始化canvas大小
setCanvasSize();
// 监听窗口大小变化
window.addEventListener('resize', () => {
setCanvasSize();
initStars();
});
// 中心点坐标
let centerX = canvas.width / 2;
let centerY = canvas.height / 2;
// 行星配置 - 根据画布大小调整距离和大小
function getPlanetConfig() {
const minDimension = Math.min(canvas.width, canvas.height);
const scale = minDimension / 600; // 基于原始600的设计比例
return [
{
name: 'sun',
image: 'https://img.alicdn.com/imgextra/i1/O1CN01oVLbLx22VlN34KDQs_!!6000000007126-2-tps-800-800.png',
size: 60 * scale,
distance: 0,
speed: 0,
angle: 0
},
{
name: 'mercury',
image: 'https://img.alicdn.com/imgextra/i2/O1CN01UjgqIB1SrRxQfrflh_!!6000000002300-2-tps-800-800.png',
size: 5 * scale,
distance: 60 * scale,
speed: 4,
angle: 0
},
{
name: 'venus',
image: 'https://img.alicdn.com/imgextra/i3/O1CN01JGEgLU1dfxnVvp91R_!!6000000003764-2-tps-800-800.png',
size: 8 * scale,
distance: 90 * scale,
speed: 3,
angle: 0
},
{
name: 'earth',
image: 'https://img.alicdn.com/imgextra/i4/O1CN01R6wlzD1IhhMlBcGLg_!!6000000000925-2-tps-800-800.png',
size: 10 * scale,
distance: 120 * scale,
speed: 2,
angle: 0
},
{
name: 'mars',
image: 'https://img.alicdn.com/imgextra/i1/O1CN01OlZAk81OVEHJ0pazq_!!6000000001710-2-tps-800-800.png',
size: 7 * scale,
distance: 150 * scale,
speed: 1.5,
angle: 0
},
{
name: 'jupiter',
image: 'https://img.alicdn.com/imgextra/i2/O1CN01MA3Mk51bAhWxWxHim_!!6000000003425-2-tps-800-800.png',
size: 12 * scale,
distance: 180 * scale,
speed: 1,
angle: 0
},
{
name: 'saturn',
image: 'https://img.alicdn.com/imgextra/i2/O1CN01NG2FjS1XDDEofNNhg_!!6000000002889-2-tps-800-800.png',
size: 24 * scale,
distance: 210 * scale,
speed: 0.8,
angle: 0
},
{
name: 'uranus',
image: 'https://img.alicdn.com/imgextra/i1/O1CN01wnxTX51xIPkTHqPBr_!!6000000006420-2-tps-800-800.png',
size: 9 * scale,
distance: 240 * scale,
speed: 0.5,
angle: 0
},
{
name: 'neptune',
image: 'https://img.alicdn.com/imgextra/i1/O1CN01LTf0rT25zwJWsIDkD_!!6000000007598-2-tps-800-800.png',
size: 8 * scale,
distance: 270 * scale,
speed: 0.4,
angle: 0
}
];
}
// 月球配置
function getMoonConfig() {
const minDimension = Math.min(canvas.width, canvas.height);
const scale = minDimension / 600;
return {
name: 'moon',
image: 'https://img.alicdn.com/imgextra/i4/O1CN01Ad5SeB20tv1nfRoA2_!!6000000006908-2-tps-800-800.png',
size: 4 * scale,
distance: 15 * scale,
speed: 8,
angle: 0
};
}
// 图片对象
const images = {};
let allImagesLoaded = false;
let planets = getPlanetConfig();
let moon = getMoonConfig();
// 星星数组
const stars = [];
const starCount = 200;
// 初始化星星
function initStars() {
stars.length = 0; // 清空现有星星
centerX = canvas.width / 2;
centerY = canvas.height / 2;
planets = getPlanetConfig();
moon = getMoonConfig();
for (let i = 0; i < starCount; i++) {
stars.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
size: 0.5 + Math.random() * 0.5,
opacity: 0.5 + Math.random() * 0.5
});
}
}
// 加载图片
function loadImages() {
let loadedCount = 0;
const totalImages = planets.length + 1; // 包括月球
planets.forEach(planet => {
images[planet.name] = new Image();
images[planet.name].onload = () => {
loadedCount++;
if (loadedCount === totalImages) {
allImagesLoaded = true;
animate(); // 开始动画
}
};
images[planet.name].src = planet.image;
});
// 加载月球图片
images[moon.name] = new Image();
images[moon.name].onload = () => {
loadedCount++;
if (loadedCount === totalImages) {
allImagesLoaded = true;
animate(); // 开始动画
}
};
images[moon.name].src = moon.image;
}
// 绘制背景
function drawBackground() {
// 创建径向渐变
const gradient = ctx.createRadialGradient(
centerX, centerY, 0,
centerX, centerY, Math.max(canvas.width, canvas.height) / 1.5
);
gradient.addColorStop(0, '#1C2837');
gradient.addColorStop(1, '#050608');
// 填充背景
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 绘制星星
stars.forEach(star => {
ctx.beginPath();
ctx.arc(star.x, star.y, star.size, 0, Math.PI * 2);
ctx.fillStyle = `rgba(255, 255, 255, ${star.opacity})`;
ctx.fill();
});
}
// 绘制轨道
function drawOrbit(distance) {
ctx.beginPath();
ctx.ellipse(centerX, centerY, distance, distance * 0.7, 0, 0, Math.PI * 2);
ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
ctx.setLineDash([5, 5]);
ctx.stroke();
ctx.setLineDash([]);
}
// 绘制太阳系
function drawSolarSystem() {
// 清空画布
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 绘制背景
drawBackground();
// 绘制行星和轨道
planets.forEach(planet => {
if (planet.distance > 0) {
// 绘制轨道
drawOrbit(planet.distance);
// 计算行星位置
const x = centerX + planet.distance * Math.cos(planet.angle);
const y = centerY + planet.distance * 0.7 * Math.sin(planet.angle);
// 绘制行星
if (allImagesLoaded && images[planet.name]) {
ctx.drawImage(
images[planet.name],
x - planet.size / 2,
y - planet.size / 2,
planet.size,
planet.size
);
} else {
// 如果图片未加载完成,绘制圆形代替
ctx.beginPath();
ctx.arc(x, y, planet.size / 2, 0, Math.PI * 2);
ctx.fillStyle = planet.name === 'sun' ? '#FDB813' : '#87CEEB';
ctx.fill();
}
} else {
// 绘制太阳
if (allImagesLoaded && images[planet.name]) {
ctx.drawImage(
images[planet.name],
centerX - planet.size / 2,
centerY - planet.size / 2,
planet.size,
planet.size
);
} else {
// 如果图片未加载完成,绘制圆形代替
ctx.beginPath();
ctx.arc(centerX, centerY, planet.size / 2, 0, Math.PI * 2);
ctx.fillStyle = '#FDB813';
ctx.fill();
}
}
});
// 绘制地球的月球
const earth = planets.find(p => p.name === 'earth');
if (earth) {
// 计算月球相对于地球的位置
const earthX = centerX + earth.distance * Math.cos(earth.angle);
const earthY = centerY + earth.distance * 0.7 * Math.sin(earth.angle);
// 计算月球位置
const moonX = earthX + moon.distance * Math.cos(moon.angle);
const moonY = earthY + moon.distance * 0.7 * Math.sin(moon.angle);
// 绘制月球
if (allImagesLoaded && images[moon.name]) {
ctx.drawImage(
images[moon.name],
moonX - moon.size / 2,
moonY - moon.size / 2,
moon.size,
moon.size
);
} else {
// 如果图片未加载完成,绘制圆形代替
ctx.beginPath();
ctx.arc(moonX, moonY, moon.size / 2, 0, Math.PI * 2);
ctx.fillStyle = '#C0C0C0';
ctx.fill();
}
}
}
// 动画循环
function animate() {
// 更新行星角度
planets.forEach(planet => {
if (planet.name !== 'sun') {
planet.angle += 0.01 * planet.speed;
}
});
// 更新月球角度
moon.angle += 0.01 * moon.speed;
// 绘制太阳系
drawSolarSystem();
// 请求下一帧
requestAnimationFrame(animate);
}
// 初始化
initStars();
loadImages();
</script>
</body>
</html>

浙公网安备 33010602011771号