Published
Edited
Mar 8, 2020
Insert cell
Insert cell
Insert cell
{
// https://github.com/bradyhouse/house/tree/master/fiddles/three/fiddle-0009-Sun
// https://observablehq.com/d/7b27773cc39263c6
let camera,
renderer,
scene,
controls,
mesh,
meshGroup,
meshes,
height=400;
init();
function createCamera() {
// Create a Camera
const fov = 25; // AKA Field of View
const aspect = width / height;
const near = 0.1; // the near clipping plane
const far = 1000; // the far clipping plane

camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.set(0, 30, 0);
camera.up.set(0,0,1)
camera.lookAt(0,0,0)

}
function createLights() {
// Create a directional light
const mainLight = new THREE.PointLight(0xffffff, 22.0);

mainLight.castShadow = true;
//Set up shadow properties for the light
mainLight.shadow.mapSize.width = 512; // default
mainLight.shadow.mapSize.height = 512; // default
mainLight.shadow.camera.near = 0.5; // default
mainLight.shadow.camera.far = 500 // default
// remember to add the light to the scene
scene.add( mainLight);
var helper = new THREE.CameraHelper( mainLight.shadow.camera );
scene.add( helper );
}
function createMaterials() {
const sunMaterials = {
surfaceMaterial: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/297733/sunSurfaceMaterial.jpg',
atmosphereMaterial: 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/297733/sunAtmosphereMaterial.png'
}
const sun = new THREE.MeshPhongMaterial({
color:'yellow',
emissive: '#F8CE3B',
});
const earth = new THREE.MeshPhongMaterial({
emissive: 0x112244,
flatShading: true,
side: THREE.DoubleSide
});
// const earth = new THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.DoubleSide } );
const L1 = new THREE.MeshPhongMaterial({
emissive: 'gray',
flatShading: true,
side: THREE.DoubleSide
});
const moon = new THREE.MeshPhongMaterial({
emissive: '#191A0F',
flatShading: true
});
[sun,earth,L1,moon].forEach(m=>{
m.color.convertSRGBToLinear();
})
return {
sun,
earth,
L1,
moon
}
}
function createGeometries() {
const sphere = new THREE.SphereBufferGeometry( 1, 12, 12 );
const L1 = new THREE.RingGeometry( 0.1, 1, 12 );
sphere.castShadow = true;
sphere.receiveShadow = true;
L1.castShadow = true;
L1.receiveShadow = true;
return {
sphere,
L1
}
}
function createMeshes() {
const materials = createMaterials();
const geometries = createGeometries();
const sunMesh = new THREE.Mesh( geometries.sphere, materials.sun );
sunMesh.scale.set(3, 3, 3);
const earthMesh = new THREE.Mesh( geometries.sphere, materials.earth );
earthMesh.rotation.x = Math.PI/2 +Math.PI*0.2;
earthMesh.position.x = 10;
const L1Mesh = new THREE.Mesh( geometries.L1, materials.L1 );
L1Mesh.scale.set(0.5, 0.5, 0.5);
// L1Mesh.material.side = THREE.DoubleSide;
L1Mesh.rotation.x = Math.PI/2 +Math.PI*0.2;
L1Mesh.rotation.y = Math.PI/2 // +Math.PI*0.2;
L1Mesh.position.x = 6;
const moonMesh = new THREE.Mesh(geometries.sphere, materials.moon);
moonMesh.position.y = 0;
moonMesh.position.x = 0;
moonMesh.position.z = 0;
moonMesh.scale.set(0.2, 0.2, 0.2);

const solarSystem = new THREE.Object3D();
const earthOrbit = new THREE.Object3D();
earthOrbit.position.x = 10;
const L1Orbit = new THREE.Object3D();
L1Orbit.position.x = 10;
const moonOrbit = new THREE.Object3D();
// moonOrbit.position.y = 2;
moonOrbit.position.x = 2;
moonOrbit.rotateX(Math.PI/2)

moonOrbit.add(moonMesh)
// earthOrbit.add(earthMesh)
earthOrbit.add(moonOrbit)
solarSystem.add(sunMesh)
solarSystem.add(earthOrbit)
solarSystem.add(earthMesh)
solarSystem.add(L1Orbit)
solarSystem.add(L1Mesh)
const group = new THREE.Group();
group.add(solarSystem);
meshGroup = group;

// Add the mesh to the scene
scene.add(group);
return {
sun:sunMesh,
earth:earthMesh,
L1: L1Mesh,
moon:moonMesh,
solarSystem:solarSystem,
earthOrbit:earthOrbit,
moonOrbit:moonOrbit
}
}
function createRenderer() {
// create the renderer
renderer = new THREE.WebGLRenderer({
antialias: true
});

renderer.setSize(width, height);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.gammaFactor = 2.2;
renderer.gammaOutput = true;
renderer.physicallyCorrectLights = true;
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap; // default THREE.PCFShadowMap
}
function init() {
// create a Scene
scene = new THREE.Scene();
// Set the background color
scene.background = new THREE.Color('#000000');
createCamera();
createLights();
meshes = createMeshes();
createRenderer();
Object.values(meshes).forEach(n=>{
const axes = new THREE.AxesHelper();
axes.material.depthTest = false;
axes.renderOrder = 1;
// n.add(axes)
})
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.05;
controls.rotateSpeed = 0.1;
invalidation.then(() => (controls.dispose(), renderer.dispose()));
}
function render() {
renderer.render(scene, camera);
}
function update() {
/*********** PUT ANIMATION LOGIC HERE **********/
meshes.earth.rotation.y +=0.1;
meshes.earthOrbit.rotation.z +=0.1;
// meshes.L1Orbit.rotation.y +=0.1;
meshes.solarSystem.rotation.z +=0.01;
if (camera.position.y < 50) {
camera.position.z += 0.2
camera.position.y += 0.05
}
// camera.lookAt(meshes.L1)
/***********************************************/
}
function onWindowResize() {
camera.aspect = width / height;;
camera.updateProjectionMatrix();
renderer.setSize(width, height)
}
window.addEventListener('resize', onWindowResize)
renderer.setAnimationLoop(() => {
update();
render();
controls.update();
})
invalidation.then(() => {
controls.dispose();
renderer.dispose();
window.removeEventListener('resize', onWindowResize);
});
yield renderer.domElement
}
Insert cell
THREE = {
const THREE = window.THREE = await require("three@0.99.0/build/three.min.js");
await require("three@0.99.0/examples/js/controls/OrbitControls.js").catch(() => {});
return window.THREE;
}
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