Foundational Code : Stepping Squares 

<!DOCTYPE html>

<html lang="en">

<head>

<title>Stepping Squares</title>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

<style>

body {

margin: 0px;

}

 

body {

background-color: #ffffff;

color: #fd7272;

font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;

}

 

a {

color: #9656bb;

}

 

button {

background-color:transparent;

border: none;

color: rgb(250, 244, 244);

padding: 11px 32px;

text-align: center;

text-decoration: none;

display:transparent;

font-size: 14px;

letter-spacing: 2px;

margin: px 2px;

cursor: pointer;

font: 11px 'Lucida Grande', sans-serif;

}

 

#info {

position: absolute;

top: 0px;

width: 100%;

padding: 1opx;

font: 11px 'Lucida Grande', sans-serif;

}

 

button:hover {

background-color: rgb(255, 51, 0);

color: rgb(255, 208, 0);

}

 

.buttonsgroup > div {

display: inline-block;

*display: inline; /* For IE7 */

zoom: 1; /* Trigger hasLayout */

width: 33%;

text-align: center;

}

#container {

 

width: 100%;

bottom: 0px;

}

 

</style>

</head>

<body>

 

<div id="info" class="buttonsgroup">

<div><button id="openFullscreen">Expand</button></div>

<div>Stepping Squares</div>

<div><button id="soundButton">Sound</button></div>

</div>

 

<div id="container"></div>

<audio loop id="music" preload="auto" style="display: none">

<source src="sound/RecordingLayeredEdit1.mp3" type="audio/mpeg">

</audio>

 

<script type="module">

 

import * as THREE from './threelib/three.module.js';

 

import { FirstPersonControls } from './threelib/FirstPersonControls.js';

import { ImprovedNoise } from './threelib/ImprovedNoise.js';

import { PositionalAudioHelper } from './threelib/PositionalAudioHelper.js';

 

let container, stats;

let camera, controls, scene, renderer, group;

let mesh, texture, material, geometry, SphereGeometry, posCount, meshHeight, meshWidth, timeToMove;

let currObjNum = 0;

let positionalAudio, listener, audioElement, helper;

 

const worldWidth = 456, worldDepth = 456;

const clock = new THREE.Clock();

 

init();

animate();

 

/* Get the documentElement (<html>) to display the page in fullscreen */

var elem = document.documentElement;

 

/* View in fullscreen */

function openFullscreen() {

if (elem.requestFullscreen) {

elem.requestFullscreen();

} else if (elem.webkitRequestFullscreen) { /* Safari */

elem.webkitRequestFullscreen();

} else if (elem.msRequestFullscreen) { /* IE11 */

elem.msRequestFullscreen();

}

}

 

const startButton = document.getElementById( 'openFullscreen' );

startButton.addEventListener( 'click', openFullscreen );

 

const soundButton = document.getElementById( 'soundButton' );

soundButton.addEventListener( 'click', initSound );

 

function initSound() {

 

listener = new THREE.AudioListener();

camera.add( listener );

 

audioElement = document.getElementById( 'music' );

audioElement.play();

}

 

function init() {

 

container = document.getElementById( 'container' );

 

camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 10000 );

 

scene = new THREE.Scene();

scene.background = new THREE.Color( 0xff3300 );

scene.fog = new THREE.FogExp2( 0xff3300, 0.0013 );

 

group = new THREE.Group();

//scene.add( group );

 

const data = generateHeight( worldWidth, worldDepth );

 

camera.position.set( 0, 1000, - 0 );

camera.rotation.y = 2.5;

//camera.lookAt( - 100, 810, - 800 );

 

const geometry = new THREE.PlaneBufferGeometry( 15000, 15000, worldWidth - 1, worldDepth - 2 );

geometry.rotateX( - Math.PI / 2 );

 

const vertices = geometry.attributes.position.array;

 

for ( let i = 0, j = 0, l = vertices.length; i < l; i ++, j += 3 ) {

 

vertices[ j + 1 ] = data[ i ] * 10;

 

}

 

texture = new THREE.CanvasTexture( generateTexture( data, worldWidth, worldDepth ) );

texture.wrapS = THREE.ClampToEdgeWrapping;

texture.wrapT = THREE.ClampToEdgeWrapping;

 

mesh = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { map: texture } ) );

scene.add( mesh );

 

renderer = new THREE.WebGLRenderer();

renderer.setPixelRatio( window.devicePixelRatio );

renderer.setSize( window.innerWidth, window.innerHeight );

container.appendChild( renderer.domElement );

 

controls = new FirstPersonControls( camera, group, renderer.domElement );

controls.movementSpeed = 150;

controls.lookSpeed = 0.1;

 

posCount = 0;

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

addPaintingHexZm (0xff0f7da);

 

window.addEventListener( 'resize', onWindowResize );

}

function addPaintingHexZm( hex ) {

var geometry, material, texture, mesh, offset, yRotation, randomx;

posCount = posCount + 1;

randomx = Math.random();

offset = posCount / 1;

offset = posCount - offset.toFixed(0) * 1;

if (offset == 0) {

offset = 1;

yRotation = -1.5;

} else {

offset = -1;

yRotation = 1.5;

}

meshHeight = 30 + 30 * Math.random();

meshWidth = 30 + 30 * Math.random();

material = new THREE.MeshBasicMaterial({

color: hex

});

//new THREE.MeshBasicMaterial( { color: 0x9656bb, transparent: true, blending: THREE.AdditiveBlending } );

geometry = new THREE.BoxBufferGeometry( meshHeight, meshWidth, 0.5 );

mesh = new THREE.Mesh(geometry, material);

 

mesh.position.y = 800;

mesh.position.x = 70 * offset * randomx;

mesh.position.z = 100 * posCount;

//mesh.rotation.y = - yRotation * randomx;

mesh.rotation.x = 1.5;

mesh.name = 'picture';

scene.add(mesh);

if (posCount == 25) {

// if (posCount == 25 || posCount == 35) {

geometry = new THREE.SphereGeometry( meshHeight/4, 60, 30 );

material = new THREE.MeshBasicMaterial( { color: 0xffaa00, transparent: true, blending: THREE.AdditiveBlending } );

//new THREE.MeshBasicMaterial( {

//color: 0x000000 } );

SphereGeometry = new THREE.Mesh(geometry, material);

if (posCount == 25) {

SphereGeometry = new THREE.Mesh(geometry, material);

}

meshHeight = 1 + 1 * Math.random();

meshWidth = 1 + 1 * Math.random();

mesh.position.y = 840;

mesh.position.z = 100 * posCount;

scene.add(SphereGeometry);

 

//SphereGeometry = new THREE.SphereGeometry

 

SphereGeometry.getNextObj = function () {

var sec = (2000);

var secInterval = 1 * sec;

const timer = Date.now();

if (timeToMove === undefined) {timeToMove = timer + 1 * sec;}

if (timeToMove < timer) {

timeToMove = timer + secInterval;

var obj;

while (true) {

currObjNum = currObjNum + 1;

if (currObjNum == scene.children.length) {

currObjNum = 0;

}

obj = scene.children[currObjNum];

if (obj.name == 'picture') {

break;

}

}

 

var vector = new THREE.Vector3();

obj.getWorldDirection( vector );

 

SphereGeometry.lastPosition = SphereGeometry.position;

SphereGeometry.nextPosition = new THREE.Vector3();

SphereGeometry.nextPosition.x = obj.position.x - vector.x*20;

SphereGeometry.nextPosition.y = obj.position.y - vector.y*20;

SphereGeometry.nextPosition.z = obj.position.z - vector.z*20;

SphereGeometry.dist = SphereGeometry.position.distanceTo(SphereGeometry.nextPosition);

//console.log(dist);

 

} else {

if (SphereGeometry.nextPosition) {

var vector = new THREE.Vector3();

vector.x = SphereGeometry.nextPosition.x - SphereGeometry.position.x;

vector.y = SphereGeometry.nextPosition.y - SphereGeometry.position.y;

vector.z = SphereGeometry.nextPosition.z - SphereGeometry.position.z;

var currDist = SphereGeometry.position.distanceTo(SphereGeometry.nextPosition);

var remainingTime = timeToMove - timer;

remainingTime = 1 - remainingTime / secInterval;

var remainingDist = currDist / SphereGeometry.dist;

//console.log(remainingTime);

SphereGeometry.position.x = SphereGeometry.position.x + vector.x * remainingTime;

SphereGeometry.position.y = SphereGeometry.position.y + vector.y * remainingTime;

SphereGeometry.position.z = SphereGeometry.position.z + vector.z * remainingTime;

}

}

}

}

}

 

posCount = 0;

addPainting ('image/Untitled_Artwork7.jpg');

 

function addPainting( src ) {

var tex;

const callbackPainting = function (t) {

tex.needsUpdate = true;

var geometry, material, texture, mesh, offset, yRotation, randomx;

texture = tex;

posCount = posCount + 1;

randomx = Math.random();

offset = posCount / 2;

offset = posCount - offset.toFixed(0) * 2;

if (offset == 0) {

offset = 1;

yRotation = -1.5;

} else {

offset = -1;

yRotation = 1.5;

}

meshHeight = texture.image.height;

meshWidth = texture.image.width;

//geometry = new THREE.PlaneGeometry(40, 40);

material = new THREE.MeshBasicMaterial({

roughness: 0,

color: 0xffffff,

map: texture

});

 

geometry = new THREE.BoxBufferGeometry( 120, 120, 1 );

 

mesh = new THREE.Mesh(geometry, material);

mesh.scale.set(1.0, meshHeight / meshWidth, 1.0);

mesh.position.y = 950;

mesh.position.x = 70 * offset * randomx;

mesh.position.z = 6700 * posCount;

//mesh.rotation.y = - yRotation * randomx;

scene.add(mesh);

};

tex = new THREE.TextureLoader().load( src, callbackPainting );

}


 

function onWindowResize() {

 

camera.aspect = window.innerWidth / window.innerHeight;

camera.updateProjectionMatrix();

 

renderer.setSize( window.innerWidth, window.innerHeight );

 

controls.handleResize();

 

}

 

function generateHeight( width, height ) {

 

let seed = Math.PI / 4;

window.Math.random = function () {

 

const x = Math.sin( seed ++ ) * 10000;

return x - Math.floor( x );

 

};

 

const size = width * height, data = new Uint8Array( size );

const perlin = new ImprovedNoise(), z = Math.random() * 100;

 

let quality = 1;

 

for ( let j = 0; j < 4; j ++ ) {

 

for ( let i = 0; i < size; i ++ ) {

 

const x = i % width, y = ~ ~ ( i / width );

data[ i ] += Math.abs( perlin.noise( x / quality, y / quality, z ) * quality * 1.75 );

 

}

 

quality *= 5;

 

}

 

return data;

 

}

 

function generateTexture( data, width, height ) {

 

let context, image, imageData, shade;

 

const vector3 = new THREE.Vector3( 0, 0, 0 );

 

const sun = new THREE.Vector3( 1, 1, 1 );

sun.normalize();

 

const canvas = document.createElement( 'canvas' );

canvas.width = width;

canvas.height = height;

 

context = canvas.getContext( '2d' );

context.fillStyle = '0xffffff';

context.fillRect( 0, 0, width, height );

 

image = context.getImageData( 0, 0, canvas.width, canvas.height );

imageData = image.data;

 

for ( let i = 0, j = 0, l = imageData.length; i < l; i += 4, j ++ ) {

 

vector3.x = data[ j - 2 ] - data[ j + 2 ];

vector3.y = 2;

vector3.z = data[ j - width * 2 ] - data[ j + width * 2 ];

vector3.normalize();

 

shade = vector3.dot( sun );

 

imageData[ i ] = ( 133 + shade * 128 ) * ( 0.5 + data[ j ] * 0.007 );

imageData[ i + 1 ] = ( 84 + shade * 76 ) * ( 0.5 + data[ j ] * 0.007 );

imageData[ i + 2 ] = ( 197 + shade ) * ( 0.5 + data[ j ] * 0.007 );

 

}

 

context.putImageData( image, 0, 0 );

 

// Scaled 4x

 

const canvasScaled = document.createElement( 'canvas' );

canvasScaled.width = width * 4;

canvasScaled.height = height * 4;

 

context = canvasScaled.getContext( '2d' );

context.scale( 4, 4 );

context.drawImage( canvas, 0, 0 );

 

image = context.getImageData( 0, 0, canvasScaled.width, canvasScaled.height );

imageData = image.data;

 

for ( let i = 0, l = imageData.length; i < l; i += 4 ) {

 

const v = ~ ~ ( Math.random() * 5 );

 

imageData[ i ] += v;

imageData[ i + 1 ] += v;

imageData[ i + 2 ] += v;

 

}

 

context.putImageData( image, 0, 0 );

 

return canvasScaled;

 

}

 

//

 

function animate() {

 

requestAnimationFrame( animate );

 

render();

 

}


 

function render() {

 

const time = performance.now() * 0.001;

 

if (SphereGeometry) {SphereGeometry.getNextObj();}

 

controls.update( clock.getDelta() );

renderer.render( scene, camera );

 

}

 

</script>

 

</body>

</html>