效果演示

源码使用说明

主要源码

export default class SolarSystem {
    constructor() {
        this.initProperties();
        this.createScene();
        this.createCamera();
        this.createRenderer();
        this.createSun();
        this.createPlanet();
        this.createLights();

        this.animate();
    }

    initProperties() {
        this._started = false;
    }

    createScene() {
        this._scene = new THREE.Scene();
    }

    createCamera() {
        this._camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
        this._camera.position.set(0, 20, 50);
        this._camera.lookAt(0, 0, 0)
    }

    createRenderer() {
        this._renderer = new THREE.WebGLRenderer();
        this._renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(this._renderer.domElement);
    }

    createSun() {
        const sunGeometry = new THREE.SphereGeometry(5, 32, 32);
        const sunMaterial = new THREE.MeshPhongMaterial({
            color: 0xffff00,
            emissive: 0xffff00, // Makes the material emit light
        });
        const sun = new THREE.Mesh(sunGeometry, sunMaterial);
        this.scene.add(sun);
        this._sun = sun;
    }

    createPlanet() {
        this._planets = [];
        const distances = this._distances = [10, 15, 20, 25]; // Distances from the sun
        const colors = [0xff6600, 0x3333ff, 0x66ff00, 0xffa5ff]; // Colors for the planets
        for (let i = 0; i < distances.length; i++) {
            const planetGeometry = new THREE.SphereGeometry(1, 32, 32);
            const planetMaterial = new THREE.MeshPhongMaterial({
                color: colors[i],
                emissive: colors[i], // Makes the material emit light
            });
            const planet = new THREE.Mesh(planetGeometry, planetMaterial);
            planet.position.x = distances[i];
            this._planets.push(planet);
            this.scene.add(planet);
        }
    }

    createLights() {
        const ambientLight = new THREE.AmbientLight(0x404040);
        this.scene.add(ambientLight);

        const pointLight = new THREE.PointLight(0xffffff, 1);
        pointLight.position.set(0, 0, 0);
        this.scene.add(pointLight);
    }

    animate = () => {
        requestAnimationFrame(this.animate);
        this.sun.rotation.y += 0.01;

        for (let i = 0; i < this.planets.length; i++) {
            // Update planet position along its orbit
            const planet = this.planets[i];
            const distance = this.distances[i];
            const speed = 0.01 * (i + 100); // Adjust speed for different planets
            const angle = speed * Date.now() * 0.001; // Time-dependent angle
            planet.position.x = distance * Math.cos(angle);
            planet.position.z = distance * Math.sin(angle);
        }

        this.renderer.render(this.scene, this.camera);
    }

    get planets() {
        return this._planets;
    }

    get scene() {
        return this._scene;
    }

    get camera() {
        return this._camera;
    }

    get sun() {
        return this._sun;
    }

    get distances() {
        return this._distances;
    }

    get renderer() {
        return this._renderer;
    }

    drive() {
        if (this._started) {
            return;
        }
        this._started = true;
        this.animate();
    }
}