Dot Wave Field
WebGL-puntenraster dat als een golf reageert op je cursor.
Zo gebruik je het
- Plak de HTML op de plek waar het onderdeel moet komen. Zet de script-tags bovenaan één keer per pagina.
- Zet de CSS in je stylesheet. Alle klassen hebben een eigen voorvoegsel, dus niets botst met je eigen opmaak.
- Voeg de JavaScript toe en roep init() aan met het element waar de HTML in staat.
<!-- Dot Wave Field · 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>/* Dot Wave Field · NedDev · eigen werk. */
.dwf-stage{position:relative;width:100%;height:100%;background:#0a0a0a;overflow:hidden;cursor:crosshair}.dwf-stage canvas{position:absolute;inset:0;width:100%;height:100%;display:block}// Dot Wave Field · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
root.classList.add('dwf-stage');var reduce=matchMedia('(prefers-reduced-motion:reduce)').matches;var c=document.createElement('canvas');root.appendChild(c);
var mouse={x:.5,y:.5,tx:.5,ty:.5};function size(){var r=root.getBoundingClientRect();var dpr=Math.min(devicePixelRatio||1,2);c.width=r.width*dpr;c.height=r.height*dpr;return{w:r.width,h:r.height,dpr:dpr};}var dims=size();
root.addEventListener('pointermove',function(e){var r=root.getBoundingClientRect();mouse.tx=(e.clientX-r.left)/r.width;mouse.ty=(e.clientY-r.top)/r.height;});
if(typeof OGL!=='undefined'&&!reduce){var renderer=new OGL.Renderer({canvas:c,dpr:Math.min(devicePixelRatio||1,2),alpha:true});var gl=renderer.gl;gl.clearColor(.039,.039,.039,1);
var program=new OGL.Program(gl,{vertex:'attribute vec2 uv;attribute vec2 position;varying vec2 vUv;void main(){vUv=uv;gl_Position=vec4(position,0.,1.);}',fragment:'precision highp float;varying vec2 vUv;uniform float uT;uniform vec2 uMouse;uniform vec2 uRes;void main(){vec2 uv=vUv;float ar=uRes.x/uRes.y;vec2 p=uv;p.x*=ar;vec2 m=uMouse;m.x*=ar;float grid=34.0;vec2 g=fract(p*grid)-0.5;float d=distance(p,m);float wave=sin(d*22.0-uT*3.0)*0.5+0.5;wave*=smoothstep(0.6,0.0,d);float r=0.10+wave*0.30;float dot=smoothstep(r,r-0.08,length(g));vec3 base=vec3(0.18);vec3 col=mix(base,vec3(0.96,0.282,0.059),wave);gl_FragColor=vec4(col*dot,dot*(0.25+wave*0.9));}',uniforms:{uT:{value:0},uMouse:{value:[.5,.5]},uRes:{value:[dims.w,dims.h]}}});
var mesh=new OGL.Mesh(gl,{geometry:new OGL.Triangle(gl),program:program});new ResizeObserver(function(){dims=size();renderer.setSize(dims.w,dims.h);program.uniforms.uRes.value=[dims.w,dims.h];}).observe(root);
var run=true,t=0;new IntersectionObserver(function(es){run=es[0].isIntersecting;}).observe(root);(function frame(){requestAnimationFrame(frame);if(!run)return;t+=.016;mouse.x+=(mouse.tx-mouse.x)*.08;mouse.y+=(mouse.ty-mouse.y)*.08;program.uniforms.uT.value=t;program.uniforms.uMouse.value=[mouse.x,1-mouse.y];renderer.render({scene:mesh});})();}
else{var ctx=c.getContext('2d');function draw(){ctx.clearRect(0,0,c.width,c.height);var dpr=dims.dpr,step=26*dpr;t2+=.016;mouse.x+=(mouse.tx-mouse.x)*.08;mouse.y+=(mouse.ty-mouse.y)*.08;var mx=mouse.x*c.width,my=mouse.y*c.height;for(var x=step/2;x<c.width;x+=step){for(var y=step/2;y<c.height;y+=step){var d=Math.hypot(x-mx,y-my)/dpr;var wave=reduce?0:Math.max(0,(Math.sin(d*.12-t2*3)*.5+.5))*Math.max(0,1-d/300);var r=(1.8+wave*4)*dpr;ctx.beginPath();ctx.arc(x,y,r,0,7);ctx.fillStyle='rgba('+Math.round(46+wave*199)+','+Math.round(46+wave*26)+','+Math.round(46-wave*31)+','+(.25+wave*.75)+')';ctx.fill();}}if(!reduce)requestAnimationFrame(draw);}var t2=0;draw();}
}
init(document.querySelector('.jouw-container'));
Meer uit achtergronden & webgl
Iets gezien dat je mooi vindt?
Zet het in je selectie en stuur hem op. Dan bouwen we je site eromheen, in jouw huisstijl.
Neem contact op →