Last active
February 1, 2023 12:06
-
-
Save jesperlandberg/22a0c6ce6203ccb257b092677882b396 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
| 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