1import { 2 Renderer, 3 Program, 4 Mesh, 5 Vec2, 6 Texture, 7 Flowmap, 8 Plane 9 } from "https://cdn.jsdelivr.net/npm/[email protected]/dist/ogl.mjs"; 10 11 const vertex = ` 12 attribute vec2 uv; 13 attribute vec2 position; 14 varying vec2 vUv; 15 16 void main() { 17 vUv = uv; 18 gl_Position = vec4(position, 0.0, .45); 19 } 20 `; 21 22 const fragment = ` 23 precision highp float; 24 uniform sampler2D tImage; 25 uniform sampler2D tFlow; 26 varying vec2 vUv; 27 28 void main() { 29 vec3 flow = texture2D(tFlow, vUv).rgb; 30 vec2 uv = vUv; 31 uv += (flow.rg * flow.b * 50.0); 32 vec3 tex = texture2D(tImage, uv).rgb; 33 gl_FragColor.rgb = tex; 34 gl_FragColor.a = 1.0; 35 } 36 `; 37 38 const background = document.querySelector(".tp-image-distortion"); 39 if (background) { 40 // Read image source from data attribute 41 const imageSrc = background.getAttribute("data-background"); 42 43 const renderer = new Renderer(); 44 const gl = renderer.gl; 45 background.appendChild(gl.canvas); 46 47 const mouse = new Vec2(0.5); 48 const lastMouse = new Vec2(0.5); 49 const velocity = new Vec2(); 50 let aspect = 1; 51 52 function resize() { 53 const rect = background.getBoundingClientRect(); 54 aspect = rect.width / rect.height; 55 gl.canvas.width = rect.width; 56 gl.canvas.height = rect.height; 57 renderer.setSize(rect.width, rect.height); 58 } 59 60 window.addEventListener("resize", resize, false); 61 resize(); 62 63 const flowmap = new Flowmap(gl, { falloff: 0.3, dissipation: 0.95, size: 1000 }); 64 65 const geometry = new Plane(gl); 66 67 const texture = new Texture(gl); 68 const img = new Image(); 69 img.crossOrigin = "anonymous"; 70 img.onload = () => { 71 texture.image = img; 72 texture.minFilter = gl.LINEAR; 73 texture.magFilter = gl.LINEAR; 74 texture.wrapS = gl.CLAMP_TO_EDGE; 75 texture.wrapT = gl.CLAMP_TO_EDGE; 76 }; 77 img.src = imageSrc; // <-- Here we use the data-background attribute 78 79 const program = new Program(gl, { 80 vertex, 81 fragment, 82 uniforms: { 83 tImage: { value: texture }, 84 tFlow: flowmap.uniform 85 } 86 }); 87 88 const mesh = new Mesh(gl, { geometry, program }); 89 90 function updateMouse(event) { 91 const rect = background.getBoundingClientRect(); 92 const x = (event.clientX - rect.left) / rect.width; 93 const y = 1 - (event.clientY - rect.top) / rect.height; 94 mouse.set(x, y); 95 } 96 97 background.addEventListener("mousemove", updateMouse, false); 98 background.addEventListener("touchmove", (event) => { 99 if (event.touches.length > 0) updateMouse(event.touches[0]); 100 }, false); 101 102 103 104 const spring = 0.04; 105 const friction = 0.8; 106 const springVel = new Vec2(); 107 function update() { 108 springVel.copy(mouse).sub(lastMouse).multiply(spring); 109 velocity.add(springVel).multiply(friction); 110 lastMouse.add(velocity); 111 112 flowmap.mouse.copy(lastMouse); 113 flowmap.velocity.copy(velocity); 114 flowmap.aspect = aspect; 115 116 flowmap.update(); 117 renderer.render({ scene: mesh }); 118 requestAnimationFrame(update); 119 } 120 121 requestAnimationFrame(update); 122 } 123
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.