Skip to content

Commit

Permalink
Add week 13 post processing code section
Browse files Browse the repository at this point in the history
  • Loading branch information
juniorxsound committed Nov 30, 2023
1 parent c0ac3b6 commit b210bf7
Show file tree
Hide file tree
Showing 16 changed files with 359 additions and 0 deletions.
24 changes: 24 additions & 0 deletions classes/week-13/post-processing-r3f/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
1 change: 1 addition & 0 deletions classes/week-13/post-processing-r3f/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# ITP Visual Journalism Fall 2023 - Post Processing
12 changes: 12 additions & 0 deletions classes/week-13/post-processing-r3f/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ITP Visual Journalism Fall 2023 - Week 13</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.jsx"></script>
</body>
</html>
31 changes: 31 additions & 0 deletions classes/week-13/post-processing-r3f/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "post-processing-r3f",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"start": "vite",
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"@react-three/drei": "^9.80.4",
"@react-three/fiber": "^8.13.7",
"@react-three/postprocessing": "^2.15.11",
"gsap": "^3.12.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"three": "^0.155.0"
},
"devDependencies": {
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@types/three": "^0.155.0",
"@vitejs/plugin-react": "^4.0.3",
"vite": "^4.3.8"
},
"engines": {
"node": "16.x"
}
}
Binary file not shown.
70 changes: 70 additions & 0 deletions classes/week-13/post-processing-r3f/src/AnimatedCamera.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useRef, useEffect } from "react";
import { PerspectiveCamera } from "@react-three/drei";

import { AnimationTimeline } from "./AnimationTimeline";

function AnimatedCamera() {
const cameraRef = useRef();

useEffect(() => {
// Here we define the entire sequence of animations for the camera using GSAP
AnimationTimeline.to(
cameraRef.current.position,
{
x: -0.6,
y: 0.5,
z: 2,
},
"intro"
);

AnimationTimeline.to(
cameraRef.current.rotation,
{
y: -0.3,
},
"intro"
);

AnimationTimeline.to(
cameraRef.current.position,
{
x: 0.6,
},
"middle"
);

AnimationTimeline.to(
cameraRef.current.rotation,
{
y: 0.3,
},
"middle"
);

AnimationTimeline.to(
cameraRef.current.position,
{
x: 0,
y: 2.5,
z: 10,
},
"outro"
);

AnimationTimeline.to(
cameraRef.current.rotation,
{
y: 0,
},
"outro"
);

return () => CameraTimeline.kill();
}, []);
return (
<PerspectiveCamera ref={cameraRef} makeDefault position={[0, 2.5, 10]} />
);
}

export default AnimatedCamera;
5 changes: 5 additions & 0 deletions classes/week-13/post-processing-r3f/src/AnimationTimeline.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { gsap } from "gsap";

export const AnimationTimeline = gsap.timeline({
paused: true, // We set this here so we can adjust progress tied to scroll
});
26 changes: 26 additions & 0 deletions classes/week-13/post-processing-r3f/src/App.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
body {
/* Reseting the default here */
margin: 0;
}

#article_wrapper {
position: relative;
background-color: grey;
height: 5000px; /* Length of the interactive scroll article */
}

#canvas_wrapper {
position: -webkit-sticky; /* Safari */
position: sticky;
top: 0;
width: 100vw;
height: 100vh;
}

.scroll_slide {
color: "white";
position: "absolute";
width: "50vw";
padding-left: "20px";
z-index: "50";
}
34 changes: 34 additions & 0 deletions classes/week-13/post-processing-r3f/src/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useEffect, useState } from "react";

import Scene from "./Scene";
import SimpleSlide from "./SimpleSlide";
import useScrollProgress from "./useScrollProgress";
import { AnimationTimeline } from "./AnimationTimeline";

// We add a CSS file here so we can style components
import "./App.css";

function App() {
const progress = useScrollProgress();

// Set the animation to play based on scroll position
useEffect(() => {
AnimationTimeline.progress(progress);
}, [progress]);

return (
<div id="article_wrapper">
{/* HTML slides are nested here and we use vh values to specify where they are */}
<SimpleSlide viewportPosition={50}>Hello from slide 1</SimpleSlide>
<SimpleSlide viewportPosition={100}>Hello from slide 2</SimpleSlide>
<SimpleSlide viewportPosition={200}>Hello from slide 3</SimpleSlide>
<SimpleSlide viewportPosition={300}>Hello from slide 4</SimpleSlide>
<SimpleSlide viewportPosition={550}>Hello from slide 5</SimpleSlide>

{/* 3D scene container */}
<Scene />
</div>
);
}

export default App;
32 changes: 32 additions & 0 deletions classes/week-13/post-processing-r3f/src/FX.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
EffectComposer,
Bloom,
Vignette,
DepthOfField,
Noise,
Pixelation,
Outline,
} from "@react-three/postprocessing";

/**
* Looking for a list of possible effects and their props?
* @see https://docs.pmnd.rs/react-postprocessing/introduction
*/
function FX() {
return (
<EffectComposer>
<DepthOfField
focusDistance={0}
focalLength={0.02}
bokehScale={2}
height={480}
/>
<Bloom luminanceThreshold={0} luminanceSmoothing={0.2} height={300} />
<Noise opacity={0.02} />
<Vignette offset={0.1} darkness={1.1} />
<Pixelation granularity={10} />
</EffectComposer>
);
}

export default FX;
20 changes: 20 additions & 0 deletions classes/week-13/post-processing-r3f/src/InfiniteAnimatedModel.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useEffect } from "react";
import { useGLTF, useAnimations } from "@react-three/drei";

function InfiniteAnimatedModel(props) {
const { modelUrl, position } = props;

const { scene, animations } = useGLTF(modelUrl);
const { actions } = useAnimations(animations, scene);
const firstAnimationClip = Object.values(actions)[0];

// Set the animation to play based on scroll position
useEffect(() => {
// We set the animation to play and pause it
firstAnimationClip.play();
}, [actions]);

return <primitive position={position} object={scene} />;
}

export default InfiniteAnimatedModel;
49 changes: 49 additions & 0 deletions classes/week-13/post-processing-r3f/src/Scene.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Canvas } from "@react-three/fiber";
import { BackSide } from "three";
import { Environment } from "@react-three/drei";

import AnimatedCamera from "./AnimatedCamera";
import InfiniteAnimatedModel from "./InfiniteAnimatedModel";
import FX from "./FX";
import { Suspense } from "react";

function Scene() {
return (
<div id="canvas_wrapper">
<Canvas>
<FX />

<Environment preset="night" />

{/* Camera 🎥 */}
<AnimatedCamera />

{/* Models with animations */}
<Suspense>
<InfiniteAnimatedModel
modelUrl="/mixamo_armature.glb"
position={[0, 0, 0]}
/>
</Suspense>

{/* Lights 💡 */}
<ambientLight intensity={0.15} color="white" />
<pointLight color="green" position={[1, 1, 1]} intensity={3} />
<pointLight color="yellow" position={[-2, 3, 1]} intensity={3} />
<pointLight color="blue" position={[2, 3, 1]} intensity={3} />
<pointLight color="white" position={[0, 1, 2.5]} intensity={3} />

{/* We can create a background color as a child element of the canvas we just have to attach it */}
<color args={["grey"]} attach="background" />

{/* Objects 📦 */}
<mesh position={[0, 2.5, 0]}>
<boxGeometry args={[7, 5, 5]} />
<meshStandardMaterial side={BackSide} />
</mesh>
</Canvas>
</div>
);
}

export default Scene;
19 changes: 19 additions & 0 deletions classes/week-13/post-processing-r3f/src/SimpleSlide.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
function SimpleSlide(props) {
const { children, viewportPosition } = props;
return (
<h2
style={{
color: "white",
position: "absolute",
minWidth: "45vw",
paddingLeft: "20px", // To offset slides a tiny bit from the left side of the screen
top: `${viewportPosition}vh`,
zIndex: "50",
}}
>
{children}
</h2>
);
}

export default SimpleSlide;
5 changes: 5 additions & 0 deletions classes/week-13/post-processing-r3f/src/main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App.jsx";

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
21 changes: 21 additions & 0 deletions classes/week-13/post-processing-r3f/src/useScrollProgress.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useEffect, useState } from "react";

export default function useScrollProgress() {
const [scrollProgress, setScrollProgress] = useState(0);

useEffect(() => {
const handleScroll = () => {
const scrollPosition = window.scrollY;
const totalHeight = document.body.scrollHeight - window.innerHeight;
const progress = scrollPosition / totalHeight;
setScrollProgress(progress);
};
// Register the event listener
window.addEventListener("scroll", handleScroll);

// Remove event listener on cleanup
return () => window.removeEventListener("scroll", handleScroll);
}, []);

return scrollProgress;
}
10 changes: 10 additions & 0 deletions classes/week-13/post-processing-r3f/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
server: {
port: 3000,
},
plugins: [react()],
});

0 comments on commit b210bf7

Please sign in to comment.