How to Implement a 3D Solar System in React with Three.js

Vishal Yadav - Sep 21 - - Dev Community

Creating a 3D solar system in React can be a fascinating way to explore the combination of web development and 3D graphics. By using the powerful Three.js library with React, you can create visually stunning and interactive 3D environments directly in the browser.

In this guide, we’ll walk through how to implement a 3D solar system using React and Three.js, explaining each part of the process in detail. By the end, you'll have a fully interactive solar system simulation running in your browser.


Table of Contents:

  1. Setting Up React with Three.js
  2. Creating the Scene and Camera
  3. Adding the Sun and Planets
  4. Animating the Solar System
  5. Handling Resizing and Cleanup
  6. Running the Solar System in Your App

1. Setting Up React with Three.js

First, make sure you have a React project setup. If you haven’t already, you can create a new React project using Vite:

npm create vite@latest my-solar-system
cd my-solar-system
npm install
Enter fullscreen mode Exit fullscreen mode

Next, you’ll need to install Three.js as a dependency to render 3D objects:

npm install three
Enter fullscreen mode Exit fullscreen mode

2. Creating the Scene and Camera

Start by creating a component called SolarSystem.js. This component will contain the scene, camera, and the rendering logic.

import { useRef, useEffect } from "react";
import * as THREE from "three";

const SolarSystem = () => {
  const mountRef = useRef(null);

  useEffect(() => {
    // Setup the scene, camera, and renderer
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(
      60,
      window.innerWidth / window.innerHeight,
      0.1,
      1000
    );
    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });

    // Set renderer properties
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(window.devicePixelRatio);
    mountRef.current.appendChild(renderer.domElement);

    // Add ambient and directional light
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
    scene.add(ambientLight);

    const sunLight = new THREE.PointLight(0xffffff, 2, 300);
    sunLight.position.set(0, 0, 0);
    scene.add(sunLight);

    // Camera initial position
    camera.position.set(0, 50, 80);
    camera.lookAt(scene.position);

    renderer.render(scene, camera);
  }, []);

  return <div ref={mountRef} style={{ width: "100%", height: "100vh" }} />;
};

export default SolarSystem;
Enter fullscreen mode Exit fullscreen mode

In the above code:

  • We create a scene to hold all objects.
  • The camera is positioned and aimed at the scene.
  • A renderer is used to render the scene to the browser.
  • Basic lights are added to illuminate the objects.

3. Adding the Sun and Planets

Next, we’ll add the sun and planets to our scene. Each planet will be represented by a 3D sphere using the SphereGeometry from Three.js.

const textureLoader = new THREE.TextureLoader();

// Sun
const sunTexture = textureLoader.load("path-to-sun-texture");
const sunGeometry = new THREE.SphereGeometry(10, 78, 78);
const sunMaterial = new THREE.MeshPhongMaterial({
  map: sunTexture,
  emissive: 0xffff00,
  emissiveIntensity: 0.5,
});
const sun = new THREE.Mesh(sunGeometry, sunMaterial);
scene.add(sun);

// Planets data
const planets = [
  {
    name: "Earth",
    radius: 4,
    distance: 25,
    speed: 0.4,
    textureUrl: "path-to-earth-texture",
  },
  // Add other planets here
];

planets.forEach((planet) => {
  const texture = textureLoader.load(planet.textureUrl);
  const geometry = new THREE.SphereGeometry(planet.radius, 32, 32);
  const material = new THREE.MeshPhongMaterial({ map: texture });
  const planetMesh = new THREE.Mesh(geometry, material);
  planetMesh.position.x = planet.distance;
  scene.add(planetMesh);
});
Enter fullscreen mode Exit fullscreen mode

We load textures for the sun and planets, define their properties such as radius and distance, and add them to the scene.


4. Animating the Solar System

To make the solar system interactive, we need to rotate the sun and move the planets around it. This can be done using the requestAnimationFrame function.

const animate = () => {
  requestAnimationFrame(animate);

  // Rotate sun
  sun.rotation.y += 0.001;

  // Rotate and revolve planets
  planets.forEach((planet, index) => {
    const planetMesh = planetMeshes[index];
    planetMesh.position.x = Math.cos(Date.now() * planet.speed * 0.001) * planet.distance;
    planetMesh.position.z = Math.sin(Date.now() * planet.speed * 0.001) * planet.distance;
    planetMesh.rotation.y += 0.005 / planet.radius;
  });

  renderer.render(scene, camera);
};

animate();
Enter fullscreen mode Exit fullscreen mode

Here, each planet is rotated on its axis and revolved around the sun using simple trigonometry (Math.cos and Math.sin).


5. Handling Resizing and Cleanup

It’s important to handle resizing when the browser window size changes. We can do this by adding an event listener and updating the camera’s aspect ratio and the renderer size.

const handleResize = () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
};

window.addEventListener("resize", handleResize);

return () => {
  window.removeEventListener("resize", handleResize);
  mountRef.current.removeChild(renderer.domElement);
};
Enter fullscreen mode Exit fullscreen mode

This ensures that the solar system scales properly across different screen sizes.


6. Running the Solar System in Your App

Now that the core logic is implemented, you can integrate the SolarSystem component into your React app by importing it into App.js:

import SolarSystem from "./components/SolarSystem";
import "./App.css";

function App() {
  return (
    <div className="min-h-screen bg-gradient-to-b from-blue-900 to-black text-white flex flex-col justify-center items-center">
      <h1 className="text-4xl font-bold">Welcome to the Solar System</h1>
      <SolarSystem />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Conclusion

By following this guide, you’ve successfully created a 3D solar system in React using Three.js. You can further enhance this by adding more planets, moons, or even user interactivity to zoom in on planets or click to get more information.

Feel free to expand on this project and make it your own solar system simulation!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .