Published
Edited
Mar 27, 2019
Insert cell
Insert cell
THREE = require("https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.js")
Insert cell
TWEEN = require("https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.4/TweenMax.min.js")



Insert cell
$ = require ("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js")
Insert cell
TweenMax = require("https://cdnjs.cloudflare.com/ajax/libs/gsap/1.11.5/TweenMax.min.js")
Insert cell
function showResume() {
$(".hero__content > h1").animate({'opacity':1},1000);
$(".hero__content > p").animate({'opacity':1},1000);
}
Insert cell
function hideTextBoxes() {
$('#skills-text').animate({'opacity':0},500);
$('#education-text').animate({'opacity':0},500);
console.log("hideTextBoxes")
}

Insert cell
function fadeInSkills(e){
$('#skills-text').css("display","");
$('#skills-text').animate({'opacity':1},1000,()=>{


})
$('#education-text').animate({'opacity':0},1000);
}

Insert cell


function isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
}





Insert cell

function fadeInEdu(e){
if(isMobile()){
$('#skills-text').css("display","none")
}else {
$('#skills-text').css("display","visible")
}
$('#skills-text').animate({'opacity':0},1000,(el)=>{


});


$('#education-text').animate({'opacity':1},1000);
}

Insert cell
THREE.OBJLoader = null
Insert cell
/**
* @author mrdoob / http://mrdoob.com/
*/

THREE.OBJLoader = ( function () {

// o object_name | g group_name
var object_pattern = /^[og]\s*(.+)?/;
// mtllib file_reference
var material_library_pattern = /^mtllib /;
// usemtl material_name
var material_use_pattern = /^usemtl /;

function ParserState() {

var state = {
objects: [],
object: {},

vertices: [],
normals: [],
colors: [],
uvs: [],

materialLibraries: [],

startObject: function ( name, fromDeclaration ) {

// If the current object (initial from reset) is not from a g/o declaration in the parsed
// file. We need to use it for the first parsed g/o to keep things in sync.
if ( this.object && this.object.fromDeclaration === false ) {

this.object.name = name;
this.object.fromDeclaration = ( fromDeclaration !== false );
return;

}

var previousMaterial = ( this.object && typeof this.object.currentMaterial === 'function' ? this.object.currentMaterial() : undefined );

if ( this.object && typeof this.object._finalize === 'function' ) {

this.object._finalize( true );

}

this.object = {
name: name || '',
fromDeclaration: ( fromDeclaration !== false ),

geometry: {
vertices: [],
normals: [],
colors: [],
uvs: []
},
materials: [],
smooth: true,

startMaterial: function ( name, libraries ) {

var previous = this._finalize( false );

// New usemtl declaration overwrites an inherited material, except if faces were declared
// after the material, then it must be preserved for proper MultiMaterial continuation.
if ( previous && ( previous.inherited || previous.groupCount <= 0 ) ) {

this.materials.splice( previous.index, 1 );

}

var material = {
index: this.materials.length,
name: name || '',
mtllib: ( Array.isArray( libraries ) && libraries.length > 0 ? libraries[ libraries.length - 1 ] : '' ),
smooth: ( previous !== undefined ? previous.smooth : this.smooth ),
groupStart: ( previous !== undefined ? previous.groupEnd : 0 ),
groupEnd: - 1,
groupCount: - 1,
inherited: false,

clone: function ( index ) {

var cloned = {
index: ( typeof index === 'number' ? index : this.index ),
name: this.name,
mtllib: this.mtllib,
smooth: this.smooth,
groupStart: 0,
groupEnd: - 1,
groupCount: - 1,
inherited: false
};
cloned.clone = this.clone.bind( cloned );
return cloned;

}
};

this.materials.push( material );

return material;

},

currentMaterial: function () {

if ( this.materials.length > 0 ) {

return this.materials[ this.materials.length - 1 ];

}

return undefined;

},

_finalize: function ( end ) {

var lastMultiMaterial = this.currentMaterial();
if ( lastMultiMaterial && lastMultiMaterial.groupEnd === - 1 ) {

lastMultiMaterial.groupEnd = this.geometry.vertices.length / 3;
lastMultiMaterial.groupCount = lastMultiMaterial.groupEnd - lastMultiMaterial.groupStart;
lastMultiMaterial.inherited = false;

}

// Ignore objects tail materials if no face declarations followed them before a new o/g started.
if ( end && this.materials.length > 1 ) {

for ( var mi = this.materials.length - 1; mi >= 0; mi -- ) {

if ( this.materials[ mi ].groupCount <= 0 ) {

this.materials.splice( mi, 1 );

}

}

}

// Guarantee at least one empty material, this makes the creation later more straight forward.
if ( end && this.materials.length === 0 ) {

this.materials.push( {
name: '',
smooth: this.smooth
} );

}

return lastMultiMaterial;

}
};

// Inherit previous objects material.
// Spec tells us that a declared material must be set to all objects until a new material is declared.
// If a usemtl declaration is encountered while this new object is being parsed, it will
// overwrite the inherited material. Exception being that there was already face declarations
// to the inherited material, then it will be preserved for proper MultiMaterial continuation.

if ( previousMaterial && previousMaterial.name && typeof previousMaterial.clone === 'function' ) {

var declared = previousMaterial.clone( 0 );
declared.inherited = true;
this.object.materials.push( declared );

}

this.objects.push( this.object );

},

finalize: function () {

if ( this.object && typeof this.object._finalize === 'function' ) {

this.object._finalize( true );

}

},

parseVertexIndex: function ( value, len ) {

var index = parseInt( value, 10 );
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;

},

parseNormalIndex: function ( value, len ) {

var index = parseInt( value, 10 );
return ( index >= 0 ? index - 1 : index + len / 3 ) * 3;

},

parseUVIndex: function ( value, len ) {

var index = parseInt( value, 10 );
return ( index >= 0 ? index - 1 : index + len / 2 ) * 2;

},

addVertex: function ( a, b, c ) {

var src = this.vertices;
var dst = this.object.geometry.vertices;

dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );

},

addVertexLine: function ( a ) {

var src = this.vertices;
var dst = this.object.geometry.vertices;

dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );

},

addNormal: function ( a, b, c ) {

var src = this.normals;
var dst = this.object.geometry.normals;

dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );

},

addColor: function ( a, b, c ) {

var src = this.colors;
var dst = this.object.geometry.colors;

dst.push( src[ a + 0 ], src[ a + 1 ], src[ a + 2 ] );
dst.push( src[ b + 0 ], src[ b + 1 ], src[ b + 2 ] );
dst.push( src[ c + 0 ], src[ c + 1 ], src[ c + 2 ] );

},

addUV: function ( a, b, c ) {

var src = this.uvs;
var dst = this.object.geometry.uvs;

dst.push( src[ a + 0 ], src[ a + 1 ] );
dst.push( src[ b + 0 ], src[ b + 1 ] );
dst.push( src[ c + 0 ], src[ c + 1 ] );

},

addUVLine: function ( a ) {

var src = this.uvs;
var dst = this.object.geometry.uvs;

dst.push( src[ a + 0 ], src[ a + 1 ] );

},

addFace: function ( a, b, c, ua, ub, uc, na, nb, nc ) {

var vLen = this.vertices.length;

var ia = this.parseVertexIndex( a, vLen );
var ib = this.parseVertexIndex( b, vLen );
var ic = this.parseVertexIndex( c, vLen );

this.addVertex( ia, ib, ic );

if ( ua !== undefined ) {

var uvLen = this.uvs.length;

ia = this.parseUVIndex( ua, uvLen );
ib = this.parseUVIndex( ub, uvLen );
ic = this.parseUVIndex( uc, uvLen );

this.addUV( ia, ib, ic );

}

if ( na !== undefined ) {

// Normals are many times the same. If so, skip function call and parseInt.
var nLen = this.normals.length;
ia = this.parseNormalIndex( na, nLen );

ib = na === nb ? ia : this.parseNormalIndex( nb, nLen );
ic = na === nc ? ia : this.parseNormalIndex( nc, nLen );

this.addNormal( ia, ib, ic );

}

if ( this.colors.length > 0 ) {

this.addColor( ia, ib, ic );

}

},

addLineGeometry: function ( vertices, uvs ) {

this.object.geometry.type = 'Line';

var vLen = this.vertices.length;
var uvLen = this.uvs.length;

for ( var vi = 0, l = vertices.length; vi < l; vi ++ ) {

this.addVertexLine( this.parseVertexIndex( vertices[ vi ], vLen ) );

}

for ( var uvi = 0, l = uvs.length; uvi < l; uvi ++ ) {

this.addUVLine( this.parseUVIndex( uvs[ uvi ], uvLen ) );

}

}

};

state.startObject( '', false );

return state;

}

//

function OBJLoader( manager ) {

this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;

this.materials = null;

}

OBJLoader.prototype = {

constructor: OBJLoader,

load: function ( url, onLoad, onProgress, onError ) {

var scope = this;

var loader = new THREE.FileLoader( scope.manager );
loader.setPath( this.path );
loader.load( url, function ( text ) {

onLoad( scope.parse( text ) );

}, onProgress, onError );

},

setPath: function ( value ) {

this.path = value;

},

setMaterials: function ( materials ) {

this.materials = materials;

return this;

},

parse: function ( text ) {

console.time( 'OBJLoader' );

var state = new ParserState();

if ( text.indexOf( '\r\n' ) !== - 1 ) {

// This is faster than String.split with regex that splits on both
text = text.replace( /\r\n/g, '\n' );

}

if ( text.indexOf( '\\\n' ) !== - 1 ) {

// join lines separated by a line continuation character (\)
text = text.replace( /\\\n/g, '' );

}

var lines = text.split( '\n' );
var line = '', lineFirstChar = '';
var lineLength = 0;
var result = [];

// Faster to just trim left side of the line. Use if available.
var trimLeft = ( typeof ''.trimLeft === 'function' );

for ( var i = 0, l = lines.length; i < l; i ++ ) {

line = lines[ i ];

line = trimLeft ? line.trimLeft() : line.trim();

lineLength = line.length;

if ( lineLength === 0 ) continue;

lineFirstChar = line.charAt( 0 );

// @todo invoke passed in handler if any
if ( lineFirstChar === '#' ) continue;

if ( lineFirstChar === 'v' ) {

var data = line.split( /\s+/ );

switch ( data[ 0 ] ) {

case 'v':
state.vertices.push(
parseFloat( data[ 1 ] ),
parseFloat( data[ 2 ] ),
parseFloat( data[ 3 ] )
);
if ( data.length === 8 ) {

state.colors.push(
parseFloat( data[ 4 ] ),
parseFloat( data[ 5 ] ),
parseFloat( data[ 6 ] )

);

}
break;
case 'vn':
state.normals.push(
parseFloat( data[ 1 ] ),
parseFloat( data[ 2 ] ),
parseFloat( data[ 3 ] )
);
break;
case 'vt':
state.uvs.push(
parseFloat( data[ 1 ] ),
parseFloat( data[ 2 ] )
);
break;

}

} else if ( lineFirstChar === 'f' ) {

var lineData = line.substr( 1 ).trim();
var vertexData = lineData.split( /\s+/ );
var faceVertices = [];

// Parse the face vertex data into an easy to work with format

for ( var j = 0, jl = vertexData.length; j < jl; j ++ ) {

var vertex = vertexData[ j ];

if ( vertex.length > 0 ) {

var vertexParts = vertex.split( '/' );
faceVertices.push( vertexParts );

}

}

// Draw an edge between the first vertex and all subsequent vertices to form an n-gon

var v1 = faceVertices[ 0 ];

for ( var j = 1, jl = faceVertices.length - 1; j < jl; j ++ ) {

var v2 = faceVertices[ j ];
var v3 = faceVertices[ j + 1 ];

state.addFace(
v1[ 0 ], v2[ 0 ], v3[ 0 ],
v1[ 1 ], v2[ 1 ], v3[ 1 ],
v1[ 2 ], v2[ 2 ], v3[ 2 ]
);

}

} else if ( lineFirstChar === 'l' ) {

var lineParts = line.substring( 1 ).trim().split( " " );
var lineVertices = [], lineUVs = [];

if ( line.indexOf( "/" ) === - 1 ) {

lineVertices = lineParts;

} else {

for ( var li = 0, llen = lineParts.length; li < llen; li ++ ) {

var parts = lineParts[ li ].split( "/" );

if ( parts[ 0 ] !== "" ) lineVertices.push( parts[ 0 ] );
if ( parts[ 1 ] !== "" ) lineUVs.push( parts[ 1 ] );

}

}
state.addLineGeometry( lineVertices, lineUVs );

} else if ( ( result = object_pattern.exec( line ) ) !== null ) {

// o object_name
// or
// g group_name

// WORKAROUND: https://bugs.chromium.org/p/v8/issues/detail?id=2869
// var name = result[ 0 ].substr( 1 ).trim();
var name = ( " " + result[ 0 ].substr( 1 ).trim() ).substr( 1 );

state.startObject( name );

} else if ( material_use_pattern.test( line ) ) {

// material

state.object.startMaterial( line.substring( 7 ).trim(), state.materialLibraries );

} else if ( material_library_pattern.test( line ) ) {

// mtl file

state.materialLibraries.push( line.substring( 7 ).trim() );

} else if ( lineFirstChar === 's' ) {

result = line.split( ' ' );

// smooth shading

// @todo Handle files that have varying smooth values for a set of faces inside one geometry,
// but does not define a usemtl for each face set.
// This should be detected and a dummy material created (later MultiMaterial and geometry groups).
// This requires some care to not create extra material on each smooth value for "normal" obj files.
// where explicit usemtl defines geometry groups.
// Example asset: examples/models/obj/cerberus/Cerberus.obj

/*
* http://paulbourke.net/dataformats/obj/
* or
* http://www.cs.utah.edu/~boulos/cs3505/obj_spec.pdf
*
* From chapter "Grouping" Syntax explanation "s group_number":
* "group_number is the smoothing group number. To turn off smoothing groups, use a value of 0 or off.
* Polygonal elements use group numbers to put elements in different smoothing groups. For free-form
* surfaces, smoothing groups are either turned on or off; there is no difference between values greater
* than 0."
*/
if ( result.length > 1 ) {

var value = result[ 1 ].trim().toLowerCase();
state.object.smooth = ( value !== '0' && value !== 'off' );

} else {

// ZBrush can produce "s" lines #11707
state.object.smooth = true;

}
var material = state.object.currentMaterial();
if ( material ) material.smooth = state.object.smooth;

} else {

// Handle null terminated files without exception
if ( line === '\0' ) continue;

throw new Error( 'THREE.OBJLoader: Unexpected line: "' + line + '"' );

}

}

state.finalize();

var container = new THREE.Group();
container.materialLibraries = [].concat( state.materialLibraries );

for ( var i = 0, l = state.objects.length; i < l; i ++ ) {

var object = state.objects[ i ];
var geometry = object.geometry;
var materials = object.materials;
var isLine = ( geometry.type === 'Line' );

// Skip o/g line declarations that did not follow with any faces
if ( geometry.vertices.length === 0 ) continue;

var buffergeometry = new THREE.BufferGeometry();

buffergeometry.addAttribute( 'position', new THREE.Float32BufferAttribute( geometry.vertices, 3 ) );

if ( geometry.normals.length > 0 ) {

buffergeometry.addAttribute( 'normal', new THREE.Float32BufferAttribute( geometry.normals, 3 ) );

} else {

buffergeometry.computeVertexNormals();

}

if ( geometry.colors.length > 0 ) {

buffergeometry.addAttribute( 'color', new THREE.Float32BufferAttribute( geometry.colors, 3 ) );

}

if ( geometry.uvs.length > 0 ) {

buffergeometry.addAttribute( 'uv', new THREE.Float32BufferAttribute( geometry.uvs, 2 ) );

}

// Create materials

var createdMaterials = [];

for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {

var sourceMaterial = materials[ mi ];
var material = undefined;

if ( this.materials !== null ) {

material = this.materials.create( sourceMaterial.name );

// mtl etc. loaders probably can't create line materials correctly, copy properties to a line material.
if ( isLine && material && ! ( material instanceof THREE.LineBasicMaterial ) ) {

var materialLine = new THREE.LineBasicMaterial();
materialLine.copy( material );
material = materialLine;

}

}

if ( ! material ) {

material = ( ! isLine ? new THREE.MeshPhongMaterial() : new THREE.LineBasicMaterial() );
material.name = sourceMaterial.name;

}

material.flatShading = sourceMaterial.smooth ? false : true;

createdMaterials.push( material );

}

// Create mesh

var mesh;

if ( createdMaterials.length > 1 ) {

for ( var mi = 0, miLen = materials.length; mi < miLen; mi ++ ) {

var sourceMaterial = materials[ mi ];
buffergeometry.addGroup( sourceMaterial.groupStart, sourceMaterial.groupCount, mi );

}

mesh = ( ! isLine ? new THREE.Mesh( buffergeometry, createdMaterials ) : new THREE.LineSegments( buffergeometry, createdMaterials ) );

} else {

mesh = ( ! isLine ? new THREE.Mesh( buffergeometry, createdMaterials[ 0 ] ) : new THREE.LineSegments( buffergeometry, createdMaterials[ 0 ] ) );

}

mesh.name = object.name;

container.add( mesh );

}

console.timeEnd( 'OBJLoader' );

return container;

}

};

return OBJLoader;

} )()

Insert cell
/**
* @author mrdoob / http://mrdoob.com/
* @author alteredq / http://alteredqualia.com/
*/

THREE.GeometryUtils = {

// Merge two geometries or geometry and geometry from object (using object's transform)

merge: function ( geometry1, geometry2, materialIndexOffset ) {

console.warn( 'THREE.GeometryUtils: .merge() has been moved to Geometry. Use geometry.merge( geometry2, matrix, materialIndexOffset ) instead.' );

var matrix;

if ( geometry2 instanceof THREE.Mesh ) {

geometry2.matrixAutoUpdate && geometry2.updateMatrix();

matrix = geometry2.matrix;
geometry2 = geometry2.geometry;

}

geometry1.merge( geometry2, matrix, materialIndexOffset );

},

// Get random point in triangle (via barycentric coordinates)
// (uniform distribution)
// http://www.cgafaq.info/wiki/Random_Point_In_Triangle

randomPointInTriangle: function () {

var vector = new THREE.Vector3();

return function ( vectorA, vectorB, vectorC ) {

var point = new THREE.Vector3();

var a = Math.random();
var b = Math.random();

if ( ( a + b ) > 1 ) {

a = 1 - a;
b = 1 - b;

}

var c = 1 - a - b;

point.copy( vectorA );
point.multiplyScalar( a );

vector.copy( vectorB );
vector.multiplyScalar( b );

point.add( vector );

vector.copy( vectorC );
vector.multiplyScalar( c );

point.add( vector );

return point;

};

}(),

// Get random point in face (triangle)
// (uniform distribution)

randomPointInFace: function ( face, geometry ) {

var vA, vB, vC;

vA = geometry.vertices[ face.a ];
vB = geometry.vertices[ face.b ];
vC = geometry.vertices[ face.c ];

return THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC );

},

// Get uniformly distributed random points in mesh
// - create array with cumulative sums of face areas
// - pick random number from 0 to total area
// - find corresponding place in area array by binary search
// - get random point in face

randomPointsInGeometry: function ( geometry, n ) {

var face, i,
faces = geometry.faces,
vertices = geometry.vertices,
il = faces.length,
totalArea = 0,
cumulativeAreas = [],
vA, vB, vC;

// precompute face areas

for ( i = 0; i < il; i ++ ) {

face = faces[ i ];

vA = vertices[ face.a ];
vB = vertices[ face.b ];
vC = vertices[ face.c ];

face._area = THREE.GeometryUtils.triangleArea( vA, vB, vC );

totalArea += face._area;

cumulativeAreas[ i ] = totalArea;

}

// binary search cumulative areas array

function binarySearchIndices( value ) {

function binarySearch( start, end ) {

// return closest larger index
// if exact number is not found

if ( end < start )
return start;

var mid = start + Math.floor( ( end - start ) / 2 );

if ( cumulativeAreas[ mid ] > value ) {

return binarySearch( start, mid - 1 );

} else if ( cumulativeAreas[ mid ] < value ) {

return binarySearch( mid + 1, end );

} else {

return mid;

}

}

var result = binarySearch( 0, cumulativeAreas.length - 1 );
return result;

}

// pick random face weighted by face area

var r, index,
result = [];

var stats = {};

for ( i = 0; i < n; i ++ ) {

r = Math.random() * totalArea;

index = binarySearchIndices( r );

result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry );

if ( ! stats[ index ] ) {

stats[ index ] = 1;

} else {

stats[ index ] += 1;

}

}

return result;

},

randomPointsInBufferGeometry: function ( geometry, n ) {

var i,
vertices = geometry.attributes.position.array,
totalArea = 0,
cumulativeAreas = [],
vA, vB, vC;

// precompute face areas
vA = new THREE.Vector3();
vB = new THREE.Vector3();
vC = new THREE.Vector3();

// geometry._areas = [];
var il = vertices.length / 9;

for ( i = 0; i < il; i ++ ) {

vA.set( vertices[ i * 9 + 0 ], vertices[ i * 9 + 1 ], vertices[ i * 9 + 2 ] );
vB.set( vertices[ i * 9 + 3 ], vertices[ i * 9 + 4 ], vertices[ i * 9 + 5 ] );
vC.set( vertices[ i * 9 + 6 ], vertices[ i * 9 + 7 ], vertices[ i * 9 + 8 ] );

totalArea += THREE.GeometryUtils.triangleArea( vA, vB, vC );

cumulativeAreas.push( totalArea );

}

// binary search cumulative areas array

function binarySearchIndices( value ) {

function binarySearch( start, end ) {

// return closest larger index
// if exact number is not found

if ( end < start )
return start;

var mid = start + Math.floor( ( end - start ) / 2 );

if ( cumulativeAreas[ mid ] > value ) {

return binarySearch( start, mid - 1 );

} else if ( cumulativeAreas[ mid ] < value ) {

return binarySearch( mid + 1, end );

} else {

return mid;

}

}

var result = binarySearch( 0, cumulativeAreas.length - 1 );
return result;

}

// pick random face weighted by face area

var r, index,
result = [];

for ( i = 0; i < n; i ++ ) {

r = Math.random() * totalArea;

index = binarySearchIndices( r );

// result[ i ] = THREE.GeometryUtils.randomPointInFace( faces[ index ], geometry, true );
vA.set( vertices[ index * 9 + 0 ], vertices[ index * 9 + 1 ], vertices[ index * 9 + 2 ] );
vB.set( vertices[ index * 9 + 3 ], vertices[ index * 9 + 4 ], vertices[ index * 9 + 5 ] );
vC.set( vertices[ index * 9 + 6 ], vertices[ index * 9 + 7 ], vertices[ index * 9 + 8 ] );
result[ i ] = THREE.GeometryUtils.randomPointInTriangle( vA, vB, vC );

}

return result;

},

// Get triangle area (half of parallelogram)
// http://mathworld.wolfram.com/TriangleArea.html

triangleArea: function () {

var vector1 = new THREE.Vector3();
var vector2 = new THREE.Vector3();

return function ( vectorA, vectorB, vectorC ) {

vector1.subVectors( vectorB, vectorA );
vector2.subVectors( vectorC, vectorA );
vector1.cross( vector2 );

return 0.5 * vector1.length();

};

}(),

center: function ( geometry ) {

console.warn( 'THREE.GeometryUtils: .center() has been moved to Geometry. Use geometry.center() instead.' );
return geometry.center();

}

}
Insert cell
class Sphere {
constructor() {
//this.triggers = document.getElementsByClassName('triggers')[0].querySelectorAll('span')
this.wireframe = false;
//if ( ! Detector.webgl ) Detector.addGetWebGLMessage();

this.defaultAnimationSpeed =1;
this.morphAnimationSpeed = 2;

this.SCREEN_WIDTH = window.innerWidth;
this.SCREEN_HEIGHT = window.innerHeight;
this.mouseX = 0;
this.mouseY = 0;
this.deltaX = 0;
this.deltaY = 0;
this.scrollDepht=0
this.windowHalfX = window.innerWidth / 2;
this.windowHalfY = window.innerHeight / 2;

this.normalSpeed = (this.defaultAnimationSpeed / 100);
this.fullSpeed = (this.morphAnimationSpeed / 100);
this.windowHalfX = window.innerWidth / 2;
this.windowHalfY = window.innerHeight / 2;
this.animationVars = {
speed: this.normalSpeed
};
this.SEPARATION = 200;
this.AMOUNTX = 10;
this.AMOUNTY = 10;

this.camera = {};
this.camera2 = {};
this.scene = new THREE.Scene();
this.scene2 = new THREE.Scene();
this.renderer = {};

this.sceneIndex = 1;
this.cameraIndex = 1;
this.camPositionIdx = 1;
this.numberOfParticles = 2000;

this.particleImage = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/605067/particle-tiny.png';
this.particleColor = '0xFFFFFF';
this.particleSize = 20;

this.OBJ_PARAMS= {
'CartoonRocket': {'scale': 33},
'echo': {'scale': 20},
'hat': {'scale': 80},
'gear': {'scale': 20},
'Lightbulb': {'scale': 50},
'kibel': {'scale': 70}
}

this.renderer = new THREE.WebGLRenderer({alpha: true, transparent: true});
this.renderer.setClearColor(0xFFF000, 0);

this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setSize(this.SCREEN_WIDTH, this.SCREEN_HEIGHT);
}

init() {

var container, clock = new THREE.Clock();
this.tick = 0;
this.clock = clock
var that = this;
var hero = DOM.svg(600, 600);
var container = document.createElement("div");
this.GPUParticleSystem = null
container.className = "hero__three-container";
hero.appendChild(container);

this.camera = new THREE.PerspectiveCamera(45, this.SCREEN_WIDTH / this.SCREEN_HEIGHT, 100, 10000);
this.camera.position.z = 1000;

//this.GPUParticleSystem = new THREE.GPUParticleSystem( {
// maxParticles: 250000
// });
//this.scene2.add(GPUParticleSystem)
container.appendChild(this.renderer.domElement);
this.container = container;

this.optGPU = {
position: new THREE.Vector3(),
positionRandomness: .3,
velocity: new THREE.Vector3(),
velocityRandomness: .5,
color: 0xaa88ff,
colorRandomness: .2,
turbulence: .5,
lifetime: 2,
size: 5,
sizeRandomness: 1
};
this.spawnerOptions = {
spawnRate: 15000,
horizontalSpeed: 1.5,
verticalSpeed: 1.33,
timeScale: 1
};


this.lines = this.generateLines();

// lines

//this.scene.add(this.lines)

this.scene2.add(this.lines)


// document.addEventListener('mousemove', onDocumentMouseMove.bind(this), false);

// this.triggers[3].addEventListener("click", wireframe.bind(this), false);


window.addEventListener('resize', onWindowResize.bind(this), false);
function onDocumentMouseMove(event) {


this.mouseX = event.clientX - this.windowHalfX;
this.mouseY = event.clientY - this.windowHalfY;
}




function onWindowResize() {


this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();

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

}


function wireframe(event) {

if (!this.wireframe) {
let wgeometry = new THREE.PlaneGeometry(1000, 1000, 100, 100);
let wmaterial = new THREE.MeshBasicMaterial({color: 0xFFFFFF, wireframe: true, wireframeLinewidth: 1});
let wireplane = new THREE.Mesh(wgeometry, wmaterial);
wireplane.name = "wireplane"
wireplane.scale.set(1, 1, 1);
wireplane.rotation.x = -Math.PI / 2;
this.scene2.add(wireplane);
var helper = new THREE.CameraHelper( 2 );
this.scene2.add( helper );
} else {
this.wireframe = true
let plane = this.scene1.getObjectByName("wireplane");
let plane2 = this.scene2.getObjectByName("wireplane");
this.scene2.remove(plane2);
this.scene.remove(plane);

}

}
return hero
}
generateLines(){
var lines = new THREE.Group();
lines.name = "lines";
for (var i = 0; i < 200; i++) {

let geometry = new THREE.Geometry();

let vertex = new THREE.Vector3(Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1);
vertex.normalize();
vertex.multiplyScalar(450);

geometry.vertices.push(vertex);

let vertex2 = vertex.clone();
vertex2.multiplyScalar(Math.random() * 0.25 + 1);

geometry.vertices.push(vertex2);
let line = new THREE.Line(geometry, new THREE.LineBasicMaterial({color: 0x353535, opacity: Math.random()}));
lines.add(line);
}
return lines
}
initMorph(scene, camera, renderer) {

var that = this;
this.particleCount = this.numberOfParticles;

//$("#skills").on("click", this.toObject.bind(that))
function animateVector3(vectorToAnimate, target, options){
options = options || {};
// get targets from options or set to defaults
var to = target || THREE.Vector3(),
easing = options.easing || TWEEN.Easing.Quadratic.In,
duration = options.duration || 2000;
// create the tween
var tweenVector3 = new TWEEN.Tween(vectorToAnimate)
.to({ x: to.x, y: to.y, z: to.z, }, duration)
.easing(easing)
.onUpdate(function(d) {
if(options.update){
options.update(d);
}
})
.onComplete(function(){
if(options.callback) options.callback();
});
// start the tween
tweenVector3.start();
// return the tween in case we want to manipulate it later on
return tweenVector3;
}

window.addEventListener('resize', this.fullScreen.bind(this), false)


// Camera and position
this.camera2 = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 100, 10000);
this.camera2.position.z = 800;

var light = new THREE.AmbientLight(0xffffff, 1); // soft white light
this.scene2.add(light);
//this.renderer.setClearColor(0xfff#


//document.addEventListener("mousewheel", MouseWheelHandler.bind(this), false);
// function MouseWheelHandler(event) {

// console.log( event.deltaY);}



this.particlesStart = new THREE.Geometry();
this.sphereParticles = new THREE.Geometry();
this.cubeParticles = new THREE.Geometry();
this.objParticles = new THREE.Geometry();
this.objPoints = null;
this.hatParticles = new THREE.Geometry();
this.hatPoints = null;
this.echoParticle = new THREE.Geometry();
this.echoPoints = null;
this.gearParticles = new THREE.Geometry();
this.gearPoints = null;
this.astroParticles = new THREE.Geometry();
this.astroPoints = null;
this.bulbParticles = new THREE.Geometry();
this.bulbPoints = null;


var customMaterial = new THREE.ShaderMaterial(
{
uniforms:
{
"c": { type: "f", value: -.3 },
"p": { type: "f", value: 3.4 },
glowColor: { type: "c", value: new THREE.Color(0xafafaf) },
viewVector: { type: "v3", value: camera.position }
},

side: THREE.BackSide,
alphaTest:0.5,
blending: THREE.AdditiveBlending,
transparent: true,
} );




this.loadObject(this.hatParticles, this.hatPoints, "hat");
//this.loadObject(this.objParticles, this.objPoints, "kibel");
//this.loadObject(this.echoParticle, this.echoPoints, "echo");
//this.loadObject(this.gearParticles, this.gearPoints, "gear");to
//this.loadObject(this.astroParticles, this.astroPoints, "CartoonRocket", "https://s3-us-west-2.amazonaws.com/s.cdpn.io/605067/");
this.loadObject(this.bulbParticles, this.bulbPoints, "Lightbulb");
//Custom objects
var sphereGeometry = new THREE.SphereGeometry(5, 30, 32);
let boxGeometry = new THREE.BoxGeometry(9, 9, 9);


for (var p = 0; p < this.numberOfParticles; p++) {
var vertex = new THREE.Vector3();
vertex.x = Math.random() * 2 - 1;
vertex.y = Math.random() * 2 - 1;
vertex.z = Math.random() * 2 - 1;

vertex.normalize();
// vertex.multiplyScalar(-Math.abs(Math.random() * 1));
vertex.multiplyScalar(40 * Math.random() + 100);

this.particlesStart.vertices.push(vertex);

}

this.spherePoints = THREE.GeometryUtils.randomPointsInGeometry(sphereGeometry, this.particleCount)
// this.spherePoints.map(function(el){
// let factor = 2* (2* Math.random() -1);
//
// el.addScalar(factor)
//
// return el
//
// })

this.cubePoints = THREE.GeometryUtils.randomPointsInGeometry(boxGeometry, this.particleCount);
// Particles
this.burstParticles = this.particlesStart.clone()
this.createVertices(this.sphereParticles, this.spherePoints, null, null);
this.createVertices(this.cubeParticles, this.cubePoints, null, 1);



this.pMaterial = new THREE.PointsMaterial({
// color: 0xFFFFFF,
//vertexColors: THREE.VertexColors,
size: this.particleSize,
alphaTest: 0.5,

//depthTest: false,
opacity: 0.7,
map: generateSprite(),//THREE.ImageUtils.loadTexture('./images/dot.png'),
blending: THREE.AdditiveBlending,
transparent: true
});

//this.triggers[0].addEventListener('click', this.toSphere.bind(this))
//this.triggers[1].addEventListener('click', this.toCube.bind(this))
$("#education").on("click", this.toHat.bind(that))
$("#skills").on("click", this.toBulb.bind(that))

this.particleSystem = new THREE.Points(
this.particlesStart,
this.pMaterial
);
this.particleSystem.sortParticles = true;
// Add the particles to the scene
//console.log(this.particleSystem)
//this.scene.add(this.particleSystem);

this.scene2.add(this.particleSystem);
this.moonGlow = new THREE.Mesh( sphereGeometry.clone(), customMaterial.clone() );
//this.moonGlow.position = moon.position;
this.moonGlow.scale.multiplyScalar(55);
this.scene2.add( this.moonGlow );
// Animate

this.sceneIndex = 2
//this.animate();
//etTimeout(this.toBurst(), 1500);
this.toBurst()

//this.tweenScale(this.particleSystem.scale, 4, {x: 5.5, y: 5.5, z: 5.5});
function generateSprite() {

let canvas = document.createElement('canvas');
canvas.width = 16;
canvas.height = 16;

let context = canvas.getContext('2d');
var gradient = context.createRadialGradient(canvas.width / 2, canvas.height / 2, 0, canvas.width / 2, canvas.height / 2, canvas.width / 2);
let t =1// Math.round(1.5-Math.random() * 100) / 100;
let clr='rgba(255,255,255,'+t+')'
gradient.addColorStop(0, clr);
gradient.addColorStop(1, 'transparent');
// gradient.addColorStop(0.2, 'rgba(0,255,255,1)');
//gradient.addColorStop(0.4, 'rgba(0,0,64,1)');
// gradient.addColorStop(1, 'rgba(0,0,0,1)');

context.fillStyle = gradient;
context.fillRect(0, 0, canvas.width, canvas.height);

var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
return texture;

}

}

changeOpacity(objects, opacity = 1, duration = 1) {
var that = this
objects.children.map(function (e) {
TweenMax.to(e.material, duration, {
ease: TWEEN.Power4.easeIn, speed: that.fullSpeed, onComplete: that.slowDown.bind(that),
opacity: opacity
})

})
}


morphTo(newParticles, color = '0x000000') {

let that = this;
TweenMax.to(this.animationVars, .4, {
ease: TWEEN.Power4.easeIn, speed: this.fullSpeed, onComplete: that.slowDown.bind(that)
});
// this.particleSystem.material.color.setHex(color);

for (var i = 0; i < this.particlesStart.vertices.length; i++) {
TweenMax.to(this.particlesStart.vertices[i], 2, {
ease: TweenMax.Elastic.easeOut.config(1, 0.75),
x: newParticles.vertices[i].x,
y: newParticles.vertices[i].y,
z: newParticles.vertices[i].z
})
}
}

tweenScale(duration = 1, toValue = {x: 2, y: 2, z: 2}) {

TweenMax.to(this.particleSystem.scale, duration, toValue,
{
ease: TweenMax.Elastic.easeOut.config(1, 0.45),
});
}

createVertices(emptyArray, points, yOffset = 0, trigger = null) {
// console.log(this.particleCount, points, yOffset)
for (var p = 0; p < this.particleCount; p++) {
var vertex = new THREE.Vector3();
vertex.x = points[p]['x'];
vertex.y = points[p]['y'] - yOffset;
vertex.z = points[p]['z'];

emptyArray.vertices.push(vertex);
}

return emptyArray;
}

loadObject(objectParticles, objectPoints, name = "fu", path = "./js/3d/",callback=undefined) {
const codepenAssetUrl = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/605067/";
var that = this;

var objLoader = new THREE.OBJLoader();

objLoader.setPath(path ? path : codepenAssetUrl)

objLoader.load(name + '.obj', function (object) {
// var mesh = new THREE.Mesh( object, new THREE.MeshBasicMaterial( { color: 0xffff00 ,transparent:true} ) );
//
//that.scene2.add(mesh)


object.traverse(function (child) {
if (child instanceof THREE.Mesh) {
let scale = that.OBJ_PARAMS[name].scale;
// console.log(child)
let area = new THREE.Box3();
area.setFromObject(child);
let yOffset = (area.max.y * scale) / 2;


child.geometry.scale(scale, scale, scale);
objectPoints = THREE.GeometryUtils.randomPointsInBufferGeometry(child.geometry, that.particleCount);


that.createVertices(objectParticles, objectPoints, yOffset, 2);
}
//else if (child){
// console.log(child)
//}
});
if (callback){
callback();
}

});


}

slowDown() {
TweenMax.to(this.animationVars, 4, {
ease: TweenMax.Power2.easeOut, speed: this.normalSpeed, delay: 1
});
}

toEcho(e) {
hideResume()
this.changeOpacity(this.lines, 0, 1)
console.log(e)
this.sceneIndex = 2
this.currentAnmiation = "object";
console.log("toEcho");
this.morphTo(this.echoParticle);
this.tweenScale(0.01);

}

removeLines() {
var o = this.scene2.getObjectByName('lines');
this.scene1.remove(o);
this.scene2.remove(o);
}
moveScene(scene, duration=1.5, position = {x: 0, y: 0, z: 0}) {

TweenMax.to(scene.position, duration, position,
{
ease: TweenMax.Elastic.easeOut.config(1, 0.75),
x: position.x,
y: position.y,
z: position.z

});
}
moveParticleSystem(duration=1.5, position = {x: 0, y: 0, z: 0}) {

TweenMax.to(this.particleSystem.position, duration, position,
{
ease: TweenMax.Elastic.easeOut.config(1, 0.75),
x: position.x,
y: position.y,
z: position.z

});
}



animate() {
this.particlesStart.verticesNeedUpdate = true;


requestAnimationFrame(this.animate.bind(this));

/*
var delta = this.clock.getDelta() * spawnerOptions.timeScale;
this.tick += delta;
if ( this.tick < 0 ) this.tick = 0;
if ( delta > 0 ) {
this.optGPU.position.x = Math.sin( this.tick * this.spawnerOptions.horizontalSpeed ) * 20;
this.optGPU.position.y = Math.sin( this.tick * this.spawnerOptions.verticalSpeed ) * 10;
this.optGPU.position.z = Math.sin( this.tick * this.spawnerOptions.horizontalSpeed + spawnerOptions.verticalSpeed ) * 5;
for ( var x = 0; x < this.spawnerOptions.spawnRate * delta; x++ ) {
// Yep, that's really it. Spawning particles is super cheap, and once you spawn them, the rest of
// their lifecycle is handled entirely on the GPU, driven by a time uniform updated below
GPUParicleSystem.spawnParticle( options );
}
}
this.GPU.update( tick );
*/

this.render();

}
fullScreen() {
this.camera.aspect = window.innerWidth / window.innerHeight;
this.camera.updateProjectionMatrix();

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


render() {
// console.log("mouseY :" + this.mouseY + " mouseX: " + this.mouseX)

var currentScene = null;
var currentCamera = null;

function switchCall(index, func1, func2) {
switch (index) {
case 1:
func1()
break;
case 2:
func2()
break;
}
}

switchCall(this.sceneIndex,
() => {

currentScene = this.scene;

}, () => {
//this.particleSystem.rotation.x += 0.001
this.particleSystem.rotation.y += 0.001
this.lines.rotation.y += 0.001
//this.particleSystem.rotation.z += 0.001
currentScene = this.scene2;
})

switchCall(this.cameraIndex,
() => {
// this.camera.position.x += ( this.mouseX + 200 - this.camera.position.x ) * .05;
//this.camera.position.y = this.screenDepth* .05;
//this.camera.lookAt(this.scene.position);

switchCall(this.camPositionIdx,
() => {
// this.camera.lookAt(this.scene.position);

}, () => {
// this.camera.lookAt(this.scene.position);
})

currentCamera = this.camera;
}, () => {
currentScene = this.scene2;
//this.camera2.position.x += ( this.mouseX + 0 - this.camera2.position.x ) * 0.05;
//this.camera2.position.y += ( -this.mouseY + 500 - this.camera2.position.y ) * 0.05;
//this.camera2.lookAt(this.scene2.position);
switchCall(this.camPositionIdx,
() => {
this.camera.lookAt(this.scene2.position);

}, () => {
// this.camera.lookAt(this.scene2.position);
})
//this.renderer.setClearColor(0x000000, 0);
currentCamera = this.camera2.clone();

})


this.renderer.render(currentScene, currentCamera);
}

toHat(e) {
hideResume();
fadeInEdu()
this.moveScene(this.scene2,1.5 , {x: -229, y: 70, z: -211})
this.moveParticleSystem()
this.changeOpacity(this.lines, 0.5, 1)
console.log(e);
this.tweenScale(2);
this.sceneIndex = 2
this.currentAnmiation = "object";
console.log("toObject");
this.morphTo(this.hatParticles);

}
toSphere() {
this.moveScene(this.scene2, 3)
this.moveParticleSystem()
this.tweenScale(3, {x: 70, y: 70, z: 70})
this.morphTo(this.sphereParticles);
}
toGear() {
this.loadObject(this.gearParticles, this.gearPoints, "gear","./js/3d/",transform.bind(this));

function transform () {
hideResume()
this.changeOpacity(this.lines, 0, 1)
console.log()
this.sceneIndex = 2;


this.tweenScale(3, {x: .80, y: .80, z: .80})
this.morphTo(this.gearParticles);
}

}
toAstro() {
this.moveScene(this.scene2, 1.5, {x: 269, y: 90, z: -111})
this.moveParticleSystem()
hideResume()
fadeInSkills()
this.changeOpacity(this.lines, 1, 1)
console.log("astro")
this.sceneIndex = 2


this.tweenScale(1.5, {x: 1, y: 1, z: 1})
this.morphTo(this.astroParticles);

}
toBulb() {
this.moveScene(this.scene2, 1.5, {x: 269, y: 90, z: -111})
this.moveParticleSystem(1.5,{x:14,y:170,z:-150})
hideResume()
fadeInSkills()
this.changeOpacity(this.lines, 1, 1)
console.log("bulb")
this.sceneIndex = 2


this.tweenScale(2.5, {x: 2.5, y: 2.5, z: 2.5})
this.morphTo(this.bulbParticles);

}
toBurst() {
showResume()
hideTextBoxes()
this.moveParticleSystem(1.5)

this.moveScene(this.scene2, 1)
this.sceneIndex = 2
this.changeOpacity(this.lines, 1, 1)
TweenMax.to(this.particleSystem.scale, 1.5, {x: 3.5, y: 3.5, z: 3.5}, {
ease: TweenMax.Elastic.easeOut.config(1, 0.75),
});

this.morphTo(this.burstParticles);

}
toCube() {
this.sceneIndex = 2;
this.changeOpacity(this.lines, 0, 1)

TweenMax.to(this.particleSystem.scale, 1, {x: 30, y: 30, z: 30}, {
ease: TweenMax.Elastic.easeOut.config(1, 0.75),
});
this.morphTo(this.cubeParticles);

}



}


Insert cell

function hideResume() {
$(".hero__content > h1").animate({'opacity':0},1000);
$(".hero__content > p").animate({'opacity':0},1000);
}
Insert cell
Insert cell
Insert cell
SPHERE.renderer
Insert cell
The
SPHERE.initMorph(SPHERE.scene, SPHERE.camera, SPHERE.renderer)
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