├── 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 GSAP Tutorial](https://raw.githubusercontent.com/lilsugsy/R3F-Tutorial---Robot-Project/main/r3f-thumb.jpg)[(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 | 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 | 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 | 70 |
71 |
72 | 73 |

Cutting-Edge of Grooming

74 | 75 | 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 | --------------------------------------------------------------------------------