React Portfolio
Built using React.js + Three.js
This is a portfolio I built from scratch meant to showcase skills, projects, work experience and my tech stack/ capabilities.
Code Snippets
The code snippet is defining a React functional component called BallCanvas
, which is responsible for rendering a 3D sphere with a texture image mapped onto it. The component is using the Canvas
component from the @react-three/fiber
library to create a WebGL canvas.
The frameloop
property of the Canvas
component is set to "demand"
, which means the canvas will only update when needed, resulting in better performance. The dpr
property is set to [1, 2]
, which defines the device pixel ratio, ensuring that the canvas looks sharp on high-resolution screens. The gl
property is set to { preserveDrawingBuffer: true }
, which enables the canvas to be saved as an image.
The component is using the Suspense
component from React to provide a fallback component while the 3D model and texture are being loaded. Inside the Suspense
component, the OrbitControls
component from the @react-three/drei
library is used to allow for rotating the 3D sphere. Finally, the Ball
component is rendered with the imgUrl
prop set to the icon
value, which is the URL of the texture image.
The Preload
component from @react-three/drei
is used to preload all assets, which can improve performance by reducing load times.
// Define a BallCanvas component that renders a Canvas from @react-three/fiber
const BallCanvas = ({ icon }) => {
return (
<Canvas
frameloop="demand"
dpr={[1, 2]}
gl={{ preserveDrawingBuffer: true }}
>
<Suspense fallback={<CanvasLoader />}>
{/* Add OrbitControls to allow for rotating the Ball */}
<OrbitControls enableZoom={false} />
{/* Render the Ball component, passing the icon prop as the texture URL */}
<Ball imgUrl={icon} />
</Suspense>
{/* Use Preload from drei to preload all assets */}
<Preload all />
</Canvas>
);
};
Then
const Tech = () => {
// Returning a flex container with each technology rendered as a BallCanvas component
return (
<div className="flex flex-row flex-wrap justify-center gap-10">
{technologies.map((technology) => (
<div className="w-28 h-28" key={technology.name}>
<BallCanvas icon={technology.icon} />
</div>
))}
</div>
);
};
Earth
The EarthCanvas
component renders a 3D model of Earth using Three.js and the useGLTF
hook from @react-three/drei
. The Canvas
element provides the Three.js rendering context and camera, and the OrbitControls
component enables interactive camera controls. The Earth
component loads the 3D model using the useGLTF
hook and renders it using the primitive
component.
const Earth = () => {
const earth = useGLTF('./planet/scene.gltf');
return (
<primitive
object={earth.scene}
scale={2.5}
position-y={0}
position-x={0}/>
)
}
const EarthCanvas = () => {
return (
<Canvas
shadows
frameloop='demand'
gl={{ preserveDrawingBuffer: true }}
camera={{
fov: 45,
near: 0.1,
far: 200,
position: [-4, 3, 6],
}}
>
<Suspense fallback={<CanvasLoader />}>
<OrbitControls
autoRotate
enableZoom={false}
maxPolarAngle={Math.PI / 2}
minPolarAngle={Math.PI / 2} />
<Earth />
</Suspense>
</Canvas>
)
}
Tech Stack
- React
- TailWindCSS
- Custom Domain
- Accessability
- Three.js
- Email.js
Sources
This project uses the following libraries and tools: