Knikkerbord dat je kantelt Nieuw
Een bord met een knikker en drie gaten: kantel het met je muis, vinger of de pijltjestoetsen en de knikker rolt, botst tegen de latjes en valt in een gat; elk gat is gewoon een link naar die groep. Wie niet wil spelen, klikt of tabt meteen naar een gat. Voor de homepage van een kinderopvang, speeltuin of zwembad, als speelse keuze tussen groepen of afdelingen. Bij minder beweging kantelt het bord niet en schuift de knikker per toetsdruk.
Zo gebruik je het
- Plak de HTML op de plek waar het onderdeel moet komen.
- 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.
<!-- Knikkerbord dat je kantelt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="fyk">
<div class="fyk__bord" tabindex="0" role="group" aria-label="Knikkerbord. Kantel met de pijltjestoetsen, of tab naar een groep.">
<h3 class="fyk__h">Welke groep past bij je kind?</h3>
<p class="fyk__p">Kantel het bord met muis, vinger of pijltjes.</p>
<span class="fyk__lat" data-r=".34,.50,.30,.035" aria-hidden="true"></span>
<span class="fyk__lat" data-r=".67,.58,.025,.32" aria-hidden="true"></span>
<a class="fyk__gat" href="#fy-knikkerbord" data-p=".14,.80" data-t="Baby's, 0 tot 2 jaar: vaste leidster en een eigen slaapkamer."><span class="fyk__put" aria-hidden="true"></span>Baby's</a>
<a class="fyk__gat" href="#fy-knikkerbord" data-p=".42,.78" data-t="Peuters, 2 tot 4 jaar: buiten spelen in de moestuin."><span class="fyk__put" aria-hidden="true"></span>Peuters</a>
<a class="fyk__gat" href="#fy-knikkerbord" data-p=".80,.80" data-t="BSO, 4 tot 12 jaar: ophalen bij vier scholen in Zwolle-Zuid."><span class="fyk__put" aria-hidden="true"></span>BSO</a>
<span class="fyk__knikker" aria-hidden="true"></span>
</div>
<p class="fyk__st" aria-live="polite"></p>
</div>
</div>/* Knikkerbord dat je kantelt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.fyk{position:absolute;inset:0;overflow:hidden;background:#e9e7e3;font-family:'Switzer',sans-serif;color:#0a0a0a;text-align:left;perspective:700px}
.fyk *{box-sizing:border-box}
.fyk__bord{position:absolute;inset:8px;background:#f4f3f1;border-radius:8px;box-shadow:inset 0 0 0 3px #0a0a0a;touch-action:none;transform:scale(.985);will-change:transform;outline:none}
.fyk__bord:focus-visible{box-shadow:inset 0 0 0 3px #0a0a0a,0 0 0 3px #F5480F}
.fyk__h{position:absolute;left:14px;top:12px;right:14px;margin:0;font:700 16px/1.2 'Switzer',sans-serif;letter-spacing:-.01em;pointer-events:none}
.fyk__p{position:absolute;left:14px;top:34px;right:14px;margin:0;font:400 12px/1.35 'Switzer',sans-serif;color:#3d3b37;pointer-events:none}
.fyk__lat{position:absolute;background:#0a0a0a;border-radius:2px}
.fyk__gat{position:absolute;display:flex;align-items:center;gap:6px;min-height:28px;padding:2px 4px 2px 2px;border-radius:4px;color:#0a0a0a;text-decoration:none;font:600 13px/1 'Switzer',sans-serif;transform:translate(-14px,-50%);white-space:nowrap}
.fyk__put{flex:0 0 24px;width:24px;height:24px;border-radius:50%;background:#0a0a0a;box-shadow:inset 0 3px 0 rgba(255,255,255,.12)}
.fyk__gat:hover{color:#F5480F}
.fyk__gat:focus-visible{outline:2px solid #F5480F;outline-offset:2px}
.fyk__knikker{position:absolute;left:0;top:0;width:18px;height:18px;border-radius:50%;background:radial-gradient(circle at 35% 35%,#ff8a5c 0 22%,#F5480F 50%,#c73a0b 100%);box-shadow:2px 3px 3px rgba(10,10,10,.3);pointer-events:none;will-change:transform}
.fyk__st{position:absolute;left:20px;right:20px;bottom:14px;margin:0;font:500 12px/1.3 'Switzer',sans-serif;pointer-events:none;text-align:center}// Knikkerbord dat je kantelt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie
// root = het element waarin de HTML staat
function init(root){
var el=root.querySelector('.fyk');if(!el)return;
var RM=window.matchMedia&&window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var bord=el.querySelector('.fyk__bord'),kn=el.querySelector('.fyk__knikker'),st=el.querySelector('.fyk__st');
var LAT=[].slice.call(el.querySelectorAll('.fyk__lat')).map(function(n){var r=n.dataset.r.split(',').map(Number);return{n:n,r:r};});
var GAT=[].slice.call(el.querySelectorAll('.fyk__gat')).map(function(n){var p=n.dataset.p.split(',').map(Number);return{n:n,fx:p[0],fy:p[1],x:0,y:0};});
var W=1,H=1,R=9,GR=12,x=0,y=0,vx=0,vy=0,tx=0,ty=0,kx=0,ky=0,px=0,py=0,mode='rol',val=0,raf=0,last=0,vis=true,G=900,START=[.82,.36];
function maat(){var w=bord.clientWidth,h=bord.clientHeight;if(!w)return false;var o=W;W=w;H=h;
LAT.forEach(function(l){l.x=l.r[0]*W;l.y=l.r[1]*H;l.w=Math.max(6,l.r[2]*W);l.h=Math.max(6,l.r[3]*H);l.n.style.left=l.x+'px';l.n.style.top=l.y+'px';l.n.style.width=l.w+'px';l.n.style.height=l.h+'px';});
GAT.forEach(function(g){g.x=g.fx*W;g.y=g.fy*H;g.n.style.left=g.x+'px';g.n.style.top=g.y+'px';});
if(o===1){x=START[0]*W;y=START[1]*H;}else{x=Math.min(Math.max(x,R),W-R);y=Math.min(Math.max(y,R),H-R);}return true;}
function teken(s){kn.style.transform='translate('+(x-R).toFixed(1)+'px,'+(y-R).toFixed(1)+'px) scale('+(s==null?1:s).toFixed(3)+')';kn.style.opacity=s==null?1:Math.min(1,s*1.4);
if(!RM)bord.style.transform='scale(.985) rotateX('+(-ty*3.5).toFixed(2)+'deg) rotateY('+(tx*3.5).toFixed(2)+'deg)';}
function botsLat(){LAT.forEach(function(l){var cx=Math.max(l.x,Math.min(x,l.x+l.w)),cy=Math.max(l.y,Math.min(y,l.y+l.h)),dx=x-cx,dy=y-cy,d2=dx*dx+dy*dy;if(d2>=R*R)return;
var d=Math.sqrt(d2)||.001,nx=d2?dx/d:0,ny=d2?dy/d:-1,p=R-(d2?d:0);x+=nx*p;y+=ny*p;var vn=vx*nx+vy*ny;if(vn<0){vx-=1.5*vn*nx;vy-=1.5*vn*ny;}});}
function rand(){var m=R+3;if(x<m){x=m;vx=Math.abs(vx)*.5;}if(x>W-m){x=W-m;vx=-Math.abs(vx)*.5;}if(y<m){y=m;vy=Math.abs(vy)*.5;}if(y>H-m){y=H-m;vy=-Math.abs(vy)*.5;}}
function gaten(){for(var i=0;i<GAT.length;i++){var g=GAT[i],dx=g.x-x,dy=g.y-y,d=Math.hypot(dx,dy);if(d<GR*.75&&Math.hypot(vx,vy)<520){val={g:g,t:0,sx:x,sy:y};mode='val';st.textContent=g.n.dataset.t;return true;}
if(d<GR*1.6&&!RM){vx+=dx/d*700*(1/60);vy+=dy/d*700*(1/60);}}return false;}
function stap(dt){var ax=(tx+kx),ay=(ty+ky);ax=Math.max(-1,Math.min(1,ax));ay=Math.max(-1,Math.min(1,ay));vx+=ax*G*dt;vy+=ay*G*dt;var f=Math.exp(-.9*dt);vx*=f;vy*=f;x+=vx*dt;y+=vy*dt;rand();botsLat();gaten();}
function tick(t){if(!vis){raf=0;return;}var dt=Math.min(.033,(t-last)/1000);last=t;
if(mode==='rol'){for(var k=0;k<3;k++){stap(dt/3);if(mode!=='rol')break;}teken();}
else if(mode==='val'){val.t+=dt;var u=Math.min(1,val.t/.35);x=val.sx+(val.g.x-val.sx)*u;y=val.sy+(val.g.y-val.sy)*u;teken(1-u*.85);if(val.t>1.8){mode='rol';x=START[0]*W;y=START[1]*H;vx=vy=0;teken(.2);}}
raf=requestAnimationFrame(tick);}
function kick(){if(RM||raf)return;last=performance.now();raf=requestAnimationFrame(tick);}
function tilt(e){var r=bord.getBoundingClientRect();tx=Math.max(-1,Math.min(1,((e.clientX-r.left)/r.width-.5)*2.4));ty=Math.max(-1,Math.min(1,((e.clientY-r.top)/r.height-.5)*2.4));if(Math.abs(tx)<.08)tx=0;if(Math.abs(ty)<.08)ty=0;kick();}
var touch=false;
bord.addEventListener('pointermove',function(e){if(RM)return;if(e.pointerType==='mouse'||touch)tilt(e);});
bord.addEventListener('pointerdown',function(e){if(RM||e.target.closest('a'))return;if(e.pointerType!=='mouse'){touch=true;try{bord.setPointerCapture(e.pointerId);}catch(_){}tilt(e);}});
function stop(){touch=false;tx=ty=0;}
bord.addEventListener('pointerup',function(e){if(e.pointerType!=='mouse')stop();});bord.addEventListener('pointercancel',stop);bord.addEventListener('pointerleave',function(e){if(e.pointerType==='mouse')stop();});
var K={ArrowLeft:[-1,0],ArrowRight:[1,0],ArrowUp:[0,-1],ArrowDown:[0,1]};
bord.addEventListener('keydown',function(e){var k=K[e.key];if(!k||e.target!==bord)return;e.preventDefault();
if(RM){if(mode!=='rol')return;x+=k[0]*14;y+=k[1]*14;rand();botsLat();if(gaten()){x=val.g.x;y=val.g.y;teken(.3);setTimeout(function(){mode='rol';x=START[0]*W;y=START[1]*H;teken();},1800);}else teken();return;}
if(k[0])kx=k[0];if(k[1])ky=k[1];kick();});
bord.addEventListener('keyup',function(e){var k=K[e.key];if(!k)return;if(k[0])kx=0;if(k[1])ky=0;});
bord.addEventListener('blur',function(){kx=ky=0;});
if(maat()){teken();if(!RM){vy=-60;kick();}}
if('ResizeObserver' in window)new ResizeObserver(function(){if(maat())teken();}).observe(bord);
if('IntersectionObserver' in window)new IntersectionObserver(function(es){vis=es[0].isIntersecting;if(vis)kick();}).observe(el);
}
init(document.querySelector('.jouw-container'));
Meer uit componenten
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 →