Skip to content

Headless React Three Fiber canvas

Use this pattern when your application already owns the canvas, post-processing, physics, or scene composition.

tsx
import { OrbitControls, useGLTF } from '@react-three/drei'
import { Canvas } from '@react-three/fiber'
import { useRef } from 'react'
import * as THREE from 'three'
import { ModelPivotGroup } from '@taranjeetsinghh/model-lab/pivot'
import { ImmersiveSequencePlayer } from '@taranjeetsinghh/model-lab/sequence'
import { CinematicEffectDriver } from '@taranjeetsinghh/model-lab/effects'

function Scene({ preset }) {
  const gltf = useGLTF('/models/product.glb')
  const modelRef = useRef<THREE.Group>(null)
  const controlsRef = useRef<any>(null)
  const progressRef = useRef<number | null>(null)

  return (
    <>
      <ModelPivotGroup
        ref={modelRef}
        pivot={preset.viewer.pivot.point}
        position={preset.viewer.model.position}
        rotation={preset.viewer.model.rotation}
        scale={preset.viewer.model.scale}
      >
        <primitive object={gltf.scene} />
      </ModelPivotGroup>

      <OrbitControls ref={controlsRef} />

      <ImmersiveSequencePlayer
        modelRef={modelRef}
        controlsRef={controlsRef}
        sequence={preset.viewer.sequence}
        progressRef={progressRef}
        play
      />

      <CinematicEffectDriver
        modelRef={modelRef}
        progressRef={progressRef}
        effect={{ type: 'cosmic-pulse' }}
      />
    </>
  )
}

export function Experience({ preset }) {
  return <Canvas><Scene preset={preset} /></Canvas>
}

Released under the MIT License.