天体观测站edit icon

作者:
邓朝元
Fork(复制)
下载
嵌入
BUG反馈
index.html
现在支持上传本地图片了!
index.html
            
            <!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;
            background: #000011;
            font-family: 'Arial', sans-serif;
            overflow: hidden;
        }
        
        #container {
            position: relative;
            width: 100vw;
            height: 100vh;
        }
        
        #canvas {
            display: block;
            cursor: grab;
        }
        
        #canvas:active {
            cursor: grabbing;
        }
        
        #controls {
            position: absolute;
            top: 20px;
            left: 20px;
            background: rgba(0, 0, 0, 0.8);
            padding: 20px;
            border-radius: 10px;
            color: white;
            font-size: 14px;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .control-group {
            margin-bottom: 15px;
        }
        
        label {
            display: block;
            margin-bottom: 5px;
            color: #aaa;
        }
        
        input, select, button {
            background: rgba(255, 255, 255, 0.1);
            border: 1px solid rgba(255, 255, 255, 0.2);
            color: white;
            padding: 8px;
            border-radius: 5px;
            width: 100%;
            box-sizing: border-box;
        }
        
        button {
            cursor: pointer;
            transition: background 0.3s;
        }
        
        button:hover {
            background: rgba(255, 255, 255, 0.2);
        }
        
        #info {
            position: absolute;
            top: 20px;
            right: 20px;
            background: rgba(0, 0, 0, 0.8);
            padding: 20px;
            border-radius: 10px;
            color: white;
            font-size: 12px;
            max-width: 300px;
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        
        .planet-name {
            font-weight: bold;
            color: #4CAF50;
        }
        
        .moon-name {
            color: #FFC107;
            margin-left: 10px;
        }
    </style>
</head>
<body>
    <div id="container">
        <canvas id="canvas"></canvas>
        
        <div id="controls">
            <div class="control-group">
                <label>时间速度:</label>
                <select id="timeSpeed">
                    <option value="0">暂停</option>
                    <option value="1">实时</option>
                    <option value="60">1分钟/秒</option>
                    <option value="3600">1小时/秒</option>
                    <option value="86400" selected>1天/秒</option>
                    <option value="604800">1周/秒</option>
                    <option value="2592000">1月/秒</option>
                    <option value="31536000">1年/秒</option>
                </select>
            </div>
            
            <div class="control-group">
                <label>设置日期:</label>
                <input type="datetime-local" id="dateInput">
                <button onclick="setCurrentTime()">设为当前时间</button>
            </div>
            
            <div class="control-group">
                <label>缩放:</label>
                <input type="range" id="zoomSlider" min="0.1" max="3" step="0.1" value="1">
            </div>
            
            <div class="control-group">
                <button onclick="toggleOrbits()">显示/隐藏轨道</button>
                <button onclick="toggleMoons()">显示/隐藏卫星</button>
            </div>
        </div>
        
        <div id="info">
            <div id="currentTime"></div>
            <div id="planetInfo"></div>
        </div>
    </div>

    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        
        // 画布设置
        function resizeCanvas() {
            canvas.width = window.innerWidth;
            canvas.height = window.innerHeight;
        }
        resizeCanvas();
        window.addEventListener('resize', resizeCanvas);
        
        // 天体数据 (轨道半径按比例缩放,公转周期为地球日)
        const celestialBodies = {
            sun: {
                name: '太阳',
                radius: 20,
                color: '#FDB813',
                x: 0, y: 0
            },
            mercury: {
                name: '水星',
                radius: 2,
                color: '#8C7853',
                orbitRadius: 80,
                period: 88, // 地球日
                angle: 0
            },
            venus: {
                name: '金星',
                radius: 3,
                color: '#FFC649',
                orbitRadius: 110,
                period: 225,
                angle: 0
            },
            earth: {
                name: '地球',
                radius: 4,
                color: '#6B93D6',
                orbitRadius: 150,
                period: 365.25,
                angle: 0,
                moons: [{
                    name: '月球',
                    radius: 1,
                    color: '#C0C0C0',
                    orbitRadius: 15,
                    period: 27.3,
                    angle: 0
                }]
            },
            mars: {
                name: '火星',
                radius: 3,
                color: '#CD5C5C',
                orbitRadius: 200,
                period: 687,
                angle: 0,
                moons: [
                    {
                        name: '火卫一',
                        radius: 0.5,
                        color: '#A0522D',
                        orbitRadius: 8,
                        period: 0.32,
                        angle: 0
                    },
                    {
                        name: '火卫二',
                        radius: 0.5,
                        color: '#A0522D',
                        orbitRadius: 12,
                        period: 1.26,
                        angle: 0
                    }
                ]
            },
            jupiter: {
                name: '木星',
                radius: 12,
                color: '#D8CA9D',
                orbitRadius: 300,
                period: 4333,
                angle: 0,
                moons: [
                    {
                        name: '木卫一',
                        radius: 1,
                        color: '#FFFF99',
                        orbitRadius: 25,
                        period: 1.77,
                        angle: 0
                    },
                    {
                        name: '木卫二',
                        radius: 1,
                        color: '#87CEEB',
                        orbitRadius: 30,
                        period: 3.55,
                        angle: 0
                    },
                    {
                        name: '木卫三',
                        radius: 1.5,
                        color: '#8B4513',
                        orbitRadius: 40,
                        period: 7.15,
                        angle: 0
                    },
                    {
                        name: '木卫四',
                        radius: 1.2,
                        color: '#696969',
                        orbitRadius: 50,
                        period: 16.69,
                        angle: 0
                    }
                ]
            },
            saturn: {
                name: '土星',
                radius: 10,
                color: '#FAD5A5',
                orbitRadius: 400,
                period: 10759,
                angle: 0,
                hasRings: true,
                moons: [
                    {
                        name: '土卫六',
                        radius: 1.5,
                        color: '#CD853F',
                        orbitRadius: 35,
                        period: 15.95,
                        angle: 0
                    },
                    {
                        name: '土卫七',
                        radius: 0.8,
                        color: '#F5DEB3',
                        orbitRadius: 45,
                        period: 21.28,
                        angle: 0
                    }
                ]
            },
            uranus: {
                name: '天王星',
                radius: 7,
                color: '#4FD0E7',
                orbitRadius: 500,
                period: 30687,
                angle: 0,
                moons: [
                    {
                        name: '天卫一',
                        radius: 0.8,
                        color: '#B0E0E6',
                        orbitRadius: 20,
                        period: 8.71,
                        angle: 0
                    },
                    {
                        name: '天卫二',
                        radius: 0.8,
                        color: '#B0E0E6',
                        orbitRadius: 25,
                        period: 13.46,
                        angle: 0
                    }
                ]
            },
            neptune: {
                name: '海王星',
                radius: 7,
                color: '#4169E1',
                orbitRadius: 600,
                period: 60190,
                angle: 0,
                moons: [
                    {
                        name: '海卫一',
                        radius: 1,
                        color: '#FFB6C1',
                        orbitRadius: 22,
                        period: 5.88,
                        angle: 0
                    }
                ]
            }
        };
        
        // 控制变量
        let currentTime = new Date();
        let timeSpeed = 86400; // 默认1天/秒
        let zoom = 1;
        let showOrbits = true;
        let showMoons = true;
        let lastTime = Date.now();
        
        // 参考时间 (J2000.0 epoch: 2000年1月1日12:00 UTC)
        const referenceTime = new Date('2000-01-01T12:00:00Z');
        
        // 初始化
        function init() {
            document.getElementById('dateInput').value = formatDateForInput(currentTime);
            document.getElementById('timeSpeed').value = timeSpeed;
            document.getElementById('zoomSlider').value = zoom;
            
            // 设置初始角度基于当前时间
            updatePlanetPositions();
            
            // 事件监听
            document.getElementById('timeSpeed').addEventListener('change', (e) => {
                timeSpeed = parseInt(e.target.value);
            });
            
            document.getElementById('dateInput').addEventListener('change', (e) => {
                currentTime = new Date(e.target.value);
                updatePlanetPositions();
            });
            
            document.getElementById('zoomSlider').addEventListener('input', (e) => {
                zoom = parseFloat(e.target.value);
            });
            
            animate();
        }
        
        // 格式化日期为input控件格式
        function formatDateForInput(date) {
            const year = date.getFullYear();
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const hours = String(date.getHours()).padStart(2, '0');
            const minutes = String(date.getMinutes()).padStart(2, '0');
            return `${year}-${month}-${day}T${hours}:${minutes}`;
        }
        
        // 设置当前时间
        function setCurrentTime() {
            currentTime = new Date();
            document.getElementById('dateInput').value = formatDateForInput(currentTime);
            updatePlanetPositions();
        }
        
        // 更新行星位置
        function updatePlanetPositions() {
            const daysSinceReference = (currentTime - referenceTime) / (1000 * 60 * 60 * 24);
            
            Object.keys(celestialBodies).forEach(key => {
                const body = celestialBodies[key];
                if (body.period) {
                    // 计算当前角度 (弧度)
                    body.angle = (2 * Math.PI * daysSinceReference / body.period) % (2 * Math.PI);
                    
                    // 更新卫星角度
                    if (body.moons) {
                        body.moons.forEach(moon => {
                            moon.angle = (2 * Math.PI * daysSinceReference / moon.period) % (2 * Math.PI);
                        });
                    }
                }
            });
        }
        
        // 切换轨道显示
        function toggleOrbits() {
            showOrbits = !showOrbits;
        }
        
        // 切换卫星显示
        function toggleMoons() {
            showMoons = !showMoons;
        }
        
        // 绘制函数
        function draw() {
            // 清空画布
            ctx.fillStyle = '#000011';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            
            // 绘制星空背景
            //drawStars();
            
            // 移动到画布中心
            ctx.save();
            ctx.translate(canvas.width / 2, canvas.height / 2);
            ctx.scale(zoom, zoom);
            
            // 绘制轨道
            if (showOrbits) {
                drawOrbits();
            }
            
            // 绘制太阳
            drawCelestialBody(celestialBodies.sun);
            
            // 绘制行星和卫星
            Object.keys(celestialBodies).forEach(key => {
                if (key !== 'sun') {
                    const planet = celestialBodies[key];
                    
                    // 计算行星位置
                    planet.x = Math.cos(planet.angle) * planet.orbitRadius;
                    planet.y = Math.sin(planet.angle) * planet.orbitRadius;
                    
                    // 绘制行星
                    drawCelestialBody(planet);
                    
                    // 绘制土星环
                    if (planet.hasRings) {
                        drawSaturnRings(planet);
                    }
                    
                    // 绘制卫星
                    if (showMoons && planet.moons) {
                        planet.moons.forEach(moon => {
                            moon.x = planet.x + Math.cos(moon.angle) * moon.orbitRadius;
                            moon.y = planet.y + Math.sin(moon.angle) * moon.orbitRadius;
                            drawCelestialBody(moon);
                            
                            // 绘制卫星轨道
                            if (showOrbits) {
                                ctx.beginPath();
                                ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
                                ctx.lineWidth = 1;
                                ctx.arc(planet.x, planet.y, moon.orbitRadius, 0, 2 * Math.PI);
                                ctx.stroke();
                            }
                        });
                    }
                }
            });
            
            ctx.restore();
            
            // 更新信息显示
            updateInfo();
        }
        
        // 绘制星空背景
        function drawStars() {
            ctx.fillStyle = 'white';
            for (let i = 0; i < 200; i++) {
                const x = Math.random() * canvas.width;
                const y = Math.random() * canvas.height;
                const size = Math.random() * 2;
                ctx.beginPath();
                ctx.arc(x, y, size, 0, 2 * Math.PI);
                ctx.fill();
            }
        }
        
        // 绘制轨道
        function drawOrbits() {
            Object.keys(celestialBodies).forEach(key => {
                const body = celestialBodies[key];
                if (body.orbitRadius) {
                    ctx.beginPath();
                    ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
                    ctx.lineWidth = 1;
                    ctx.arc(0, 0, body.orbitRadius, 0, 2 * Math.PI);
                    ctx.stroke();
                }
            });
        }
        
        // 绘制天体
        function drawCelestialBody(body) {
            ctx.save();
            ctx.translate(body.x, body.y);
            
            // 绘制光晕效果(太阳)
            if (body.name === '太阳') {
                const gradient = ctx.createRadialGradient(0, 0, body.radius, 0, 0, body.radius * 2);
                gradient.addColorStop(0, body.color);
                gradient.addColorStop(1, 'rgba(253, 184, 19, 0)');
                ctx.fillStyle = gradient;
                ctx.beginPath();
                ctx.arc(0, 0, body.radius * 2, 0, 2 * Math.PI);
                ctx.fill();
            }
            
            // 绘制天体本体
            ctx.fillStyle = body.color;
            ctx.beginPath();
            ctx.arc(0, 0, body.radius, 0, 2 * Math.PI);
            ctx.fill();
            
            // 添加边框
            ctx.strokeStyle = 'rgba(255, 255, 255, 0.3)';
            ctx.lineWidth = 1;
            ctx.stroke();
            
            ctx.restore();
        }
        
        // 绘制土星环
        function drawSaturnRings(planet) {
            ctx.save();
            ctx.translate(planet.x, planet.y);
            
            ctx.strokeStyle = 'rgba(250, 213, 165, 0.6)';
            ctx.lineWidth = 2;
            
            // 内环
            ctx.beginPath();
            ctx.arc(0, 0, planet.radius + 3, 0, 2 * Math.PI);
            ctx.stroke();
            
            // 外环
            ctx.beginPath();
            ctx.arc(0, 0, planet.radius + 6, 0, 2 * Math.PI);
            ctx.stroke();
            
            ctx.restore();
        }
        
        // 更新信息显示
        function updateInfo() {
            document.getElementById('currentTime').innerHTML = `<strong>当前时间:</strong><br>${currentTime.toLocaleString('zh-CN')}`;
            
            let planetInfo = '<strong>天体信息:</strong><br>';
            Object.keys(celestialBodies).forEach(key => {
                const body = celestialBodies[key];
                if (key !== 'sun') {
                    planetInfo += `<span class="planet-name">${body.name}</span><br>`;
                    if (showMoons && body.moons) {
                        body.moons.forEach(moon => {
                            planetInfo += `<span class="moon-name">├ ${moon.name}</span><br>`;
                        });
                    }
                }
            });
            document.getElementById('planetInfo').innerHTML = planetInfo;
        }
        
        // 动画循环
        function animate() {
            const now = Date.now();
            const deltaTime = (now - lastTime) / 1000; // 秒
            lastTime = now;
            
            if (timeSpeed > 0) {
                currentTime = new Date(currentTime.getTime() + deltaTime * timeSpeed * 1000);
                document.getElementById('dateInput').value = formatDateForInput(currentTime);
                updatePlanetPositions();
            }
            
            draw();
            requestAnimationFrame(animate);
        }
        
        // 鼠标控制缩放
        canvas.addEventListener('wheel', (e) => {
            e.preventDefault();
            const zoomFactor = e.deltaY > 0 ? 0.9 : 1.1;
            zoom = Math.max(0.1, Math.min(3, zoom * zoomFactor));
            document.getElementById('zoomSlider').value = zoom;
        });
        
        // 启动模拟器
        init();
    </script>
</body>
</html>
        
编辑器加载中
预览
控制台