Inktdruppel die zich in water uitspreidt Nieuw
Klik of tik ergens en er valt een druppel inkt in helder water: hij bloeit open, zakt in slierten naar beneden en lost langzaam op, om en om zwart en oranje. Voor de hero van een tekenatelier, drukkerij, tattoostudio of kunstuitleen, of als rustige achtergrond op een workshoppagina. Canvas 2D, pauzeert buiten beeld; met minder beweging verschijnt de vlek in één keer.
Workshop inkt en water
Zaterdag 9 november · Haarlem · € 45
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.
<!-- Inktdruppel die zich in water uitspreidt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="ikw">
<canvas class="ikw__cv" aria-hidden="true"></canvas>
<div class="ikw__txt"><p class="ikw__h">Workshop inkt en water</p><p class="ikw__p">Zaterdag 9 november · Haarlem · € 45</p></div>
<button class="ikw__btn" type="button">Laat een druppel vallen</button>
</div>
</div>/* Inktdruppel die zich in water uitspreidt · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.ikw{position:absolute;inset:0;background:linear-gradient(180deg,#fff 0%,#f4f3f1 100%);cursor:crosshair;font-family:Switzer,sans-serif;color:#0a0a0a;overflow:hidden}
.ikw__cv{position:absolute;inset:0;width:100%;height:100%;display:block}
.ikw__txt{position:absolute;left:16px;bottom:14px;right:16px;pointer-events:none}
.ikw__h{margin:0;font:600 18px/1.2 Switzer,sans-serif}
.ikw__p{margin:4px 0 0;font:400 14px/1.35 Switzer,sans-serif;color:#3a3a3a}
.ikw__btn{position:absolute;top:14px;right:14px}
.ikw__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:#0a0a0a;color:#fff;transition:background-color .18s,color .18s}
.ikw__btn:hover{background:#F5480F;color:#0a0a0a}
.ikw__btn:focus-visible{outline:2px solid #F5480F;outline-offset:3px}
@media (prefers-reduced-motion: reduce){.ikw__btn{transition:none}}// Inktdruppel die zich in water uitspreidt · © 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('.ikw'), cv = w.querySelector('.ikw__cv'), ctx = cv.getContext('2d'), btn = w.querySelector('.ikw__btn');
var W = 1, H = 1, ps = [], n = 0, t = 0, MAX = 2200;
var cols = ['10,10,10', '245,72,15'];
fit(cv, ctx, function (a, b) { W = a; H = b; draw(); });
function drop(x, y) {
var c = cols[n++ % 2];
for (var i = 0; i < 46; i++) {
var a = Math.random() * 6.283, s = 15 + Math.random() * Math.random() * 90;
ps.push({ x: x, y: y, vx: Math.cos(a) * s, vy: Math.sin(a) * s * .5, r: 1.2 + Math.random() * 1.4, c: c, life: 0, max: 2.2 + Math.random() * 2.4, seed: Math.random() * 50, kid: 0, p: 1 });
}
ps.push({ x: x, y: y, vx: 0, vy: 4, r: 4, g: 6, a0: .26, c: c, life: 0, max: 6.5, p: 0 });
if (ps.length > MAX) ps.splice(0, ps.length - MAX);
if (reduce) { for (var k = 0; k < 75; k++) upd(1 / 30); draw(); }
}
function upd(dt) {
t += dt;
for (var i = ps.length - 1; i >= 0; i--) {
var p = ps[i]; p.life += dt;
if (p.life > p.max) { ps.splice(i, 1); continue; }
if (p.p) {
var k = Math.exp(-1.6 * dt); p.vx *= k; p.vy *= k; p.vy += 30 * dt;
var sw = Math.sin(p.y * .05 + t * .9 + p.seed) * 28, sv = Math.cos(p.x * .045 - t * .7 + p.seed) * 12;
p.x += (p.vx + sw) * dt; p.y += (p.vy + sv) * dt; p.kid -= dt;
if (p.kid <= 0) { p.kid = .055; ps.push({ x: p.x, y: p.y, vx: sw * .08, vy: 3 + Math.random() * 4, r: p.r, g: 2.5 + Math.random() * 4, a0: .085, life: 0, max: 3.5 + Math.random() * 2.5, c: p.c, p: 0 }); }
} else { p.x += p.vx * dt; p.y += p.vy * dt; p.r += p.g * dt * (1 - p.life / p.max); }
}
}
function draw() {
ctx.clearRect(0, 0, W, H);
for (var i = 0; i < ps.length; i++) {
var p = ps[i], f = 1 - p.life / p.max;
var a = p.p ? .45 * f : p.a0 * f * Math.min(1, p.life * 6);
if (a < .004) continue;
ctx.fillStyle = 'rgba(' + p.c + ',' + a.toFixed(3) + ')';
ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, 6.283); ctx.fill();
}
}
w.addEventListener('pointerdown', function (e) {
if (e.target.closest('.ikw__btn')) return;
var r = w.getBoundingClientRect(); drop(e.clientX - r.left, e.clientY - r.top);
});
btn.addEventListener('click', function () { drop(W * (.25 + Math.random() * .5), H * (.2 + Math.random() * .25)); });
loop(w, function (dt) { if (reduce || !ps.length) return; upd(dt); draw(); });
setTimeout(function () { drop(W * .62, H * .28); }, 120);
setTimeout(function () { drop(W * .4, H * .22); }, 700);
}
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 →