Last active
September 14, 2023 17:32
-
-
Save drcmda/6ccb3264475c23f0f72dc48e6d44d370 to your computer and use it in GitHub Desktop.
scrolling images + minimap
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as THREE from 'three' | |
import { Suspense, useRef, useState } from 'react' | |
import { Canvas, createPortal, applyProps, useFrame, useThree } from '@react-three/fiber' | |
import { useFBO, PerspectiveCamera, ScrollControls, Scroll, useScroll, Image } from '@react-three/drei' | |
function Images() { | |
const { width, height } = useThree(state => state.viewport) | |
const data = useScroll() | |
const group = useRef() | |
useFrame(() => { | |
group.current.children[0].material.zoom = 1 + data.range(0, 1 / 3) / 3 | |
group.current.children[1].material.zoom = 1 + data.range(0, 1 / 3) / 3 | |
group.current.children[2].material.zoom = 1 + data.range(1.15 / 3, 1 / 3) / 3 | |
group.current.children[3].material.zoom = 1 + data.range(1.15 / 3, 1 / 3) / 2 | |
group.current.children[4].material.zoom = 1 + data.range(1.25 / 3, 1 / 3) / 1 | |
group.current.children[5].material.zoom = 1 + (1 - data.range(2 / 3, 1 / 3)) / 3 | |
}) | |
return ( | |
<Scroll ref={group}> | |
<Image position={[2, 0, 1]} scale={3} url="/img2.jpg" /> | |
<Image position={[-2, 0, 0]} scale={[4, height, 1]} url="/img1.jpg" /> | |
<Image position={[-2, -height, 2]} scale={[1, 3, 1]} url="/img3.jpg" /> | |
<Image position={[-0.4, -height, 3]} scale={[1, 2, 1]} url="/img3.jpg" /> | |
<Image position={[0.6, -height, 4]} scale={[1, 1, 1]} url="/img3.jpg" /> | |
<Image position={[0, -height * 2, 0]} scale={[width, height - width * 0.2, 1]} url="/img4.jpg" /> | |
</Scroll> | |
) | |
} | |
function Minimap({ children }) { | |
const viewport = useThree((state) => state.viewport) | |
const fbo = useFBO(512, 512) | |
const camera = useRef() | |
const [scene] = useState(() => applyProps(new THREE.Scene(), { overrideMaterial: new THREE.MeshBasicMaterial({ color: 'black' }) })) | |
useFrame((state) => { | |
state.gl.setRenderTarget(fbo) | |
state.gl.render(scene, camera.current) | |
state.gl.setRenderTarget(null) | |
}) | |
return ( | |
<> | |
{createPortal(children, scene)} | |
<PerspectiveCamera position={[0, 0, 17]} fov={75} ref={camera} /> | |
<mesh position={[viewport.width / 6, viewport.height / 8, 3]}> | |
<planeGeometry /> | |
<meshBasicMaterial transparent map={fbo.texture} /> | |
</mesh> | |
</> | |
) | |
} | |
export default function App() { | |
return ( | |
<Canvas dpr={[1, 2]}> | |
<Suspense fallback={null}> | |
<ScrollControls damping={4} pages={3} distance={1.5}> | |
<Minimap> | |
<Images /> | |
</Minimap> | |
<Images /> | |
</ScrollControls> | |
</Suspense> | |
</Canvas> | |
) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
ScrollControls, Scroll, useScroll, Image, not found in '@react-three/drei'
Which version of drei are you using?