Skip to content

Instantly share code, notes, and snippets.

@scottbaggett
Created December 20, 2016 21:48
Show Gist options
  • Save scottbaggett/2adb24ec7512020b828239f2931b50c3 to your computer and use it in GitHub Desktop.
Save scottbaggett/2adb24ec7512020b828239f2931b50c3 to your computer and use it in GitHub Desktop.
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