Public
Edited
Feb 21
2 forks
Importers
7 stars
Insert cell
Insert cell
threeScene({
width,
height: 300,
visibility,
cam: { z: 5 },
update: ({ meches }) => (meches.cube.rotation.y += 0.01)
})
Insert cell
Insert cell
function* threeScene({
width,
height, // dimmensions
visibility = e => e, // for preventing updates when not visible
update, // update function, if not present, scene will be static
init, // init function, called with all base object for additional scene setup
cam = {}, // camera setup
addMeshes = defaultMesh, // adds meches to scene
addLights = defaultLights, // adds lights to scene
createControls = defaultControls, // setup controls
backgroundColor = 0x8FBCD4 // bg color
}) {
const scene = createScene(backgroundColor);
const renderer = createRenderer({ width, height });
console.log('cam setup', { ...cam, width, height });
const camera = cam.setup
? cam.setup({ width, height })
: defaultCamera({ ...cam, width, height });
const controls = createControls({ camera, element: renderer.domElement });

invalidation.then(() => (controls.dispose(), renderer.dispose()));

const lights = addLights(scene);
const meches = addMeshes(scene);

if (init) {
init({ scene, renderer, camera, controls, lights, meches });
}

if (update) {
while (true) {
update({ scene, renderer, camera, controls, lights, meches });
renderer.render(scene, camera);
yield visibility(renderer.domElement);
}
} else {
controls.addEventListener("change", () => renderer.render(scene, camera));
renderer.render(scene, camera);
yield visibility(renderer.domElement);
}
}
Insert cell
Insert cell
createScene = function(color) {
const scene = new THREE.Scene();
scene.background = new THREE.Color( color );
return scene;
}
Insert cell
function createRenderer({width, height}) {
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( width, height );
renderer.setPixelRatio( devicePixelRatio );

renderer.outputEncoding = THREE.sRGBEncoding;

renderer.physicallyCorrectLights = true;

return renderer;
}
Insert cell
function defaultMesh(scene) {
const material = new THREE.MeshStandardMaterial({
color: 0xff3333
});
// just as with textures, we need to put colors into linear color space
material.color.convertSRGBToLinear();

const geometry = new THREE.BoxGeometry(2, 2, 2);

const cube = new THREE.Mesh(geometry, material);

scene.add(cube);

return { cube };
}
Insert cell
function defaultLights(scene) {

const ambientLight = new THREE.HemisphereLight( 0xddeeff, 0x0f0e0d, 5 );

const mainLight = new THREE.DirectionalLight( 0xffffff, 5 );
mainLight.position.set( 10, 10, 10 );

scene.add( ambientLight, mainLight );
return {ambientLight, mainLight};
}
Insert cell
function defaultControls({ camera, element }) {
const controls = new OrbitControls(camera, element);
return controls;
}
Insert cell
function defaultCamera({
width,
height,
x = -4,
y = 4,
z = 10,
fov = 45,
near = 0.1,
far = 100
}) {
const aspect = width / height;
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(x, y, z);
camera.lookAt(new THREE.Vector3(0, 0, 0));
return camera;
}
Insert cell
Insert cell
THREE = import("three@0.173.0")
Insert cell
OrbitControls = (
await import("three@0.173.0/examples/jsm/controls/OrbitControls.js")
).OrbitControls
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