We build shit that works.
Live fragment shader, fluid colour, reacts to the cursor. Pure GLSL on OGL.
<!-- WebGL gradient-mesh · NedDev · eigen werk. -->
<!-- benodigd, één keer per pagina: -->
<script type="module">import * as OGL from "https://esm.sh/ogl@1.0.11"; window.OGL = OGL;</script>
<div class="jouw-container">
<div class="herowebgl-root"><canvas class="herowebgl-canvas"></canvas><div class="herowebgl-copy"><span>NEDDEV<sup>®</sup></span><p>We build shit that works.</p></div></div>
</div>/* WebGL gradient-mesh · NedDev · eigen werk. */
.herowebgl-root{position:absolute;inset:0;background:#0a0a0a}
.herowebgl-canvas{position:absolute;inset:0;width:100%;height:100%}
.herowebgl-copy{position:absolute;left:18px;bottom:16px;z-index:2;color:#fff;font-family:'Boldonse','Switzer',sans-serif;pointer-events:none}
.herowebgl-copy span{font-size:30px;letter-spacing:-.03em}.herowebgl-copy sup{font-size:.4em;color:#F5480F}
.herowebgl-copy p{font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.1em;margin:4px 0 0;opacity:.8}// WebGL gradient-mesh · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var canvas=root.querySelector('.herowebgl-canvas');var renderer,gl;try{renderer=new OGL.Renderer({canvas:canvas,dpr:Math.min(devicePixelRatio,1.5),alpha:false});gl=renderer.gl;}catch(e){return;}
function resize(){var r=canvas.getBoundingClientRect();renderer.setSize(r.width,r.height);}
var vertex='attribute vec2 uv;attribute vec2 position;varying vec2 vUv;void main(){vUv=uv;gl_Position=vec4(position,0.,1.);}';
var fragment='precision highp float;varying vec2 vUv;uniform float uTime;uniform vec2 uMouse;vec3 cA=vec3(.96,.28,.06);vec3 cB=vec3(.04,.04,.04);vec3 cC=vec3(.55,.12,.02);void main(){vec2 p=vUv;float t=uTime*.25;float w=sin(p.x*3.+t)*.5+cos(p.y*4.-t*1.3)*.5;float m=distance(p,uMouse);float g=smoothstep(.0,1.,p.y+w*.18+sin(m*6.-t)*.06);vec3 col=mix(cB,cA,g);col=mix(col,cC,smoothstep(.4,.0,m)*.5);gl_FragColor=vec4(col,1.);}';
var program=new OGL.Program(gl,{vertex:vertex,fragment:fragment,uniforms:{uTime:{value:0},uMouse:{value:[.5,.5]}}});var mesh=new OGL.Mesh(gl,{geometry:new OGL.Triangle(gl),program:program});
resize();addEventListener('resize',resize);canvas.addEventListener('pointermove',function(e){var r=canvas.getBoundingClientRect();program.uniforms.uMouse.value=[(e.clientX-r.left)/r.width,1-(e.clientY-r.top)/r.height];});
var raf,vis=true;var io=new IntersectionObserver(function(es){es.forEach(function(en){vis=en.isIntersecting;});},{threshold:.05});io.observe(canvas);
(function loop(t){raf=requestAnimationFrame(loop);if(!vis)return;program.uniforms.uTime.value=t*.001;renderer.render({scene:mesh});})(0);
}
init(document.querySelector('.jouw-container'));