├── README.md
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
├── models
│ └── robot
│ │ ├── phantoms-transformed.glb
│ │ └── phantoms.glb
└── robots.txt
├── r3f-thumb.jpg
└── src
├── App.js
├── components
└── Robot.jsx
├── index.css
└── index.js
/README.md:
--------------------------------------------------------------------------------
1 | [(React Three Fiber ScrollControls with Gsap tutorial)](https://www.youtube.com/watch?v=52sTNIJs78A)
2 |
3 | # React Three Fiber/Three.js Tutorial for Beginners | Awwwards Style Website | Gsap, ScrollControls
4 |
5 | This is repositry contains the files that we created in my youtube tutorial here: https://www.youtube.com/watch?v=52sTNIJs78A
6 |
7 | ## Getting Started with this project
8 | - Download the repository,
9 | - Unzip it,
10 | - Rename the folder to be what you want your project to be called
11 | - Open the folder in your VS Code
12 | - Open a new integrated terminal within the folder
13 | - Run 'npm i' to install the node modules
14 | - Run npm start once the modules have installed
15 |
16 | ## Notes
17 | This is a basic project to get you up and running. Here are some suggestions on how you can improve:
18 | - Add custom fonts
19 | - Make responsive
20 | - Add better shadows (play around with lighting and element positions, what can cast/receive shadows etc...)
21 | - Make the canvas background change colour on scroll
22 | - Make multi page using Routers (play with animating things in and out)
23 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "our-project",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@react-three/drei": "^9.52.3",
7 | "@react-three/fiber": "^8.10.0",
8 | "@testing-library/jest-dom": "^5.16.5",
9 | "@testing-library/react": "^13.4.0",
10 | "@testing-library/user-event": "^13.5.0",
11 | "baffle": "^0.3.6",
12 | "gsap": "^3.11.4",
13 | "react": "^18.2.0",
14 | "react-dom": "^18.2.0",
15 | "react-scripts": "5.0.1",
16 | "three": "^0.148.0",
17 | "web-vitals": "^2.1.4"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": [
27 | "react-app",
28 | "react-app/jest"
29 | ]
30 | },
31 | "browserslist": {
32 | "production": [
33 | ">0.2%",
34 | "not dead",
35 | "not op_mini all"
36 | ],
37 | "development": [
38 | "last 1 chrome version",
39 | "last 1 firefox version",
40 | "last 1 safari version"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lilsugsy/R3F-ScrollControls-Tutorial-With-Gsap/bf176307f4e039134c9236cc011e635b708c233c/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 | You need to enable JavaScript to run this app.
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lilsugsy/R3F-ScrollControls-Tutorial-With-Gsap/bf176307f4e039134c9236cc011e635b708c233c/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lilsugsy/R3F-ScrollControls-Tutorial-With-Gsap/bf176307f4e039134c9236cc011e635b708c233c/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/models/robot/phantoms-transformed.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lilsugsy/R3F-ScrollControls-Tutorial-With-Gsap/bf176307f4e039134c9236cc011e635b708c233c/public/models/robot/phantoms-transformed.glb
--------------------------------------------------------------------------------
/public/models/robot/phantoms.glb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lilsugsy/R3F-ScrollControls-Tutorial-With-Gsap/bf176307f4e039134c9236cc011e635b708c233c/public/models/robot/phantoms.glb
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/r3f-thumb.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lilsugsy/R3F-ScrollControls-Tutorial-With-Gsap/bf176307f4e039134c9236cc011e635b708c233c/r3f-thumb.jpg
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import {useEffect} from 'react'
2 | import {RoundedBox, ScrollControls, Scroll, Environment,Sparkles,Backdrop,Float, Ring} from '@react-three/drei'
3 | import { Robot } from './components/Robot';
4 | import baffle from 'baffle'
5 |
6 |
7 | function App() {
8 |
9 | useEffect(()=> {
10 | const target = baffle('.title')
11 | target.set({
12 | characters: '░P░h░a░n░t░o░m░',
13 | speed: 100
14 | })
15 | target.start()
16 | target.reveal(1000,1000)
17 | })
18 |
19 | return (
20 | <>
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
39 |
40 |
41 |
42 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | PHANTOM
58 |
59 |
60 |
Be a Man of the Future.
61 |
Featuring a sleek, metallic design inspired by advanced technology, this aftershave bottle is as stylish as it is functional. But it's not just a pretty face - inside, you'll find a nourishing and protective aftershave formula that will leave your skin feeling refreshed and hydrated.
62 |
Read more
63 |
64 |
65 |
66 |
67 |
Tech-Savvy Side
68 |
Featuring a sleek, metallic design inspired by advanced technology, this aftershave bottle is as stylish as it is functional. But it's not just a pretty face - inside, you'll find a nourishing and protective aftershave formula that will leave your skin feeling refreshed and hydrated.
69 |
Read more
70 |
71 |
72 |
73 | Cutting-Edge of Grooming
74 |
75 | Buy now
76 |
77 |
78 | >
79 | );
80 | }
81 |
82 | export default App;
83 |
--------------------------------------------------------------------------------
/src/components/Robot.jsx:
--------------------------------------------------------------------------------
1 | /*
2 | Auto-generated by: https://github.com/pmndrs/gltfjsx
3 | Command: npx gltfjsx@6.1.3 phantoms.glb --transform
4 | */
5 |
6 | import React, { useRef,useLayoutEffect } from 'react'
7 | import { useGLTF,useScroll } from '@react-three/drei'
8 | import {useFrame} from '@react-three/fiber'
9 | import gsap from 'gsap'
10 |
11 | export function Robot(props) {
12 | const { nodes, materials } = useGLTF('./models/robot/phantoms-transformed.glb')
13 | const robot = useRef()
14 | const scroll = useScroll()
15 | const tl = useRef()
16 |
17 | useFrame((state, delta)=>{
18 | tl.current.seek(scroll.offset * tl.current.duration())
19 | })
20 |
21 | useLayoutEffect(()=> {
22 | tl.current = gsap.timeline({defaults: {duration: 2, ease: 'power1.inOut'}})
23 |
24 | tl.current
25 | .to(robot.current.rotation, {y: -1}, 2)
26 | .to(robot.current.position, {x: 1}, 2)
27 |
28 | .to(robot.current.rotation, {y: 1}, 6)
29 | .to(robot.current.position, {x: -1}, 6)
30 |
31 | .to(robot.current.rotation, {y: 0}, 11)
32 | .to(robot.current.rotation, {x: 1}, 11)
33 | .to(robot.current.position, {x: 0}, 11)
34 |
35 | .to(robot.current.rotation, {y: 0}, 13)
36 | .to(robot.current.rotation, {x: -1}, 13)
37 | .to(robot.current.position, {x: 0}, 13)
38 |
39 | .to(robot.current.rotation, {y: 0}, 16)
40 | .to(robot.current.rotation, {x: 0}, 16)
41 | .to(robot.current.position, {x: 0}, 16)
42 |
43 | .to(robot.current.rotation, {y: 0}, 20)
44 | .to(robot.current.rotation, {x: 0}, 20)
45 | .to(robot.current.position, {x: 0}, 20)
46 |
47 | },[])
48 |
49 | return (
50 |
51 |
52 |
53 |
62 |
63 |
64 |
75 |
76 |
77 |
78 | )
79 | }
80 |
81 | useGLTF.preload('./models/robot/phantoms-transformed.glb')
82 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body,
3 | #root
4 | {
5 | position: fixed;
6 | top: 0;
7 | left: 0;
8 | width: 100%;
9 | height: 100%;
10 | overflow: hidden;
11 | }
12 |
13 | body {
14 | margin: 0;
15 | font-family: "brandon-grotesque",source-code-pro, Menlo, Monaco, Consolas, 'Courier New';
16 | -webkit-font-smoothing: antialiased;
17 | -moz-osx-font-smoothing: grayscale;
18 | color: #cdcbca;
19 | }
20 |
21 | h1,h2,h3,h4,h5 {
22 | text-transform: uppercase;
23 | letter-spacing: 1.03px;
24 | line-height: 1.2em;
25 | }
26 |
27 | h1 {
28 | background: -webkit-linear-gradient(0deg,#cdcbca, aliceblue,#cdcbca,#2a3a3f);
29 | background-size: auto;
30 | background-clip: border-box;
31 | -webkit-background-clip: text;
32 | -webkit-text-fill-color: transparent;
33 | background-size: 100% 100% !important;
34 | }
35 |
36 | h2 {
37 | background: -webkit-linear-gradient(0deg,#cdcbca, aliceblue,#cdcbca,#2a3a3f);
38 | background-size: auto;
39 | background-clip: border-box;
40 | -webkit-background-clip: text;
41 | -webkit-text-fill-color: transparent;
42 | background-size: 100% 100% !important;
43 | font-size: 40px;
44 | }
45 |
46 | p {
47 | font-size: 20px;
48 | line-height: 1.4em;
49 | }
50 |
51 | button {
52 | background: transparent ;
53 | display: inline-block;
54 | box-shadow: none;
55 | text-transform: uppercase;
56 | font-size: 16px;
57 | letter-spacing: 3px;
58 | line-height: 1.4em;
59 | border: 1px solid #fff;
60 | color: #fff;
61 | padding: 14px 40px;
62 | border-radius: 3px;
63 | }
64 |
65 | .row {
66 | width: 100%;
67 | padding: 0 40px;
68 | }
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 | import { Canvas } from '@react-three/fiber'
6 |
7 | const root = ReactDOM.createRoot(document.getElementById('root'));
8 | root.render(
9 |
10 |
11 |
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------