00:00/00:00
3:22
00:03:22

Shortcuts ⌨️

Image for: Shortcuts ⌨️
  • SPACE to play / pause
  • ARROW RIGHT or L to go forward
  • ARROW LEFT or J to go backward
  • ARROW UP to increase volume
  • ARROW DOWN to decrease volume
  • F to toggle fullscreen
  • M to toggle mute
  • 0 to 9 to go to the corresponding part of the video
  • SHIFT + , to decrease playback speed
  • SHIFT + . or ; to increase playback speed

⚠️ Update

Image for: ⚠️ Update

If the PMNDRs market is down, keep watching the video.

At the end of this section, you’ll have to use a link pointing to a model. Instead use the following one:

const computer = useGLTF('https://threejs-journey.com/resources/models/macbook_model.gltf')

⚠️ Update

Image for: ⚠️ Update

In the latest versions of @react-three/drei, we need to set the touch-action on the <div> right above the <canvas> that R3F creates.

By default, this <div> has no class, but we can set one using className on the <Canvas>:

<Canvas
    className="r3f"
    // ...
>

Next, in /src/style.css, we can select it and change its touch-action to none:

.r3f
{
    touch-action: none;
}

⚠️ Update

Image for: ⚠️ Update

In the latest versions of @react-three/drei, PresentationControls doesn’t rely on Spring anymore making the following part useless.

The configuration has been replaced by the damping prop where a higher damping will make the animation feel slow while a smaller damping will make the animation feel fast (default value is 0.25).

Let’s try a damping to 0.1:

<PresentationControls
    damping={ 0.1 }
>

⚠️ Update

Image for: ⚠️ Update

In the latest versions of @react-three/drei, the snap prop doesn’t support specific configuration.

Just leave the snap prop without any value:

<PresentationControls
    // ...
    snap
>

Unlock content 🔓

Image for: Unlock content 🔓

To get access to 93 hours of video, a members-only Discord server, subtitles, lesson resources, future updates and much more join us for only $95!

Want to learn more? 👋

Image for: Want to learn more? 👋
93%

That's the end of the free part 😔

To get access to 93 hours of video, a members-only Discord server and future updates, join us for only $95!

Next lesson
64.

Fun and Simple Portfolio

Image for: Fun and Simple Portfolio

Difficulty Medium

Introduction 00:00

Image for: Introduction 00:00

If you are here and are trying to level up your skills in WebGL with Three.js, you probably know how important it is to have a good portfolio.

In web development and more generally in the digital industry, what matters most is your experience. Companies and job recruiters will certainly judge you on that first criterion before giving you a chance.

You need a way to display your projects, which is why it’s important to have a portfolio.

And that portfolio is actually one of your projects (if not the most important one). It should be your testimony and demonstrate what you can do and why companies should hire you for.

But creating a cool portfolio is a long and difficult process. You are your own client and you are probably the most demanding client you could have.

But let’s say that you already have a simpler HTML/CSS portfolio that displays your projects and some information (which is already good).

In this lesson, we are going to capitalise on that HTML/CSS portfolio and make it look more exciting and more creative. We are going to create a nice 3D scene with a laptop model and put that HTML/CSS portfolio inside the screen of the laptop.

This concept is inspired by Paul Henschel (0xca0a) experiment that you can find here https://twitter.com/0xca0a/status/1398633764931178498

Note that, through the lesson, we are going to set values that fit nicely and make the experience pleasant. To get those values, I had to tweak them a lot and I use Leva to do so.

If you are creating your own experiences, don’t feel frustrated not finding the perfect value on the first try. It’s a process of trial and error. And don’t forget to add a debug UI like Leva to help you.

Setup 04:07

Image for: Setup 04:07

In the starter, we have a simple cube in the center.

The @react-three/drei dependency is already installed within the project and we are using the OrbitControls helper to be able to move the camera around. We are going to replace it later, but let’s keep it for now.

We didn’t use Perf because we shouldn’t have any performance concerns, but feel free to add it if you want.

We didn’t use Leva because we are going to set very specific values, but you should add it if you want to tweak the experience.

Background 04:36

Image for: Background 04:36

First of all, let’s change the background to a darker color in order to create a warmer mood and highlight the importance of the content.

In Experience.jsx, add a <color> with the attach attribute to "background":

export default function Experience()
{
    return <>

        <color args={ [ '#241a1a' ] } attach="background" />

        {/* ... */}

    </>
}

Laptop 05:55

Image for: Laptop 05:55

We are going to display the portfolio on a laptop.

We could create the model ourselves, but instead, let’s use a free model.

Find a good model

There are many free models online, but the PMNDRS team created a place where we can find a bunch of models ready to be used in Three.js and more specifically in R3F: https://market.pmnd.rs

If you’re looking for a "Macbook" model, you should find this one https://market.pmnd.rs/model/macbook.

Want to learn more?

That's the end of the free part 😔

To get access to 93 hours of video, a members-only Discord server and future updates, join us for only $95!

How to use it 🤔

Image for: How to use it 🤔
  • Download the Starter pack or Final project
  • Unzip it
  • Open your terminal and go to the unzip folder
  • Run npm install to install dependencies
    (if your terminal warns you about vulnerabilities, ignore it)
  • Run npm run dev to launch the local server
    (project should open on your default browser automatically)
  • Start coding
  • The JS is located in src/script.js
  • The HTML is located in src/index.html
  • The CSS is located in src/style.css

If you get stuck and need help, join the members-only Discord server:

Discord