Skip to main content

Popup

Type

Class

Default Usage

import { Scene, Popup } from 'react-three-lite'
import TrafficLight from './TrafficLight'

function App() {
const handleCreated = (scene, { camera }) => {
camera.position.set(0, 1.5, 3)

// Create popup with React component at starting position [0, 1, 0]
const popup = new Popup([0, 1, 0], <TrafficLight />, {})
scene.add(popup.scene)

// Move popup vertically upward to [0, 2, 0] with 2 seconds animation
popup.moveTo([0, 2, 0], 2000)
}

return (
<Scene
style={{ marginTop: '10px', width: '100%', height: '300px' }}
onCreated={handleCreated}
/>
)
}

TrafficLight Component

Here is the code for the TrafficLight component used in the example above:

TrafficLight.tsx

import { useState, useEffect } from 'react'

export default function TrafficLight() {
const [currentLight, setCurrentLight] = useState('red')
const [offsetY, setOffsetY] = useState(0)

useEffect(() => {
// Light color changing animation
const lightTimer = setInterval(() => {
setCurrentLight(prev => {
if (prev === 'red') return 'green'
if (prev === 'green') return 'yellow'
return 'red'
})
}, 2000)

// Vertical movement animation
let direction = 1
const moveTimer = setInterval(() => {
setOffsetY(prev => {
const newValue = prev + direction * 0.05
if (newValue > 0.3 || newValue < -0.3) {
direction = -direction
}
return Math.max(-0.3, Math.min(0.3, newValue))
})
}, 50)

return () => {
clearInterval(lightTimer)
clearInterval(moveTimer)
}
}, [])

return (
<div style={{
display: 'flex',
flexDirection: 'column',
gap: '4px',
padding: '8px',
background: '#333',
borderRadius: '6px',
border: '1px solid #666',
transform: `translateY(${offsetY}px)`
}}>
<div style={{
width: '20px',
height: '20px',
borderRadius: '50%',
background: currentLight === 'red' ? '#ff0000' : '#330000',
boxShadow: currentLight === 'red' ? '0 0 10px #ff0000' : 'none',
transition: 'all 0.3s'
}} />
<div style={{
width: '20px',
height: '20px',
borderRadius: '50%',
background: currentLight === 'yellow' ? '#ffff00' : '#333300',
boxShadow: currentLight === 'yellow' ? '0 0 10px #ffff00' : 'none',
transition: 'all 0.3s'
}} />
<div style={{
width: '20px',
height: '20px',
borderRadius: '50%',
background: currentLight === 'green' ? '#00ff00' : '#003300',
boxShadow: currentLight === 'green' ? '0 0 10px #00ff00' : 'none',
transition: 'all 0.3s'
}} />
</div>
)
}

Methods

NameParametersDescription
constructor(position: [number, number, number], component: ReactNode, props: object) => voidCreates a new Popup instance. component can be a React element.
moveTo(position: [number, number, number], duration: number) => voidduration is the duration from one position to another. The unit is millisecond.