Published
Edited
Apr 25, 2020
1 fork
Importers
4 stars
Insert cell
Insert cell
Insert cell
reusable3dCanvas( this, cube, { background, camera: { aspect: 2, position: [3,4,5], rotateSpeed:10.0 }, trackballControl: true } )
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
cube = new THREE.Mesh( new THREE.CubeGeometry(), new THREE.MeshLambertMaterial( { color: cubeColor } ) )
Insert cell
Insert cell
reusable3dCanvas = function( existingCanvas, mesh, config={} ) {
if ( existingCanvas && existingCanvas.replaceMesh ) {
existingCanvas.replaceMesh( mesh )
return existingCanvas
} else {
return reactive3dCanvas( mesh, config )
}
}
Insert cell
reactive3dCanvas = function( mesh, config={} ) {
let { orbitControl=true, trackballControl=false } = config
const camera = lightedCamera( perspectiveCamera( config.camera ), config.lights )
const s = scene( mesh, camera, config )
var r = renderer( config )
var control = null
if ( trackballControl )
// we want to toggle this off sometimes, to avoid the OrbitControls import bug
control = addTrackballControl( r, s, camera, config.camera )
else if ( orbitControl )
// we want to toggle this off sometimes, to avoid the OrbitControls import bug
control = addOrbitControl( r, s, camera, config.camera )

// enable later scene manipulation
r.domElement.scene = s
r.domElement.render = () => r .render( s, camera )
r.domElement.replaceMesh = function( mesh ) {
// this will only apply in a reusable canvas
s .remove( s .replaceableMesh )
s .add( mesh )
s .replaceableMesh = mesh
r .render( s, camera )
}
r.domElement.adjustCamera = function( position, lookAt, up ) {
camera .lookAt( new THREE.Vector3( ...lookAt ) ) // This seems to be disabled by OrbitControls
control .target = new THREE.Vector3( ...lookAt )
camera .up = new THREE.Vector3( ...up )
camera .position .set( ...position )
control .update()
r .render( s, camera )
}
r .render( s, camera )
return r.domElement
}
Insert cell
renderer = function( config={} ) {
let { renderWidth=width, camera={} } = config
let { aspect=2 } = camera
const renderer = new THREE.WebGLRenderer( {antialias: true} )
renderer.setPixelRatio( window.devicePixelRatio )
renderer.setSize( renderWidth, renderWidth/aspect )
return renderer
}
Insert cell
perspectiveCamera = function( config={} ) {
let { fov=30, aspect=2, near=1, far=4000, position=[0,0,500], up=[0,0,1], lookAt=[0,0,0] } = config
console.log( lookAt )
const camera = new THREE.PerspectiveCamera( fov, aspect, near, far )
camera .lookAt( new THREE.Vector3( ...lookAt ) ) // This seems to be disabled by OrbitControls
camera .up = new THREE.Vector3( ...up )
camera .position .set( ...position )
return camera
}
Insert cell
lightedCamera = function( camera, config={} ) {
const { spot={ color:0x888888, intensity:0.4, position:[200,500,0] } } = config
const spotLight = new THREE.SpotLight( spot.color, spot.intensity )
spotLight .position .set( ...spot.position )
camera .add( spotLight )

const { ambient={ color:0x444444, intensity:0.8 } } = config
camera .add( new THREE.AmbientLight( ambient.color, ambient.intensity ) )
camera .add( new THREE.HemisphereLight( 0xefede8, 0x727248, .6 ) )
return camera
}
Insert cell
scene = function( mesh, camera, config={} ) {
const scene = new THREE.Scene()
const { background=0xaaccff } = config
scene .background = new THREE.Color( background )
scene .add( camera )
scene .add( mesh )
scene .replaceableMesh = mesh
return scene
}
Insert cell
addOrbitControl = function( renderer, scene, camera, config={} ) {
let { lookAt=[0,0,0] } = config
const control = new THREE.OrbitControls( camera, renderer.domElement )
control .target = new THREE.Vector3( ...lookAt )
// controls .rotateSpeed = 5;
// controls .zoomSpeed = 2.5;
control.addEventListener( "change", () => {
renderer.render(scene, camera)
})
function animate() {
requestAnimationFrame( animate )
control .update()
}
animate()
return control
}
Insert cell
addTrackballControl = function( renderer, scene, camera, config={} ) {
let { lookAt=[0,0,0], rotateSpeed=5 } = config
const control = new THREE.TrackballControls( camera )
control .target = new THREE.Vector3( ...lookAt )
control .rotateSpeed = 5;
control .zoomSpeed = 2.5;
control.addEventListener( "change", () => {
renderer.render(scene, camera)
})
function animate() {
requestAnimationFrame( animate )
control .update()
}
animate()
return control
}
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more