Created
December 20, 2016 21:48
-
-
Save scottbaggett/2adb24ec7512020b828239f2931b50c3 to your computer and use it in GitHub Desktop.
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
import EventEmitter from "event-emitter-es6" | |
class CategoryImage extends EventEmitter { | |
constructor(properties) { | |
super() | |
this.initVelocities() | |
this.hasBuilt = false | |
// console.info(properties) | |
let pieces = (properties.hasOwnProperty('pieces')) ? properties.pieces : 16 | |
let scale = (properties.hasOwnProperty('scale')) ? properties.scale : 0.25 | |
let col = 0 | |
let row = 0 | |
let catObj = new THREE.Object3D() | |
let coords = (properties.hasOwnProperty('coords')) ? properties.coords : [] | |
let src = (properties.hasOwnProperty('src')) ? properties.src : "/images/categories/hoverboard.png" | |
this.titleProps = properties.title | |
this.path = properties.path | |
this.name = properties.name | |
this.container = new THREE.Object3D() | |
this.container.name = `category-image--${properties.name}` | |
this.timeline = new TimelineMax({paused: true}) | |
this.introTimeline = new TimelineMax({paused: true}) | |
const promises = [] | |
const loader = new THREE.TextureLoader() | |
for (let i = 0; i < pieces; i++) { | |
const url = `/images/categories/${this.name}/${this.name}${i}.png` | |
promises.push( new Promise( (resolve, reject) => { | |
let texture = loader.load(url, () => { | |
resolve(texture) | |
}) | |
})) | |
} | |
const titleUrl = `/images/categories/${this.name}/${this.name}-title.png` | |
promises.push( new Promise( (resolve, reject) => { | |
let texture = loader.load(titleUrl, () => { | |
resolve(texture) | |
}) | |
})) | |
// loop over all of the category images | |
// and generate the meshes & materials... | |
Promise.all(promises).then(( preloadArray ) => { | |
let i = 0; | |
const titleTexture = preloadArray[preloadArray.length-1] | |
const titleGeom = new THREE.PlaneGeometry(this.titleProps.dimensions[0]/6, this.titleProps.dimensions[1]/6) | |
const titleMaterial = new THREE.MeshBasicMaterial({ | |
map: titleTexture, | |
transparent: true, | |
opacity: 0, | |
depthTest: true, | |
}) | |
const titleMesh = new THREE.Mesh(titleGeom, titleMaterial) | |
titleMesh.scale.set(0.5, 0.5, 0.5) | |
titleMesh.position.y = this.titleProps.yOffset | |
titleMesh.position.z = 20 | |
titleMesh.name = "title" | |
catObj.add(titleMesh) | |
const texturesArray = preloadArray.slice(0,-1) | |
texturesArray.forEach( texture => { | |
let planeGeom = new THREE.PlaneGeometry(512, 512) | |
let planeMat = new THREE.MeshBasicMaterial({ | |
map: texture, | |
alphaTest: .03, | |
transparent: true, | |
opacity: 0 | |
}) | |
let planeMesh = new THREE.Mesh(planeGeom, planeMat) | |
planeMesh.position.z = i * -.1 | |
catObj.add(planeMesh) | |
planeMesh.scale.set(scale, scale, scale) | |
let delay = i * 0.15 | |
let velocity = this.velocities.get(this.name) | |
// POSITION | |
this.timeline.fromTo(planeMesh.position, 5, { | |
x: velocity[i].x * 600, | |
y: velocity[i].y * -600, | |
z: 1000 | |
}, { | |
x: 0, y: 0, z: -200 + i * 0.1, ease: Quint.easeOut | |
}, delay) | |
// MATERIAL OPACITY | |
this.timeline.fromTo(planeMesh.material, 2, | |
{ opacity: 0 }, | |
{ opacity: 1}, | |
delay | |
) | |
let delay2 = i * .02 | |
// EMIT EXPLODE EVENT RIGHT BEFORE | |
if (i==0) { | |
this.timeline.add(() => { | |
this.emit("explode") | |
}, 6.5) | |
} | |
this.timeline.to(planeMesh.position, 5, { | |
z: 2000 + (pieces - i) * 10, | |
x: velocity[i].x * 400, | |
y: velocity[i].y * -450, | |
delay: 0, | |
ease: Power3.easeIn | |
}, 7 + (pieces - i) * 0.11) | |
// INTRO TIMELINE | |
//---------------------------------------------------------------------- | |
// POSITION | |
this.introTimeline.fromTo(planeMesh.position, 3, { | |
x: 0, | |
y: -2000, | |
z: -200 + i * 0.1 | |
}, { | |
x: 0, y: 0, z: -200 + i * 0.1, ease: Quint.easeOut | |
}, i * 0.1) | |
this.introTimeline.add(() => { | |
this.emit("intro:near") | |
}, 4) | |
this.introTimeline.add(() => { | |
this.emit("intro:complete") | |
}, 8) | |
// MATERIAL OPACITY | |
this.introTimeline.to(planeMesh.material, 2, { opacity: 1}, 0) | |
// OUTTRO | |
this.introTimeline.to(planeMesh.position, 3, { | |
y: window.innerHeight, | |
ease: Quint.easeIn | |
}, 3.85 + (i*.01)) | |
this.introTimeline.timeScale(1.5) | |
//---------------------------------------------------------------------- | |
i++ | |
}) | |
// category title | |
this.timeline.to(titleMesh.material, 3, {opacity: 1}, 4) | |
this.timeline.fromTo(titleMesh.position, 3, | |
{y: this.titleProps.yOffset - 40}, | |
{y: this.titleProps.yOffset, ease: Quint.easeOut}, | |
4 | |
) | |
this.timeline.to(titleMesh.position, 4, | |
{y: this.titleProps.yOffset - 40, ease: Quint.easeIn}, | |
7 | |
) | |
this.timeline.to(titleMesh.material, 2, {opacity: 0}, 9) | |
this.timeline.timeScale(window.timeScale) | |
this.container.add(catObj) | |
this.container.position.z = -100 | |
this.container.scale.set(1,1,1) | |
}) | |
} | |
intro() { | |
this.introTimeline.restart() | |
} | |
build() { | |
if (!this.hasBuilt) { | |
this.hasBuilt = true | |
this.timeline.play() | |
} else { | |
console.info("restarting category image timeline...") | |
this.timeline.restart() | |
} | |
// console.info(`category-image.js build: ${this.path}`) | |
} | |
initVelocities() { | |
// velocity properties for each category trnasitions | |
this.velocities = new Map() | |
this.velocities.set("top-stories", [ | |
{x: -1, y: 0.8 }, // 0 | |
{x: 1, y: 0.5 }, // 1 | |
{x: 0, y: -0.5 }, // 2 | |
{x: 0.1, y: -0.5 }, // 3 | |
{x: 0, y: 2.4 }, // 4 | |
{x: 0.7, y: 0.2 }, // 5 | |
{x: -0.8, y: 0.3 }, // 6 | |
{x: -1, y: -0.8 }, // 7 | |
{x: -2, y: -0.4 }, // 8 | |
{x: 0, y: -0.4 }, // 9 | |
{x: 1, y: -1.0 }, // 10 | |
{x: -1, y: -0.8 }, // 11 | |
{x: 0, y: -0.4 }, // 12 | |
{x: 0, y: 0.3 }, // 13 | |
{x: -.03, y: 1.8 }, // 14 | |
{x: 0.4, y: 1.3 }, // 15 | |
]) | |
this.velocities.set("craftsmanship", [ | |
{x: -1, y: -1}, | |
{x: 0.8, y: -2}, | |
{x: 0.5, y: -0.5}, | |
{x: -2, y: -0.5}, | |
{x: 0, y: 0.5}, | |
{x: 0, y: 2} | |
]) | |
this.velocities.set('design', [ | |
{x: -0.2, y: 1 }, // 0 | |
{x: 0.2, y: 1 }, // 1 | |
{x: 0.1, y: 1 }, // 2 | |
{x: 0.1, y: 1 }, // 3 | |
{x: 0, y: 1.2 }, // 4 | |
{x: 0.7, y: 0.2 }, // 5 | |
{x: -0.8, y: -1 }, // 6 | |
{x: -1, y: -1 }, // 7 | |
{x: -1, y: -1 }, // 8 | |
{x: 0, y: -1 }, // 9 | |
{x: -1, y: -1.0 }, // 10 | |
{x: -1, y: -0.8 }, // 11 | |
{x: -1, y: -0.4 }, // 12 | |
{x: 1, y: 0.3 }, // 13 | |
{x: 1, y: 0.3 }, // 14 | |
{x: 1.4, y: 0.3 }, // 15 | |
]) | |
this.velocities.set("experiences", [ | |
{x: -1, y: 3 }, // 0 | |
{x: 1, y: 2 }, // 1 | |
{x: 0, y: -2 }, // 2 | |
{x: 0.1, y: -0.5 }, // 3 | |
{x: 0, y: 1.2 }, // 4 | |
{x: 0.7, y: 0.2 }, // 5 | |
{x: -0.8, y: 0.3 }, // 6 | |
{x: -1, y: -0.8 }, // 7 | |
{x: -1, y: -0.4 }, // 8 | |
{x: 0, y: -0.4 }, // 9 | |
{x: 1, y: -1.0 }, // 10 | |
{x: -1, y: -0.8 }, // 11 | |
{x: 0, y: -0.4 }, // 12 | |
{x: 0, y: 0.3 }, // 13 | |
{x: 0, y: 0.3 }, // 14 | |
{x: 0, y: -0.5 }, // 15 | |
]) | |
this.velocities.set("technology", [ | |
{x: 0, y: 1.4 }, // 0 | |
{x: 0, y: 2 }, // 1 | |
{x: 0, y: 2 }, // 2 | |
{x: -1, y: 1.3 }, // 3 | |
{x: -1, y: 0.2 }, // 4 | |
{x: 2, y: 0.2 }, // 5 | |
{x: -1, y: -0.2 }, // 6 | |
{x: -1, y: -0.8 }, // 7 | |
{x: -1, y: -1 }, // 8 | |
{x: 0, y: -0.4 }, // 9 | |
{x: 1, y: -1.0 }, // 10 | |
{x: 1, y: -0.8 }, // 11 | |
{x: 0, y: -1.5 }, // 12 | |
{x: -1, y: 0.3 }, // 13 | |
{x: -3, y: -2 }, // 14 | |
{x: 3, y: -2.5 }, // 15 | |
]) | |
} | |
destroy() { | |
} | |
} | |
export default CategoryImage |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment