Setting up Vite - 3D web3 serie
Tags: web3, three, javascript, vite
Published: 2022-07-27 15:39:00

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](https://dev.to/uigla/chapter-2-3d-website-using-threejs-fiber-react-web3-and-vite-as-bundler-using-more-packages-4p02)
3 - [Cannon physics](https://dev.to/uigla/3d-web-cannon-physics-web3-serie-24jh)
4 - [Web3](https://dev.to/uigla/3d-web-react-web3-44e7)

**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

```node
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
```
> Check [vite docs](https://vitejs.dev/guide/#scaffolding-your-first-vite-project)

`npm i three`

> [Three.js](https://threejs.org/) 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](https://docs.pmnd.rs/react-three-fiber/getting-started/introduction). 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](https://threejs.org/docs/#manual/en/introduction/Creating-a-scene) any 3D object"_

**First render**

index.js
```javascript
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>
);

```
App.js

```javascript
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

```
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
```javascript
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;
```

Sphere.js
_Works as Box component, unique difference is inside mesh element_
```javascript

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;
```
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**_
{% embed https://codesandbox.io/embed/three-react-fx8ze7?fontsize=14&hidenavigation=1&theme=light&view=preview %}

Serie follows at [3D web - Three.js (fiber & drei) - web3 serie](https://dev.to/uigla/chapter-2-3d-website-using-threejs-fiber-react-web3-and-vite-as-bundler-using-more-packages-4p02) Check demo in the bottom!

I hope it has been helpful.