Skip to content

Instantly share code, notes, and snippets.

@jesperlandberg
Last active February 1, 2023 12:06
Show Gist options
  • Select an option

  • Save jesperlandberg/22a0c6ce6203ccb257b092677882b396 to your computer and use it in GitHub Desktop.

Select an option

Save jesperlandberg/22a0c6ce6203ccb257b092677882b396 to your computer and use it in GitHub Desktop.
const vertex = `
precision mediump float;
attribute vec3 position;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
varying vec2 vUv;
void main() {
vec3 pos = position.xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4(pos,1.);
}
`
const fragment = `
precision mediump float;
uniform sampler2D uTex;
varying vec2 vUv;
void main() {
vec3 color = texture2D(uTex, vUv).xyz;
gl_FragColor = vec4(color, 1.);
}
`
class DomGl {
constructor() {
this.renderer = new Renderer({
alpha: true,
dpr: 1
})
this.renderer.setSize(store.width, store.height)
this.gl = this.renderer.gl
this.gl.clearColor(1, 1, 1, 0.)
store.body.appendChild(this.gl.canvas)
this.scene = new Transform()
this.view = {
left: store.width / -2,
right: store.width / 2,
bottom: store.height / -2,
top: store.height / 2,
}
this.camera = new Camera(this.gl, {
left: this.view.left,
right: this.view.right,
bottom: this.view.bottom,
top: this.view.top,
})
this.camera.position.z = 1
this.state = {
current: 0,
threshold: 200,
isResizing: false
}
this.ui = {
planes: document.querySelectorAll('.js-plane')
}
this.planes = null
this.init()
}
run = ({ current }) => {
const state = this.state
state.current = current
this.transformPlanes()
this.renderer.render({ scene: this.scene, camera: this.camera })
}
transformPlanes() {
if (!this.planes) return
const state = this.state
const total = this.planes.length - 1
for (let i = 0; i <= total; i++) {
const { mesh, rect } = this.planes[i]
if (!mesh) return
const isVisible = this.isVisible(rect)
if (isVisible || state.isResizing) {
const translate = rect.top - state.current
mesh.position.y = translate
}
}
}
isVisible({ top, bottom }) {
const { current, threshold } = this.state
const start = top - current
const end = bottom - current
const isVisible = start < (threshold + store.height) && end > -threshold
return isVisible
}
createPlanes() {
this.planes = []
this.ui.planes.forEach(plane => {
const cache = []
const image = plane.querySelector('img')
cache.el = plane
cache.rect = plane.getBoundingClientRect()
cache.texture = new Texture(this.gl)
cache.img = new Image()
cache.img.onload = () => cache.texture.image = cache.img
cache.img.src = image.src
cache.geo = new Plane(this.gl)
cache.program = new Program(this.gl, {
vertex,
fragment,
uniforms: {
uTime: { value: 0 },
uTex: { value: cache.texture }
}
})
cache.mesh = new Mesh(this.gl, {
geometry: cache.geo,
program: cache.program
})
cache.mesh.position.set(cache.rect.left, cache.rect.top, 1)
cache.mesh.scale.set(cache.rect.width, cache.rect.height, 1)
cache.mesh.setParent(this.scene)
this.planes.push(cache)
})
}
on() {
EventBus.on(GlobalRAFEvents.TICK, this.run)
}
off() {
EventBus.off(GlobalRAFEvents.TICK, this.run)
}
init() {
this.on()
this.createPlanes()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment