Golvend duinlandschap Nieuw
Vijf lagen duin in zandtinten rollen heel langzaam onder een oranje zon door, en schuiven met de muis een fractie mee zodat er diepte ontstaat. Voor de hero van een strandpaviljoen, camping, fietsverhuur of B&B aan zee, waar een foto te druk zou zijn. Canvas 2D met een handvol sinussen, licht genoeg voor elke site; met minder beweging staat het landschap stil.
Paviljoen Duinzicht, Zandvoort
Vandaag open tot 22.00 uur
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.
<!-- Golvend duinlandschap · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="dng">
<canvas class="dng__cv" aria-hidden="true"></canvas>
<div class="dng__txt"><p class="dng__h">Paviljoen Duinzicht, Zandvoort</p><p class="dng__p">Vandaag open tot 22.00 uur</p></div>
<a class="dng__btn" href="#">Reserveer een tafel</a>
</div>
</div>/* Golvend duinlandschap · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.dng{position:absolute;inset:0;background:#fbfaf8;font-family:Switzer,sans-serif;color:#0a0a0a;overflow:hidden}
.dng__cv{position:absolute;inset:0;width:100%;height:100%;display:block}
.dng__txt{position:absolute;left:16px;top:14px;right:30%}
.dng__h{margin:0;font:600 18px/1.2 Switzer,sans-serif}
.dng__p{margin:4px 0 0;font:400 14px/1.35 Switzer,sans-serif;color:#3a3a3a}
.dng__btn{position:absolute;left:16px;bottom:14px}
.dng__btn{display:inline-flex;align-items:center;min-height:36px;padding:0 14px;border:0;border-radius:4px;font:600 14px/1 Switzer,sans-serif;cursor:pointer;text-decoration:none;background:#fff;color:#0a0a0a;transition:background-color .18s,color .18s}
.dng__btn:hover{background:#F5480F;color:#0a0a0a}
.dng__btn:focus-visible{outline:2px solid #fff;outline-offset:3px}
@media (prefers-reduced-motion: reduce){.dng__btn{transition:none}}// Golvend duinlandschap · © 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 reduce=!!(window.matchMedia&&matchMedia('(prefers-reduced-motion: reduce)').matches);
function fit(cv,ctx,cb){var dpr=Math.min(window.devicePixelRatio||1,2);function f(){var r=cv.getBoundingClientRect();var w=Math.max(1,Math.round(r.width)),h=Math.max(1,Math.round(r.height));if(cv.width===Math.round(w*dpr)&&cv.height===Math.round(h*dpr))return;cv.width=Math.round(w*dpr);cv.height=Math.round(h*dpr);if(ctx)ctx.setTransform(dpr,0,0,dpr,0,0);if(cb)cb(w,h,dpr);}if(window.ResizeObserver)new ResizeObserver(f).observe(cv);f();}
function loop(el,step){var on=false,raf=0,last=0;function fr(t){raf=requestAnimationFrame(fr);var dt=last?Math.min(.05,(t-last)/1000):.016;last=t;step(dt,t/1000);}function go(v){if(v&&!on){on=true;last=0;raf=requestAnimationFrame(fr);}else if(!v&&on){on=false;cancelAnimationFrame(raf);}}if(window.IntersectionObserver)new IntersectionObserver(function(es){go(es[0].isIntersecting);}).observe(el);else go(true);}
var w = root.querySelector('.dng'), cv = w.querySelector('.dng__cv'), ctx = cv.getContext('2d');
var W = 1, H = 1, t = 0, px = 0, tx = 0;
var L = [
{ c: '#ecdfca', b: .58, a: .07, f: 1.2, s: .5, d: .15 },
{ c: '#e0c8a3', b: .66, a: .075, f: 1.8, s: .8, d: .3 },
{ c: '#d0aa7a', b: .74, a: .07, f: 2.5, s: 1.2, d: .5 },
{ c: '#b98552', b: .83, a: .06, f: 3.3, s: 1.7, d: .75 },
{ c: '#8c5730', b: .92, a: .045, f: 4.4, s: 2.3, d: 1 }
];
function hgt(u) { return Math.sin(u) * .55 + Math.sin(u * 2.13 + 1.7) * .28 + Math.sin(u * 4.7 + .4) * .12; }
function draw() {
ctx.fillStyle = '#fbfaf8'; ctx.fillRect(0, 0, W, H);
ctx.fillStyle = '#F5480F'; ctx.beginPath(); ctx.arc(W * .8, H * .4, Math.min(W, H) * .1, 0, 6.283); ctx.fill();
for (var i = 0; i < L.length; i++) {
var l = L[i], off = t * l.s * .06 + i * 7.3 + px * l.d * .5;
ctx.fillStyle = l.c; ctx.beginPath(); ctx.moveTo(0, H);
for (var x = 0; x <= W + 8; x += 8) ctx.lineTo(x, H * (l.b + l.a * hgt(x / W * 3.4 * l.f + off)));
ctx.lineTo(W, H); ctx.closePath(); ctx.fill();
}
}
fit(cv, ctx, function (a, b) { W = a; H = b; draw(); });
w.addEventListener('pointermove', function (e) { var r = w.getBoundingClientRect(); tx = ((e.clientX - r.left) / r.width - .5) * 2; });
w.addEventListener('pointerleave', function () { tx = 0; });
w.querySelector('.dng__btn').addEventListener('click', function (e) { e.preventDefault(); });
loop(w, function (dt) { if (reduce) return; t += dt; px += (tx - px) * Math.min(1, dt * 3); 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 →