'use client'
import { Canvas, useThree } from '@react-three/fiber'
import { ScrollControls, Scroll, Html } from '@react-three/drei'
import { Scene } from './components/Scene'
import { ScrollContainer } from './components/ScrollContainer'
export default function Home() {
return (
<div className='w-full h-screen'>
<Canvas camera={{ position: [0, 0, 5], fov: 75 }} className='w-full h-full'>
<ScrollControls pages={3} damping={0.1}>
<ambientLight intensity={0.5} />
<pointLight position={[10, 10, 10]} />
<Scene />
<Scroll html className='w-full'>
<ScrollContainer>
<h1>html in here (optional)</h1>
<h1 style={{ top: '100vh' }}>second page</h1>
{/* I want this img dom shown as background behind the model*/}
<div style={{ top: '200vh' }}>
<img src={'example.png'} style={{ width:'100%', height:'100%' }}/>
</div>
</ScrollContainer>
</Scroll>
</ScrollControls>
</Canvas>
</div>
)
}
I put the following into my .css file:
canvas {
display: block;
background: url(./Test.jpg) repeat 0 0;
background-size: auto;
}
then in the .js file, I set alpha: true:
renderer = new THREE.WebGLRenderer( { antialias: true, alpha: true } );
It will set background to whole page as 3d model is rendered on whole page. I only want background in last section when user reaches there scrolling the 3d model
//Scene.jsx
import { useRef } from 'react'
import { useFrame } from '@react-three/fiber'
import { useScroll, Environment, PerspectiveCamera } from '@react-three/drei'
import { calculatePosition, calculateRotation } from '../lib/animations'
import { Group, Mesh } from 'three'
import { Model } from './Model'
export function Scene() {
const modelRef = useRef(null)
const meshRef = useRef(null)
const scroll = useScroll()
useFrame((state) => {
if (!modelRef.current || !meshRef.current) return
const scrollOffset = scroll.offset
const newPosition = calculatePosition(scrollOffset)
const newRotation = calculateRotation(scrollOffset, state.clock.elapsedTime)
modelRef.current.position.copy(newPosition)
meshRef.current.rotation.copy(newRotation)
})
return (
<>
<PerspectiveCamera makeDefault position={[0, 0, 20]} />
<Environment preset='sunset' />
<ambientLight intensity={0.5} />
<spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} intensity={1} castShadow />
<group ref={modelRef}>
<mesh ref={meshRef} castShadow receiveShadow>
<Model url='/polaroid_camera/scene.gltf' position={[0, -3, 0]} />
</mesh>
</group>
</>
)
}
I don’t quite understand your problem, you show the jsx
code, but you want everything to happen outside the Canvas
, because at the very bottom under the model, there should be a background as part of the DOM
, not React
. If the solution from this thread is not right for you, then the solution proposed by @vielzutun.ch should be. What you are looking for is done in the z-order
, and through, among other things, CSS
manipulation you will get the variant you want. If you want the model to be only a small part of your structure, you mainly manage it through layers order (CSS) and the Alpha
channel (Canvas).
Here is the sandbox that I create to show the problem Create 3D scroll animation website (forked) - StackBlitz
I basically want 3d model to scroll vertically on page with user scroll and there is background image at last div(bottom of screen) that should be behind the 3d model