Running woman
A woman runs through a mysterious forest.
by realhunts
HTML
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://threejs.org/examples/js/loaders/GLTFLoader.js"></script>
<!-- Audio from https://freesound.org/people/arnaud%20coutancier/sounds/271323/
Lincenced under Attribution-NonCommercial 3.0 Unported (CC BY-NC 3.0)
-->
<audio loop id="ambient" preload="auto" style="display: none">
<source src="https://yume.human-interactive.org/examples/forest/run.ogg" type="audio/ogg">
</audio>
<section id="loading-screen">
<div id="loader"></div>
</section>
<div id="start-screen">
<button id="start" type="button">Start Demo</button>
</div>
CSS
html, body {
overflow: hidden;
margin: 0;
width: 100%;
height: 100%;
}
#loading-screen {
position: absolute;
z-index: 2;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #000000;
opacity: 1;
transition: 1s opacity;
}
#loading-screen.fade-out {
opacity: 0;
}
#start-screen {
position: absolute;
z-index: 1;
top: 0;
left: 0;
width: 100%;
height:100%;
display: flex;
align-items: center;
justify-content: center;
opacity: 1;
transition: 1s opacity;
background-color: #000000;
}
#start-screen.fade-out {
opacity: 0;
}
#start-screen > button {
height: 20px;
width: 100px;
color: #9370DB;
background: transparent;
outline: 1px solid #9370DB;
border: 0px;
cursor: pointer;
}
/* CSS from http://freefrontend.com/css-loaders/ */
#loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #9370DB;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
#loader:before {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #BA55D3;
-webkit-animation: spin 3s linear infinite;
animation: spin 3s linear infinite;
}
#loader:after {
content: "";
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FF00FF;
-webkit-animation: spin 1.5s linear infinite;
animation: spin 1.5s linear infinite;
}
@-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform:...
JavaScript
// ported from http://oos.moxiecode.com/js_webgl/forest/index.html
let camera, cameraTarget, scene, renderer, clock, textureLoader, glTFLoader;
let ground1, ground2;
let particles1, particles2;
const trees = new Set();
const rocks = new Set();
const flowers = new Set();
let r = 0;
init();
function init() {
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 100000 );
cameraTarget = new THREE.Vector3( 0, 0, - 400 );
clock = new THREE.Clock();
scene = new THREE.Scene();
scene.background = new THREE.Color( 0x473768 );
scene.fog = new THREE.FogExp2( 0x473768, 0.0008 );
//
const loadingManager = new THREE.LoadingManager( onLoad );
textureLoader = new THREE.TextureLoader( loadingManager );
glTFLoader = new THREE.GLTFLoader( loadingManager );
// setup scene
addGround();
addTrees();
addRocks();
addFlowers();
addMoon();
addCloud();
addParticles()
//
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
//
window.addEventListener( 'resize', onWindowResize, false );
//
const startButton = document.getElementById( 'start' );
startButton.addEventListener( 'click', onStart, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate() {
requestAnimationFrame( animate );
const delta = clock.getDelta();
run( delta );
renderer.render( scene, camera );
}
function run( delta ) {
const speed = delta * 700;
r += delta / 2;
// animate camera
camera.position.x = 20 * Math.cos( r * 2 );
camera.position.y = 10 * Math.sin( r * 30 ) - 150;
cameraTarget.x = 5 * Math.sin( r );
cameraTarget.y =...