+1 (843) 212-6898+8801897661858
Whatsapp-colorCreated with Sketch.
sales@mediusware.comSchedule A Call
Logo
Company
Services
Hire Developers
Industries
Case StudySTART FREE TRIALicon

About

Who We Are

Our Team

Blogs

Women Empowerment

Career

CSR

Delivery Models

Engagement Model

Services

Software Development

Web Development

Mobile App Development

E-commerce Development

Software Development

Enterprise Solutions

UI/UX Design

API Integration

Technology

React.js

Vue.js

Angular js

Laravel

Android

Flutter

iOS

React Native

Hire Developers

Hire Mobile App Developers

Hire Front-end Developers

Hire Backend Developers

Hire E-commerce Developers

Hire Developers

Hire Android Developers

Hire iOS Developers

Hire Swift Developers

Hire Flutter Developers

Hire React Native Developers

Hire Django Developers

Hire Node.js Developers

Hire Laravel Developers

We shape the art of technology
Headquarter

Headquarter

1050 Johnnie Dodds Blvd Mount Pleasant South Carolina USA ,Zip- 29464

sales@mediusware.io

+1 843-212-7149

Bangladesh Office

Bangladesh Office

24/1, Taj Mahal Road, Shiya Masjid mor, Floor - 8th & 9th, Ring Road, 1207, Dhaka, Bangladesh

sales@mediusware.com

+8801897661858

© 2025 Mediusware. All Rights Reserved

Terms & ConditionsPrivacy Policy

Table of contents

  1. Introduction
  2. Prerequisites
  3. Basic Concepts of Three.js
  4. Creating a Simple 3D Scene with Three.js and vanilla js
  5. Integrating Three.js with React
  6. Building an Interactive 3D Component
Share This Blog !
Get the best of our content straight to your inbox!

Don’t worry, we don’t spam!

React + Three.js + React Three Fiber: Crafting Interactive 3D views in Web Applications

React + Three.js + React Three Fiber: Crafting Interactive 3D views in Web Applications image

Last Update: 16 Oct 2024

Introduction

Overview of Three.js and React

Three.js is a robust JavaScript library designed for creating and displaying 3D graphics in web browsers. It abstracts the complexities of WebGL, enabling developers to create 3D scenes with relative ease. With features like lighting, shadows, textures, and animations, Three.js opens the door to visually stunning applications, from simple 3D models to fully immersive environments.

React is a widely-used JavaScript library developed by Facebook for building user interfaces, particularly single-page applications. Its component-based architecture allows developers to create reusable UI elements, manage state efficiently, and build dynamic applications that respond quickly to user interactions. React’s declarative approach simplifies the development process, making it easier to maintain and scale applications.

 

Importance of Integrating Both for Modern Web Development

Integrating Three.js with React brings together the strengths of both libraries, creating a powerful toolkit for web developers. By combining React’s efficient UI management with the 3D capabilities of Three.js, developers can build applications that are not only visually captivating but also highly interactive and responsive.

This integration allows for:

 

  • Dynamic 3D Content: Easily update and manipulate 3D objects based on user interactions or state changes.
  • Component-Based Structure: Organize 3D elements as React components, making the code more maintainable and reusable.
  • Enhanced User Experiences: Create engaging and interactive applications, from educational tools to gaming experiences, that stand out in today’s digital landscape.

Prerequisites

Before diving into the integration of Three.js with React, it’s helpful to have a few foundational skills and knowledge areas. While you don’t need to be an expert, a basic understanding of the following will make the learning process smoother

Basic Understanding of JavaScript:

    • Since Three.js and React are both JavaScript libraries, a solid grasp of JavaScript fundamentals is essential. Familiarity with concepts like variables, functions, objects, and arrays will be crucial.

Familiarity with React:

A fundamental knowledge of React is important for integrating Three.js effectively. You should be comfortable with concepts such as:

      • Components: Understanding how to create and use functional components.
      • Props and State: Knowing how to pass data between components and manage local state.
      • Lifecycle Methods and Hooks: Familiarity with hooks like useEffect and useState will help you manage the rendering and updates of your 3D scenes.

Familiarity with 3D Concepts (Optional, but Helpful):

    • While not strictly necessary, having some basic knowledge of 3D graphics can enhance your understanding and make working with Three.js more intuitive. Key concepts include:
      • Scenes, Cameras, and Renderers: Understanding how these components work together to create a 3D environment.
      • Meshes and Materials: Knowing how 3D objects are constructed and textured.
      • Lighting and Shadows: Recognizing how different light types affect the appearance of objects in a scene.
    • Resources like online tutorials or introductory articles on 3D graphics can provide a helpful background.

Basic Concepts of Three.js

Three.js is a powerful JavaScript library that simplifies the process of creating 3D graphics in the web browser.

Key Components

  • Scene

    • The scene is the environment where all 3D objects are placed. It acts as a container for your objects, lights, and cameras.
    • You can think of it as a virtual stage where everything happens.
    • Creating the scene, we need three things: scene, camera and renderer, so that we can render the scene with camera.
      import * as THREE from 'three';
      
      const scene = new THREE.Scene();
      
      const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
      
      // Create renderer for scene
      const renderer = new THREE.WebGLRenderer();
      
      // set renderer size as window height and width
      renderer.setSize( window.innerWidth, window.innerHeight );
      
      // you can also append renderer to any html element
      document.body.appendChild( renderer.domElement );
  • Camera

    • The camera defines the viewpoint from which the scene is rendered. There are different types of cameras, but the most common are:
      • PerspectiveCamera: Mimics the human eye, with a field of view that decreases with distance.
      • OrthographicCamera: Renders objects without perspective distortion, useful for 2D or isometric views.
    • Creating perspective camera
      const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 );
  • Renderer

    • The renderer is responsible for displaying the scene from the perspective of the camera. Three.js primarily uses WebGL for rendering, which allows for hardware-accelerated graphics.
    • We create a renderer and attach it to an HTML element (usually a <canvas>).
  • Mesh

    • A mesh is a 3D object made up of geometry (the shape) and material (the appearance).
    • Geometries define the vertices and faces of the object, while materials determine how the object interacts with light (e.g., color, texture).
    • Creating a Mesh with plane geometry
      const geometry = new THREE.PlaneGeometry( 1, 1 );
      const material = new THREE.MeshBasicMaterial( {color: 0xffff00, side: THREE.DoubleSide} );
      const plane = new THREE.Mesh( geometry, material );
      scene.add( plane );

Brief Introduction to Geometries, Materials, and Lights

  • Geometries

    • Geometries represent the shapes of 3D objects. Common geometries include:
      • BoxGeometry: A rectangular box.
      • SphereGeometry: A sphere.
      • PlaneGeometry: A flat surface.
    • You can also create custom geometries by defining your own vertices and faces.
  • Materials

    • Materials define how a mesh appears visually. Key types include:
      • MeshBasicMaterial: A simple material that does not react to light; it’s good for basic coloring.
      • MeshLambertMaterial: A material that reflects light, providing a matte appearance.
      • MeshPhongMaterial: A shiny material that reacts to light and has specular highlights.
      • MeshStandardMaterial: A more advanced material that supports physically-based rendering.
  • Lights

    • Lighting is crucial for creating realistic scenes. Common light types include:
      • AmbientLight: Provides a uniform light that illuminates all objects equally.
      • DirectionalLight: Simulates sunlight; it has a direction and casts shadows.
      • PointLight: Emits light in all directions from a point; behaves like a light bulb.
      • SpotLight: Emits light in a cone shape, useful for focused lighting.

 

Creating a Simple 3D Scene with Three.js and vanilla js

Step 1: Creating project with vite:

npm create vite@latest vanilla_3d_web --template vanilla

Step 2: Navigate to the Project Directory:

cd vanilla_3d_web

Step 3: Install Dependencies:

npm install

Step 4: Start the Development Server:

npm run dev

Step 5: Edit i"/index.html":

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>3D web view with vanilla js + Three.js</title>
  </head>
  <body>
      <canvas id="main"></canvas> 
    <script type="module" src="/main.js"></script>
  </body>
</html>

Step 6: Reset canvas styles and position to window: "/styles.css"

* {
  margin: 0;
  padding: 0;
}

canvas {
  position: absolute;
  top: 0;
  left: 0;
}

Step 7: writting Three.js to render 3D view "/main.js":

import './style.css'
import * as THREE from 'three';

import { OrbitControls } from 'three/examples/jsm/Addons.js';

// main scene 
const scene = new THREE.Scene();

// main camera
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

// main renderer
const renderer = new THREE.WebGLRenderer({
  canvas: document.getElementById("main")
})

// set pixel ratio of renderer
renderer.setPixelRatio(window.devicePixelRatio);

// set renderer witdth and height
renderer.setSize( window.innerWidth, window.innerHeight );

// set camera position
camera.position.setZ(40);


// create opject
const geometry = new THREE.TorusGeometry(10, 3, 16, 100);

// the Standard Mesh Material react to light source
const material = new THREE.MeshStandardMaterial({ color: 0xFF6347 });
const torus = new THREE.Mesh(geometry, material);

// add torus to scene
scene.add(torus);

// add light source
const pointLight = new THREE.PointLight(0xffffff);

// set the position
pointLight.position.set(20,20,20);

// ambient light
const ambientLight = new THREE.AmbientLight(0xffffff);

// add point light to scene
scene.add(pointLight, ambientLight);


// light helper which help to locate where the light is
const lightHelper = new THREE.PointLightHelper(pointLight);
scene.add(lightHelper);

// add grid helper
// const gridHelper = new THREE.GridHelper(200, 50);
// scene.add(gridHelper);

// orbit controls that use to explore scene with mouse
const controls = new OrbitControls(camera, renderer.domElement);

// rendom star adding to scene
function addStar() {
  const geometry = new THREE.SphereGeometry(0.25, 24, 24);
  const material = new THREE.MeshStandardMaterial( {color: 0xfffff});
  const star = new THREE.Mesh( geometry, material );

  // give the star a random postion
  const [x, y, z] = Array(3).fill().map(() => THREE.MathUtils.randFloatSpread(100));

  star.position.set(x, y, z);

  scene.add(star);
}
// add 200 random start
Array(200).fill().forEach(addStar)

// rerender like game loop function
function animate() {
  requestAnimationFrame( animate );

  torus.rotation.x += 0.01;
  torus.rotation.y += 0.005;
  torus.rotation.z += 0.01;

  controls.update()
  renderer.render(scene, camera);

}

animate()

Result:

demo

Integrating Three.js with React

Setting Up Development Environment

 Creating a New React App

  • Option A: Using Create React App
    •   Install Create React App (if you haven't already): Open your terminal and run: 
      npx create-react-app 3d_web
    • Navigate to Your Project Directory:
      cd 3d_web
    • Start the Development Server:
      npm start
  • Option B: Using Vite
    • Install Vite (if you haven't already): Open your terminal and run:

      npm create vite@latest 3d_web --template react
      
    • Navigate to Your Project Directory:

      cd 3d_web
      
    • Install Dependencies:

      npm install
    •  Start the Development Server: 

      npm run dev

Installing Three.js

  • Install Three.js and React Three Fiber: In your project directory, run the following command:
    npm install three @react-three/fiber
  • Additional Dependencies : GLTFLoader for importing 3D models:
    npm install @react-three/drei

Creating 3D scene: "/src/App.tsx"

import { OrbitControls, useTexture } from "@react-three/drei"
import { Canvas } from "@react-three/fiber"


const App = () => {  

  return (
    <div style={{background: "grey", height: "100vh", width: "100vw"}}>
      <Canvas />
    </div>
  )
}

Here, we are using "Canvas" from "@react-three/fiber" that automatically setup  Scenes, Cameras, and Renderers for us

Adding light and object to the scene: "/src/App.tsx"

import { OrbitControls, } from "@react-three/drei"
import { Canvas } from "@react-three/fiber"

const App = () => {  

  return (
    <div style={{background: "grey", height: "100vh", width: "100vw"}}>
      <Canvas>
            {/* ambientLight for illuminates all objects equally. */}
        <ambientLight intensity={0.5}/>
        {/* orbitcontrols to move around with mouse */}
        <OrbitControls />
       <mesh  position={[0, 0, 0]} rotation={[Math.PI * -0.5, 0, 0]}>
            <planeGeometry args={[500, 500]}  />
            <meshStandardMaterial color={"#18d6b6"} />
       </mesh>
        {/* orbitcontrols to move around with mouse */}
        <OrbitControls />
      </Canvas>
    </div>
  )
}

Building an Interactive 3D Component

Here we are going to build simple click color change game:
Creating Ground for a scene:

import {useTexture} from "@react-three/drei"

const BreakGround = () => {
  const textureMap = useTexture("./textures/ground/red_brick_diff.png");
  return  <mesh  position={[0, 0, 0]} rotation-x={Math.PI * -0.5}>
        <planeGeometry args={[500, 500]}  />
        <meshStandardMaterial map={textureMap} />
    </mesh>
}

Creating InteractiveBall component that can be interact with click event:

import { Color, Vector3 } from "three";

const InteractiveBall = ({onClick, color, position}: {onClick: () => void, color: Color, position: Vector3}) => {
  return <mesh
   onClick={() => {
    onClick()
  }}
  position={position}
  >
    <sphereGeometry args={[10 ,10, 10]} />
    <meshStandardMaterial color={color} />
  </mesh>
}

Creating helper function that can helper function to interact with ball:

// generate random reward 1000 to 100000
const getRandomNumber = () => {
  return Math.abs(Math.floor(Math.random() * (1000 - 100000 + 1)) + 1000);
}

// generate random color for ball
const getRandomColor = () => {
  const randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
  return new THREE.Color(randomColor);;
}

Creating simple state screen:

<div style={{
        position: "absolute",
        top: "0px",
        left: "0px",
        width: "100vw",
        height: "100vh",
        display: "flex",
        alignItems: "center",
        justifyContent: "center"
      }}>

        <div style={{
          width: "300px",
          height: "300px",
          backgroundColor: "rgb(249 215 220 / 0.5)",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          flexDirection: "column",
          rowGap: "10px"
        }} >

          <h1 style={{
            fontSize: "30px",
            color: "#effa16",
            fontWeight: "900"
          }}>Congrats!</h1>
          <p style={{
            fontSize: "50px",
            color: "#84fa16",
            fontWeight: "900",
            textAlign: "center"
          }}>You won <span style={{
            color: "#f76fee"
          }}>${getRandomNumber()}</span> </p>
          <button style={{
            padding: "8px 20px",
            backgroundColor: "#fa78e4",
            color: "#fff",
            fontWeight: "700",
            borderRadius: "0.75rem" 
          }} 
          onClick={() => {
            setGameState(false)
            setClickCounter(0);
          }}
          >Play again</button>
        </div>
      </div>

 

Putting it all togather:

import { OrbitControls, useTexture } from "@react-three/drei"
import { Canvas } from "@react-three/fiber"
import { useEffect, useState } from "react";
import { Color, Vector3 } from "three";
import * as THREE from "three";


const BreakGround = () => {
  const textureMap = useTexture("./textures/ground/red_brick_diff.png");
  return  <mesh  position={[0, 0, 0]} rotation-x={Math.PI * -0.5}>
        <planeGeometry args={[500, 500]}  />
        <meshStandardMaterial map={textureMap} />
    </mesh>
}

const InteractiveBall = ({onClick, color, position}: {onClick: () => void, color: Color, position: Vector3}) => {
  return <mesh
   onClick={() => {
    onClick()
  }}
  position={position}
  >
    <sphereGeometry args={[10 ,10, 10]} />
    <meshStandardMaterial color={color} />
  </mesh>
}

const getRandomNumber = () => {
  return Math.abs(Math.floor(Math.random() * (1000 - 100000 + 1)) + 1000);
}

const getRandomColor = () => {
  const randomColor = '#' + Math.floor(Math.random() * 16777215).toString(16);
  return new THREE.Color(randomColor);;
}

const App = () => {  
  const [ball_1_Color, setBall_1_Color] = useState<Color>(getRandomColor);
  const [ball_2_color, setBall_2_color] = useState<Color>(getRandomColor);

  const [gameState, setGameState] = useState<boolean>(false);
  const [clickCounter, setClickCounter] = useState<number>(0);

  useEffect(() => {
    if (ball_1_Color.equals(ball_2_color)) {
      setGameState(true);
    }
    if (clickCounter === 10) {
      setBall_1_Color(ball_1_Color);
      setBall_2_color(ball_2_color);
      setGameState(true);
    }

  }, [ball_1_Color, ball_2_color, clickCounter])

  return (
    <div  style={{
      position: "relative"
    }}>
      <div style={{background: "grey", height: "100vh", width: "100vw", position: "fixed", left: "0px", top: "0px"}}>
        <Canvas camera={{fov: 75, position: [10, 35, 50]}}>
          <ambientLight intensity={0.5}/>
          <spotLight castShadow position={[0, 2, 0]} />
          <directionalLight  position={[0, 10, 10]} />
          {/* orbitcontrols to move around with mouse */}
          <OrbitControls />
          <BreakGround />
          <InteractiveBall onClick={() => {
            setClickCounter((state) => state += 1)
            setBall_1_Color(getRandomColor())
          }} color={ball_1_Color} position={new Vector3(0, 10, 0)} />
          <InteractiveBall onClick={() => {
            setBall_2_color(getRandomColor())
            setClickCounter((state) => state += 1)
          }} 
          color={ball_2_color}
          position={new Vector3(20, 10, 0)} 
          />
        </Canvas>
      </div>
      {/* win screen */}
      {
        gameState &&
      <div style={{
        position: "absolute",
        top: "0px",
        left: "0px",
        width: "100vw",
        height: "100vh",
        display: "flex",
        alignItems: "center",
        justifyContent: "center"
      }}>

        <div style={{
          width: "300px",
          height: "300px",
          backgroundColor: "rgb(249 215 220 / 0.5)",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
          flexDirection: "column",
          rowGap: "10px"
        }} >

          <h1 style={{
            fontSize: "30px",
            color: "#effa16",
            fontWeight: "900"
          }}>Congrats!</h1>
          <p style={{
            fontSize: "50px",
            color: "#84fa16",
            fontWeight: "900",
            textAlign: "center"
          }}>You won <span style={{
            color: "#f76fee"
          }}>${getRandomNumber()}</span> </p>
          <button style={{
            padding: "8px 20px",
            backgroundColor: "#fa78e4",
            color: "#fff",
            fontWeight: "700",
            borderRadius: "0.75rem" 
          }} 
          onClick={() => {
            setGameState(false)
            setClickCounter(0);
          }}
          >Play again</button>
        </div>
      </div>
      }
    </div>
  )
}

Trendingblogs
The Software Development Life Cycle (SDLC): A Complete Guide for Software Success image

The Software Development Life Cycle (SDLC): A Complete Guide for Software Success

Zustand: A Lightweight State Management Library for React image

Zustand: A Lightweight State Management Library for React

From Bugs to Beauty: Integrating UI/UX Testing into Software Quality Assurance image

From Bugs to Beauty: Integrating UI/UX Testing into Software Quality Assurance

Why is a Gaming PC the Ultimate Tool for Both Gaming and Professional Development? image

Why is a Gaming PC the Ultimate Tool for Both Gaming and Professional Development?

Why React Native is the Best Choice for Cross-Platform Development image

Why React Native is the Best Choice for Cross-Platform Development

Let's Deep Dive Into Threads with Rust image

Let's Deep Dive Into Threads with Rust

Get the best of our content straight to your inbox!

Don’t worry, we don’t spam!

Frequently Asked Questions