planets
a three.js display of planets by notchris
by notchris
HTML
<div id="render"></div>
<div class="pallete">
<div class="sun"></div>
<div class="a"></div>
<div class="b"></div>
<div class="c"></div>
<div class="d"></div>
<div class="e"></div>
<div class="f"></div>
<div class="g"></div>
<div class="h"></div>
</div>
SCSS
* {
box-sizing: border-box;
text-rendering: optimizeLegibility;
font-kerning: auto;
}
html {
font-family: sans-serif;
}
body {
margin: 0;
}
html,
body {
width: 100%;
height: 100%;
}
.label {
margin-top: -2em;
text-align: center;
}
.label .planet-distance::after {
content: '';
font-size: 0.1em;
position: absolute;
top: 24px;
left: 50%;
width: 1px;
height: 16px;
background: rgba(0, 0, 0, 0.5);
}
.planets {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.planet-title {
font-family: 'Arial', sans-serif;
font-size: 0.6em;
font-weight: 600;
display: block;
width: 100%;
text-transform: uppercase;
padding-bottom:0.3em;
}
.planet-distance {
font-family: 'Arial', sans-serif;
font-size: 0.5em;
font-weight: 400;
display: block;
width: 100%;
}
#render {
width: 100%;
height: 100%;
min-height: 200px;
max-height: 200px;
max-width: 100%;
position: relative;
}
.pallete {
display: flex;
align-items: center;
flex-direction: row;
justify-content: center;
padding: 0.5em 0;
}
.pallete div {
width: 30px;
height: 30px;
margin-right: 1em;
opacity: 0.5;
border-radius: 30px;
cursor: pointer;
}
.pallete div:hover {
border: 2px solid rgba(0, 0, 0, 0.5);
opacity: 1;
}
.pallete div:last-child {
margin-right: 0 !important;
}
.pallete {
& .sun {
background: #FFE600
}
& .a {
background: #C2D0FF
}
& .b {
background: #FF9900
}
& .c {
background: #00A3FF
}
& .d {
background: #FF5C00
}
& .e {
background: #E59700
}
& .f {
background: #FFCF72
}
& .g {
background: #61D9FF
}
& .h {
background: #0047FF
}
}
JavaScript
/* Planets by notchris */
import * as THREE from "https://cdn.skypack.dev/[email protected]";
import {
CSS2DRenderer,
CSS2DObject
} from 'https://cdn.skypack.dev/[email protected]/examples/jsm/renderers/CSS2DRenderer.js'
import gsap from "https://cdn.skypack.dev/[email protected]";
import {
OrbitControls
} from "https://cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls";
let renderer,
labelRenderer,
scene,
camera,
clock,
planets,
controls,
mainObj,
activePlanet
const el = document.querySelector('#render')
const { width, height } = el.getBoundingClientRect()
const size = new THREE.Vector3()
const center = new THREE.Vector3()
const box = new THREE.Box3()
init()
const planetArr = [
'sun',
'mercury',
'venus',
'earth',
'mars',
'jupiter',
'saturn',
'uranus',
'neptune'
]
const planetEls = document.querySelectorAll('.pallete > div')
planetEls.forEach((p, i) => {
p.addEventListener('mouseover', () => {
activePlanet = planetArr[i]
gsap.to(mainObj.rotation, {
duration: 0.3,
x: Math.PI / 2,
ease: 'none',
paused: false
})
gsap.to(mainObj.position, {
duration: 0.3,
z: 200,
ease: 'none',
paused: false
})
const mesh = scene.getObjectByName(planetArr[i])
mesh.children[0].visible = true
activePlanet = mesh
})
p.addEventListener('mouseleave', () => {
gsap.to(mainObj.rotation, {
duration: 0.3,
x: 0.1,
ease: 'none',
paused: false
})
gsap.to(mainObj.position, {
duration: 0.3,
z: 0,
ease: 'none',
paused: false
})
const mesh = scene.getObjectByName(planetArr[i])
mesh.children[0].visible = false
activePlanet = null
})
})
animate()
function fitCameraToSelection(camera, controls, selection, fitOffset) {
box.makeEmpty()
for (const object of selection)...