Steve Ruiz
Knock together three.js scenes using overrides.
The component takes two lifecycle overrides: start
and update
.
start
will be called once when the component first loads. Use start
to set up the scene, adding lights, objects and positions.
update
will be called on each animation frame, about 60 times per second. Use update
to handle animations, interactions, and other changes.
Both functions run with two arguments: the props
of the component and a few of the component’s elements: the parent scene
, the current camera
, the normalized mouse
position, and a raycaster
.
The component comes with a default camera (a new THREE.PerspectiveCamera(75, 1, 0.01, 1000)
) though you can change this via the camera
override.
export const BasicOverride: Override = (props) => {
return {
camera: new THREE.PerspectiveCamera(75, 1, 0.01, 1000),
start: (props, { scene, camera, mouse, raycaster }) => {},
update: (props, { scene, camera, mouse, raycaster }) => {},
onClick: (props, { scene, camera, mouse, raycaster }) => {},
onMouseMove: (props, { scene, camera, mouse, raycaster }) => {},
onMouseEnter: (props, { scene, camera, mouse, raycaster }) => {},
onMouseLeave: (props, { scene, camera, mouse, raycaster }) => {},
}
}
import { Data, animate, Override, Animatable } from 'framer'
import * as THREE from 'three'
const data = Data({ speed: 0.025 })
const light = new THREE.DirectionalLight(0xfffff0, 1)
light.position.set(50, 100, 150)
const cube = new THREE.Mesh(
new THREE.BoxGeometry(1, 1, 1),
new THREE.MeshStandardMaterial({
color: 0xaaaaa0,
})
)
export const three: Override = () => {
return {
start(props, { scene }) {
scene.add(light)
scene.add(cube)
},
update(props, { scene }) {
cube.rotation.x += data.speed
cube.rotation.y += data.speed
cube.rotation.z += data.speed
},
onMouseEnter() {
data.speed = 0.05
},
onMouseLeave() {
data.speed = 0.025
},
}
}
import { Override, serverURL } from 'framer'
import * as THREE from 'three'
import * as GLTFLoader from 'three-gltf-loader'
const loader = new GLTFLoader()
const light = new THREE.DirectionalLight('#FF0000', 1)
light.position.set(1, 10, 1)
export const SceneOverride: Override = (props) => {
return {
start: (props, { scene, camera, mouse, raycaster }) => {
scene.add(light)
const url = serverURL() + 'models/cat/scene.gltf'
loader.load(url, (gltf) => {
scene.add(gltf.scene)
})
},
update: (props, { scene, camera, mouse, raycaster }) => {
scene.rotation.y += 0.01
light.rotation.y -= 0.01
},
onClick: (props, { scene, camera, mouse, raycaster }) => {},
onMouseMove: (props, { scene, camera, mouse, raycaster }) => {},
onMouseEnter: (props, { scene, camera, mouse, raycaster }) => {},
onMouseLeave: (props, { scene, camera, mouse, raycaster }) => {},
}
}