DEV Community

Uigla
Uigla

Posted on • Updated on

Setting up Vite - 3D web3 serie

Hey Reader,

This is the first post of 3D-web3 Series.
Where we can learn about creating a 3D space (including pshysics) in our web and connecting to the blockchain using web3 libraries.

1 - Vite config and basic three.js
2 - Three.js (fiber & drei) - web3 serie
3 - Cannon physics
4 - Web3

Vite is a modern, blazing-fast tool for scaffolding and bundling projects. It has quickly become popular due to near-instant code compilation and rapid hot module replacement.

Vite uses "Rollup.js" internally for bundling (is in charge of configuration) and esbuild as pre-bundle dependency (which is written in Go).

-- @Notice create-react-app uses "Webpack" internally for bundling --

It has been developed by "Evan You" who also created the "Vue.js" framework.

Set-up - open consol in your projects directory and run

npm create vite@latest my-three-react-web3-app --template react
// Follow consol instructions and select -> React -> React
// ("You're also able to use Vanilla, Vue, Svelte... and JS or TS")
cd my-three-react-web3-app
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

Check vite docs

npm i three

Three.js is an open source JavaScript library to create and display animated 3D computer graphics in a web browser using WebGL.

We'll use Threejs only to take some built-in objects (we'll use it more in next articles)

npm i @react-three/fiber

To simplify development process, we'll be working with @react-three/fiber. Which is a React renderer for threejs on the web and react-native.

The renderer is responsible for rendering React components to the DOM and native views. This means that we are able to create regular React components and let react-three-fiber handle converting those components into three.

"Fiber allows as to avoid threejs set up to render any 3D object"

First render

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')).render(
    <React.StrictMode>
        <App />
    </React.StrictMode>
);

Enter fullscreen mode Exit fullscreen mode

App.js

import { Canvas } from '@react-three/fiber'
import Box from './components/Box'
import './App.css'

function App() {
  return (
    <Canvas>
      <ambientLight />
      <pointLight position={[10, 10, 10]} />
      <Box position={[-1.2, 0, 0]} />
      <Box position={[1.2, 0, 0]} />
    </Canvas>
  )
}

export default App

Enter fullscreen mode Exit fullscreen mode

Following Box and Sphere components, will use Hooks to simplify code logic.

useRef to attach to "mesh" which is a built-in "DOM element" by fiber, which allows to manipulate the object inside.

useFrame calls you back every frame, which is good for running effects, updating controls, etc. You receive the state and a clock delta.

useState to change scale and color when objects is clicked.

Box.js

import React, { useRef, useState } from 'react'
import { useFrame } from '@react-three/fiber'

const Box = (props) => {
    // This reference will give us direct access to the mesh
    const mesh = useRef()
    // Set up state for the hovered and active state
    const [hovered, setHover] = useState(false)
    const [active, setActive] = useState(false)
    // Subscribe this component to the render-loop, rotate the mesh every frame
// Adding rotation grade per each frame
    useFrame((state, delta) => {
        mesh.current.rotation.x += 0.01
        mesh.current.rotation.y += 0.01
    })
    // Return view, these are regular three.js elements expressed in JSX
    return (
        <mesh
            {...props}
            ref={mesh}
            scale={active ? 1.5 : 1}
            onClick={(e) => {
                setActive(!active)
                setHover(!hovered)
            }}
        >
            <boxGeometry args={[1, 1, 1]} />
            <meshStandardMaterial color={hovered ? 'green' : 'blue'} />
        </mesh>
    )
}
export default Box;
Enter fullscreen mode Exit fullscreen mode

Sphere.js
Works as Box component, unique difference is inside mesh element


import React, { useRef, useState } from 'react'
import { useFrame } from '@react-three/fiber'

function Sphere(props) {
    // This reference gives us direct access to the THREE.Mesh object
    const ref = useRef();
    // Hold state for hovered and clicked events
    const [hovered, setHover] = useState(false);
    const [active, setActive] = useState(false);
    // Subscribe this component to the render-loop, rotate the mesh every frame
// Adding rotation grade per each frame
    useFrame((state, delta) => (ref.current.rotation.y += 0.01));
    // Return the view, these are regular Threejs elements expressed in JSX
    return (
        <mesh
            {...props}
            ref={ref}
            scale={active ? 4 : 1}
            onClick={(e) => {
                setActive(!active);
                setHover(!hovered);
            }}
        >
            <sphereBufferGeometry args={[0.7, 30, 30]} attach="geometry" />
            <meshBasicMaterial
                wireframe
                attach="material"
                color={hovered ? "yellow" : "pink"}
            />
        </mesh>
    );
}

export default Sphere;
Enter fullscreen mode Exit fullscreen mode

I am making a series developing this App, new post coming soon.

SandBox demo @Notice Code is not splited in components as in our Vite App

Click on 3D objects

Serie follows at 3D web - Three.js (fiber & drei) - web3 serie Check demo in the bottom!

I hope it has been helpful.

Top comments (0)