Skip to content

Instantly share code, notes, and snippets.

@drcmda
Last active September 14, 2023 17:32
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drcmda/6ccb3264475c23f0f72dc48e6d44d370 to your computer and use it in GitHub Desktop.
Save drcmda/6ccb3264475c23f0f72dc48e6d44d370 to your computer and use it in GitHub Desktop.
scrolling images + minimap
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>
)
}
@vradionovskii
Copy link

ScrollControls, Scroll, useScroll, Image, not found in '@react-three/drei'
Which version of drei are you using?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment