A Pen by Richard Gil on CodePen.
Created
March 26, 2019 19:07
-
-
Save shshaw/4ea4105f2e626e122f33395145275d46 to your computer and use it in GitHub Desktop.
Basecamp Demo
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="container"></div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
console.clear(); | |
var camera, | |
scene, | |
controls, | |
renderer, | |
renderer2, | |
raycaster, | |
mousePosition, | |
canvas, | |
canvasPosition; | |
var group, moleculeColor, moleculesGroup; | |
var x = 0; | |
var objects = []; | |
axes = new THREE.AxesHelper(100); | |
moleculesGroup = new THREE.Group(); | |
////////// Setting Up ////////// | |
scene = new THREE.Scene(); | |
scene.add(axes); | |
raycaster = new THREE.Raycaster(); | |
mouse = new THREE.Vector2(); | |
camera = new THREE.PerspectiveCamera( | |
10, | |
window.innerWidth / window.innerHeight, | |
0.1, | |
20000 | |
); | |
camera.position.set(0, 0, 9000); | |
camera.updateProjectionMatrix(); | |
// loading in background | |
var texture = new THREE.TextureLoader().load( | |
"https://s3-us-west-2.amazonaws.com/s.cdpn.io/65844/bg.jpg" | |
); | |
var geometry = new THREE.PlaneGeometry(5000, 2500, 64); | |
var material = new THREE.MeshBasicMaterial({ | |
map: texture, | |
color: 0xffffff, | |
side: THREE.DoubleSide | |
}); | |
scene.background = texture; | |
////////// Trackball Controls ////////// | |
controls = new THREE.TrackballControls(camera); | |
controls.noRotate = true; | |
controls.rotateSpeed = 3.6; | |
controls.zoomSpeed = 0.8; | |
controls.panSpeed = 1; | |
controls.noZoom = false; | |
controls.noPan = false; | |
controls.noRotate = false; | |
controls.staticMoving = false; | |
controls.dynamicDampingFactor = 0.12; | |
controls.enabled = false; | |
////////// Orbit Controls ////////// | |
// controls = new THREE.OrbitControls(camera); | |
// controls.autoRotate = false; | |
// controls.zoomSpeed = 0.8; | |
// controls.rotateSpeed = 3.6; | |
// controls.panSpeed = 1; | |
// controls.enableZoom = true; | |
// controls.enablePan = true; | |
// controls.enableDamping = true; | |
// controls.dampingFactor = 0.12; | |
// controls.enabled = true; | |
renderer = new THREE.CSS3DRenderer(); | |
renderer.setSize(window.innerWidth, window.innerHeight); | |
renderer.domElement.style.position = "absolute"; | |
renderer.domElement.style.top = 0; | |
document.getElementById("container").appendChild(renderer.domElement); | |
renderer2 = new THREE.WebGLRenderer({ antialias: true, alpha: true }); | |
renderer2.setClearColor(0x000000, 0); | |
renderer2.setSize(window.innerWidth, window.innerHeight); | |
document.body.appendChild(renderer2.domElement); | |
window.addEventListener("resize", function() { | |
var width = window.innerWidth; | |
var height = window.innerHeight; | |
renderer.setSize(width, height); | |
renderer2.setSize(width, height); | |
camera.aspect = width / height; | |
camera.updateProjectionMatrix(); | |
}); | |
////////// Setting up molecules ////////// | |
var angle = 0; | |
var radius = 600; | |
var container = document.getElementById("container"); | |
var containerPositionInfo = container.getBoundingClientRect(); | |
var containerWidth = containerPositionInfo.width; | |
var containerHeight = window.innerHeight; | |
var step = 2 * Math.PI / data.molecules.length; | |
var sphereRadius = 100; | |
for (var i = 0; i < data.molecules.length; i++) { | |
var title = data.molecules[i].title; | |
var shape = data.molecules[i].shape; | |
var color = data.molecules[i].color; | |
var spehereX = | |
Math.round(containerWidth / 2 + radius * Math.cos(angle) - sphereRadius / 2) - containerWidth / 2, | |
spehereY = | |
Math.round(containerHeight / 2 + radius * Math.sin(angle) - sphereRadius / 2) - containerHeight / 2; | |
var currMolecule = generateMoleculeGroup(spehereX, spehereY, title, sphereRadius, shape, color); | |
scene.add(currMolecule); | |
angle += step; | |
} | |
function generateMoleculeGroup(spehereX, spehereY, title, sphereRadius, shape, color) { | |
// determining color of molecule | |
switch (color) { | |
case "yellow": | |
var material = new THREE.MeshLambertMaterial({ | |
color: 0xffb200, | |
wireframe: false | |
}); | |
break; | |
case "red": | |
var material = new THREE.MeshLambertMaterial({ | |
color: 0x920a0c, | |
wireframe: false | |
}); | |
break; | |
case "blue": | |
var material = new THREE.MeshLambertMaterial({ | |
color: 0x05859a, | |
wireframe: false | |
}); | |
break; | |
default: | |
var material = new THREE.MeshLambertMaterial({ | |
color: 0xffb200, | |
wireframe: false | |
}); | |
break; | |
} | |
// determining shape | |
switch (shape) { | |
case "polygon": | |
var geometry = new THREE.SphereBufferGeometry( | |
sphereRadius, | |
4, | |
4 | |
); | |
break; | |
case "sphere": | |
var geometry = new THREE.SphereBufferGeometry( | |
sphereRadius, | |
360, | |
360 | |
); | |
break; | |
default: | |
var geometry = new THREE.SphereBufferGeometry( | |
sphereRadius, | |
360, | |
360 | |
); | |
} | |
// creating HTML elements for label | |
var element = document.createElement("div"); | |
element.className = "element"; | |
element.setAttribute("data-count", i); | |
element.style.backgroundColor = "rgba(255,255,255,0)"; | |
element.addEventListener("click", function() { | |
var attribute = this.getAttribute("data-count"); | |
alert(attribute); | |
}); | |
var label = document.createElement("div"); | |
label.className = "label"; | |
label.textContent = title; | |
element.appendChild(label); | |
var labelObject = new THREE.CSS3DObject(element); | |
labelObject.position.x = spehereX + 200; | |
labelObject.position.y = spehereY; | |
labelObject.position.z = 0; | |
// creating sphere | |
var sphereObject = new THREE.Mesh(geometry, material); | |
sphereObject.name = title; | |
scene.add(sphereObject); | |
sphereObject.position.x = spehereX; | |
sphereObject.position.y = spehereY; | |
sphereObject.position.z = 0; | |
// grouping elements | |
var moleculeGroup = new THREE.Group(); | |
moleculeGroup.add(sphereObject); | |
moleculeGroup.add(labelObject); | |
objects.push(moleculeGroup); | |
return moleculeGroup; | |
// scene.add(moleculeGroup); | |
//adding grouping to array to keep track | |
} | |
////////// Lights ////////// | |
var directionalLight = new THREE.DirectionalLight("white", 0.125); | |
directionalLight.position.set(2.6, 1, 3); | |
directionalLight.name = "Back light"; | |
scene.add(directionalLight); | |
var ambientLight = new THREE.AmbientLight(0xffffff, 1); | |
scene.add(ambientLight); | |
var spotlight = new THREE.SpotLight(0xffd500, 0.5); | |
spotlight.position.set(100, 1000, 1000); | |
scene.add(spotlight); | |
var geometry = new THREE.SphereGeometry(10, 12, 12); | |
var material = new THREE.MeshBasicMaterial({ color: 0xfffff, wireframe: true }); | |
var spherespotlight = new THREE.Mesh(geometry, material); | |
spherespotlight.position.set( | |
spotlight.position.x, | |
spotlight.position.y, | |
spotlight.position.z | |
); | |
scene.add(spherespotlight); | |
var update = function() { | |
for (var y = 0; y < objects.length; y++) { | |
objects[y].children[0].rotation.x += 0.01; | |
objects[y].children[0].rotation.y += 0.005; | |
} | |
}; | |
var render = function() { | |
renderer.render(scene, camera); | |
renderer2.render(scene, camera); | |
}; | |
var animate = function() { | |
requestAnimationFrame(animate); | |
controls.update(); | |
update(); | |
render(); | |
}; | |
animate(); | |
//////////////////////////////////////// | |
TweenLite.ticker.addEventListener('tick', render ); | |
var timeline = new TimelineLite({ | |
onStart: function(){ | |
TweenLite.ticker.removeEventListener("tick", controls.update ); | |
controls.enabled = false; | |
}, | |
onComplete: function(){ | |
TweenLite.ticker.addEventListener("tick", controls.update ); | |
controls.position0.copy(camera.position); | |
controls.reset(); | |
controls.enabled = true; | |
} | |
}); | |
easing = 'Expo.easeInOut'; | |
//////////////////////////////////////// | |
camera.reset = function(){ | |
var pos = { x: 0, y: 0 }; | |
var distance = 9000; | |
var speed = 1; | |
if ( camera.parent !== scene ) { | |
var pos = camera.position.clone(); | |
camera.parent.localToWorld(camera.position); | |
scene.add(camera); | |
} | |
timeline.clear(); | |
timeline.to( camera.position, speed, { | |
x: pos.x, | |
y: pos.y, | |
z: distance, | |
ease: easing | |
}, 0); | |
timeline.to( camera.rotation, speed, { x: 0, y: 0, z: 0, ease: easing}, 0); | |
}; | |
//////////////////////////////////////// | |
camera.getDistance = function(object) { | |
var box = new THREE.Box3(); | |
var size = new THREE.Vector3(); | |
box.setFromObject(object); | |
box.getSize(size); | |
// var helper = new THREE.BoundingBoxHelper(object, 0xff0000); | |
// scene.add(helper); | |
// helper.update(); | |
// box3.setFromObject(helper); | |
var width = size.x, | |
height = size.y; | |
// Set camera distance | |
var vFOV = camera.fov * Math.PI / 180, | |
ratio = 2 * Math.tan( vFOV / 2 ), | |
screen = ratio * camera.aspect, //( renderer.domElement.width / renderer.domElement.height ), | |
size = Math.max(height,width), | |
distance = size / screen + box.max.z / screen * 1.1; | |
return distance; | |
}; | |
//////////////////////////////////////// | |
camera.zoom = function(object){ | |
console.log(camera.getDistance(object)); | |
var pos = camera.position.clone(); | |
object.worldToLocal(camera.position); | |
object.add(camera); | |
var speed = 1; | |
timeline.clear(); | |
timeline.to( camera.position, speed, { | |
x: pos.x, | |
y: pos.y, | |
z: camera.getDistance(object), | |
ease: easing | |
},0); | |
}; | |
//////////////////////////////////////// | |
var startX, startY, | |
$target = $(renderer.domElement), | |
selected; | |
function mouseUp(e) { | |
e.preventDefault(); | |
var x = ( e.touches ? e.touches[0].clientX : e.clientX ), | |
y = ( e.touches ? e.touches[0].clientY : e.clientY ), | |
diff = Math.max(Math.abs(startX - x), Math.abs(startY - y)); | |
if ( diff > 40 ) { return; } | |
var mouse = { | |
x: ( x / window.innerWidth ) * 2 - 1, | |
y: - ( y / window.innerHeight ) * 2 + 1 | |
}; | |
var vector = new THREE.Vector3( mouse.x, mouse.y ).unproject( camera ); | |
var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() ); | |
var intersects = raycaster.intersectObject( scene, true ); | |
if ( intersects.length > 0 && intersects[ 0 ].object !== selected ) { | |
selected = intersects[ 0 ].object; | |
camera.zoom(selected); | |
} else { | |
selected = null; | |
camera.reset(); | |
} | |
} | |
function mouseDown( e ) { | |
e = e.originalEvent || e; | |
startX = ( e.touches ? e.touches[0].clientX : e.clientX ); | |
startY = ( e.touches ? e.touches[0].clientY : e.clientY ); | |
$target.one('mouseup touchend', mouseUp ); | |
setTimeout(function(){ $target.off('mouseup.part touchend.part'); },300); | |
} | |
$target.on('mousedown touchend', mouseDown ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/102/three.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.5/TweenMax.min.js"></script> | |
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script> | |
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script> | |
<script src="https://threejs.org/examples/js/renderers/CSS3DRenderer.js"></script> | |
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/65844/data.json"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, | |
body { | |
height: 100%; | |
} | |
body { | |
background-color #000; | |
margin: 0; | |
font-family: Helvetica, sans-serif; | |
overflow: hidden; | |
} | |
* { | |
box-sizing: border-box; | |
} | |
#container { | |
position: relative; | |
width: 100%; | |
/* left: -50%; */ | |
background: transparent; | |
} | |
.element { | |
position: relative; | |
display: block; | |
width: 260px; | |
height: 100%; | |
max-height: 80px; | |
background-color: white; | |
/* box-shadow: 0px 0px 12px rgba(0, 255, 255, 0.5); */ | |
/* border: 1px solid rgba(127, 255, 255, 0.25); */ | |
text-align: left; | |
cursor: pointer; | |
} | |
.element:before { | |
content: ''; | |
position: absolute; | |
display: flex; | |
z-index: 0; | |
top: 0; | |
left: 0; | |
background: rgba(255, 255, 255, 0.9); | |
width: 100%; | |
height: 100%; | |
} | |
.element:after { | |
content: ''; | |
position: absolute; | |
z-index: 5; | |
width: 20px; | |
height: 20px; | |
background-color: #ffd500 | |
} | |
.element .label { | |
position: absolute; | |
z-index: 10; | |
font-size: 24px; | |
font-weight: bold; | |
color: rgba(89, 89, 89, 1); | |
margin: 0px 20px; | |
padding: 0px 20px; | |
top: 50%; | |
transform: translateY(-50%); | |
} | |
.element:hover { | |
box-shadow: 0px 0px 12px rgba(0, 255, 255, 0.75); | |
border: 1px solid rgba(127, 255, 255, 0.75); | |
} | |
.element .details { | |
position: absolute; | |
bottom: 15px; | |
left: 0px; | |
right: 0px; | |
font-size: 12px; | |
color: rgba(127, 255, 255, 0.75); | |
} | |
.descrition_container { | |
position: absolute; | |
top: 50%; | |
right: 20px; | |
max-width: 380px; | |
background-color: white; | |
box-shadow: 0px 5px 30px 4px rgba(0,0,0,0.16); | |
transition: all ease 0.5s; | |
transform: translateX(110%) translateY(-50%); | |
} | |
.description_title { | |
padding: 0 30px; | |
margin: 18px 0 0; | |
} | |
h2 { | |
font-family: Arial, Helvetica, sans-serif; | |
font-size: 36px; | |
line-height: 48px; | |
font-weight: bold; | |
color: rgba(0, 158, 180, 1); | |
margin: 0px; | |
padding: 0px; | |
} | |
h3 { | |
font-family: Arial, Helvetica, sans-serif; | |
font-size: 20px; | |
font-weight: bold; | |
color: rgba(0, 158, 180, 1); | |
padding: 0 30px; | |
} | |
.description_details { | |
font-family: Arial, Helvetica, sans-serif; | |
color: rgba(89, 89, 89, 1); | |
font-size: 16px; | |
line-height: 20px; | |
margin: 0px 0 18px; | |
padding: 0 30px; | |
} | |
.button_cta { | |
position: relative; | |
display: block; | |
width: 100%; | |
font-family: Arial, Helvetica, sans-serif; | |
color: white; | |
font-size: 20px; | |
font-weight: bold; | |
background-color: rgba(0, 158, 180, 1); | |
margin: 0px 0; | |
padding: 16px 30px; | |
text-decoration: none; | |
text-align: center; | |
transition: all ease 0.25s; | |
cursor: pointer; | |
} | |
.button_cta:hover { | |
background-color: rgba(5, 96, 99, 1.00); | |
} | |
ul { | |
list-style: none; | |
margin: 0; | |
padding: 0; | |
display: flex; | |
flex-direction: column; | |
justify-content: flex-start | |
} | |
ul li { | |
position: relative; | |
padding: 16px 30px; | |
width: 100%; | |
font-family: Arial, Helvetica, sans-serif; | |
color: rgba(89, 89, 89, 1); | |
font-size: 16px; | |
border-top: 1px solid rgba(208, 208, 208, 1); | |
} | |
ul li:last-child { | |
border-bottom: 1px solid rgba(208, 208, 208, 1) | |
} | |
ul li a { | |
color: rgba(89, 89, 89, 1); | |
text-decoration: none; | |
} | |
ul li a:hover { | |
color: rgba(5, 96, 99, 1.00); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment