Skip to content

Instantly share code, notes, and snippets.

@jesperlandberg
Created May 11, 2020 07:55
Show Gist options
  • Save jesperlandberg/7507e769c23cdeba596dbed014f8dd23 to your computer and use it in GitHub Desktop.
Save jesperlandberg/7507e769c23cdeba596dbed014f8dd23 to your computer and use it in GitHub Desktop.
import {
Mesh,
PlaneBufferGeometry,
ShaderMaterial,
LinearFilter,
Vector2
} from 'three'
import gsap from 'gsap'
import Gl from '../Gl'
import Elem from '../Elem'
import ObjectPool from '../ObjectPool'
import fragmentShader from '@/gl/shaders/hover/frag.frag'
import vertexShader from '@/gl/shaders/hover/vert.vert'
import { qs } from '@/utils'
import { Events } from '@/events'
const geometry = new PlaneBufferGeometry(1, 1, 30, 30)
const material = new ShaderMaterial({
transparent: true,
fragmentShader,
vertexShader
})
export default class extends Elem {
init(args) {
super.init(args)
this.geometry = geometry
this.material = material.clone()
this.time = 0
this.mouse = true
this.material.uniforms = {
uTime: { value: 0 },
uTexture: { value: this.texture },
uVelo: { value: new Vector2(0, 0) },
uAlpha: { value: 0 },
uOffset: { value: new Vector2(this.camUnit.width, this.camUnit.height) },
uScreenProgress: { value: new Vector2(this.progress.x, this.progress.y) },
uProgress: { value: 0 }
}
this.img = qs('img', this.el)
this.texture = this.loader.load(this.img.currentSrc || this.img.src, (texture) => {
texture.minFilter = LinearFilter
texture.generateMipmaps = false
this.material.uniforms.uTexture.value = texture
Gl.renderer.initTexture(texture)
})
this.mesh = new Mesh(this.geometry, this.material)
this.mesh.renderOrder = 10
this.add(this.mesh)
ObjectPool.planesGroup.add(this)
ObjectPool.planes[this.name] = this
this.tl = null
this.onAdd()
}
onAdd() {
this.trigger = qs(`[data-gl-trigger="${this.name}"]`)
Events.on('mouseenter', this.trigger, this.enter)
Events.on('mouseleave', this.trigger, this.leave)
}
enter = () => {
const { uProgress } = this.material.uniforms
this.tl && this.tl.kill()
this.tl = gsap.timeline()
.set(this, {
visible: true
})
.to(uProgress, {
value: 1,
duration: 1,
ease: 'expo'
})
}
leave = () => {
const { uProgress } = this.material.uniforms
this.tl && this.tl.kill()
this.tl = gsap.timeline()
.to(uProgress, {
value: 0,
duration: 0.5,
ease: 'power1.out'
})
.set(this, {
visible: false
})
}
updatePosition(x, y, velo) {
super.updatePosition(x, y)
if (this.material && velo) {
this.time++
const { uVelo, uTime } = this.material.uniforms
uVelo.value.x = velo.x * 0.005
uVelo.value.y = velo.y * 0.005
uTime.value = this.time
}
}
destroy() {
gsap.to(this.material.uniforms.uProgress, {
value: 0,
duration: 0.5,
ease: 'power1',
onComplete: () => {
this.parent && this.parent.remove(this)
this.visible = false
Events.off('mouseenter', this.trigger, this.enter)
Events.off('mouseleave', this.trigger, this.leave)
}
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment