Kop die wappert als een vlag New
A heading on a flag that ripples in the wind: the letters rise and fall with the cloth, with light and shade in the folds. Point at the flag and the wind picks up. Has a pause button and stops off-screen. For an opening, festive week or anniversary on a shop or bakery homepage.
Nu open in Zwolle
Bakkerij Bol, Grote Markt 12. De eerste week elk brood €1 goedkoper.
How to use it
- Paste the HTML where the text animations should appear.
- Add the CSS to your stylesheet. All classes are prefixed, so nothing clashes with your own styles.
- Add the JavaScript and call init() with the element that contains the HTML.
<!-- Kop die wappert als een vlag · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie -->
<div class="jouw-container">
<div class="t7v">
<div class="t7v__mast">
<span class="t7v__pole" aria-hidden="true"></span>
<div class="t7v__flag">
<svg class="t7v__cloth" aria-hidden="true"><path class="t7v__bg" fill="#F5480F"/><g class="t7v__sh"></g></svg>
<h3 class="t7v__h">Nu open in Zwolle</h3>
</div>
</div>
<div class="t7v__foot">
<p class="t7v__p">Bakkerij Bol, Grote Markt 12. De eerste week elk brood €1 goedkoper.</p>
<button class="t7v__btn" type="button" aria-pressed="false">Wind stilzetten</button>
</div>
</div>
</div>/* Kop die wappert als een vlag · © 2026 NedDev BV · NedDev Lab-licentie (gratis gebruik, niet doorverkopen) · neddev.com/nl/lab/gebruik/#licentie */
.t7v{position:absolute;inset:0;display:flex;flex-direction:column;justify-content:center;gap:14px;padding:16px 20px;container-type:size;font-family:'Switzer',sans-serif;box-sizing:border-box}
.t7v__mast{position:relative;display:flex;align-items:flex-start;height:58cqh;padding-left:10px}
.t7v__pole{position:absolute;left:0;top:-6px;bottom:0;width:6px;border-radius:4px;background:#0a0a0a}
.t7v__flag{position:relative;margin-top:4px;width:min(84cqi,420px);height:62%;display:flex;align-items:center;justify-content:center}
.t7v__cloth{position:absolute;left:0;top:0;width:100%;height:100%;overflow:visible}
.t7v__h{position:relative;margin:0;padding:0 6%;font-weight:800;font-size:clamp(20px,7.4cqi,38px);line-height:1;letter-spacing:-.02em;color:#fff;white-space:nowrap}
.t7v__c{display:inline-block;will-change:transform}
.t7v__sp{display:inline-block;width:.26em}
.t7v__foot{display:flex;align-items:center;justify-content:space-between;gap:12px}
.t7v__p{margin:0;font-size:clamp(12px,3.2cqi,14px);line-height:1.4;color:#3a3a3a}
.t7v__btn{flex:none;min-height:30px;padding:6px 10px;border:1px solid #0a0a0a;border-radius:4px;background:#fff;color:#0a0a0a;font:600 13px/1.2 'Switzer',sans-serif;cursor:pointer;transition:background-color .16s,color .16s}
.t7v__btn:hover{background:#0a0a0a;color:#fff}
.t7v__btn:focus-visible{outline:2px solid #F5480F;outline-offset:2px}// Kop die wappert als een vlag · © 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 w=root.querySelector('.t7v'),flag=w.querySelector('.t7v__flag'),svg=w.querySelector('.t7v__cloth'),bg=w.querySelector('.t7v__bg'),gsh=w.querySelector('.t7v__sh'),h=w.querySelector('.t7v__h'),btn=w.querySelector('.t7v__btn');
var NS='http://www.w3.org/2000/svg',txt=h.textContent;h.textContent='';h.setAttribute('aria-label',txt);var C=[];
txt.split('').forEach(function(ch){var s=document.createElement('span');s.setAttribute('aria-hidden','true');if(ch===' '){s.className='t7v__sp';h.appendChild(s);return;}s.className='t7v__c';s.textContent=ch;h.appendChild(s);C.push({el:s,cx:0});});
var STR=48,strips=[];for(var i=0;i<STR;i++){var p=document.createElementNS(NS,'path');gsh.appendChild(p);strips.push(p);}
var W=1,H=1,t=0,amp=1,ampT=1,spd=1,spdT=1,run=true,vis=true,raf=0,last=0,reduce=matchMedia('(prefers-reduced-motion: reduce)').matches;
function measure(){W=flag.offsetWidth||1;H=flag.offsetHeight||1;svg.setAttribute('viewBox','0 0 '+W+' '+H);var fl=flag.getBoundingClientRect().left;C.forEach(function(c){c.el.style.transform='';var r=c.el.getBoundingClientRect();c.cx=r.left+r.width/2-fl;});}
function Y(x){var u=x/W;return H*.085*amp*Math.pow(u,.85)*Math.sin(u*7.2-t*3.1*1)+H*.03*amp*u*Math.sin(u*13-t*4.7);}
function S(x){return (Y(x+1)-Y(x-1))/2;}
function draw(){var top='',bot='',n=40,x,k;for(k=0;k<=n;k++){x=W*k/n;top+=(k?'L':'M')+x.toFixed(1)+' '+Y(x).toFixed(1);}for(k=n;k>=0;k--){x=W*k/n;bot+='L'+x.toFixed(1)+' '+(H+Y(x)*.9).toFixed(1);}bg.setAttribute('d',top+bot+'Z');
for(var j=0;j<STR;j++){var x0=W*j/STR,x1=W*(j+1)/STR,sl=S((x0+x1)/2),a=Math.max(-1,Math.min(1,sl*3.2));
strips[j].setAttribute('d','M'+x0.toFixed(1)+' '+Y(x0).toFixed(1)+'L'+x1.toFixed(1)+' '+Y(x1).toFixed(1)+'L'+x1.toFixed(1)+' '+(H+Y(x1)*.9).toFixed(1)+'L'+x0.toFixed(1)+' '+(H+Y(x0)*.9).toFixed(1)+'Z');
strips[j].setAttribute('fill',a>0?'#0a0a0a':'#ffffff');strips[j].setAttribute('fill-opacity',(Math.abs(a)*(a>0?.26:.2)).toFixed(3));}
C.forEach(function(c){var y=Y(c.cx)*.95,r=Math.atan(S(c.cx))*180/Math.PI;c.el.style.transform='translateY('+y.toFixed(2)+'px) rotate('+r.toFixed(2)+'deg)';});}
function loop(now){raf=0;var dt=last?Math.min(.05,(now-last)/1000):.016;last=now;amp+=(ampT-amp)*.04;spd+=(spdT-spd)*.04;t+=dt*spd;draw();if(run&&vis&&w.isConnected)raf=requestAnimationFrame(loop);}
function start(){if(!raf&&run&&vis){last=0;raf=requestAnimationFrame(loop);}}
measure();t=.6;draw();
flag.addEventListener('pointerenter',function(){ampT=1.6;spdT=1.7;});flag.addEventListener('pointerleave',function(){ampT=1;spdT=1;});
btn.addEventListener('click',function(){run=!run;btn.setAttribute('aria-pressed',String(!run));btn.textContent=run?'Wind stilzetten':'Laten wapperen';if(run)start();});
if(reduce){run=false;btn.setAttribute('aria-pressed','true');btn.textContent='Laten wapperen';}
if('ResizeObserver' in window)new ResizeObserver(function(){measure();draw();}).observe(flag);
if(document.fonts&&document.fonts.ready)document.fonts.ready.then(function(){measure();draw();});
if('IntersectionObserver' in window){new IntersectionObserver(function(en){vis=en[0].isIntersecting;start();}).observe(w);}else start();
}
init(document.querySelector('.jouw-container'));
More text animations
Seen something you like?
Add it to your selection and send it over. We build your site around it, in your brand.
Get in touch →