Bouwen aan wat blijft.
Elke letter schuift met een kleine draai omhoog uit een masker zodra de kop in beeld komt; voor een openingskop die binnenkomt.
<!-- Letters omhoog · NedDev · eigen werk. -->
<!-- benodigd, één keer per pagina: -->
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.13.0/dist/ScrollTrigger.min.js"></script>
<div class="jouw-container">
<div class="ei-spl"><h3 class="ei-spl__h" data-ei-spl>Bouwen aan wat blijft.</h3><button class="ei-spl__re" type="button">opnieuw</button></div>
</div>/* Letters omhoog · NedDev · eigen werk. */
.ei-spl{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;padding:0 20px;box-sizing:border-box}
.ei-spl__h{margin:0;font-family:'Boldonse','Switzer',sans-serif;font-weight:400;font-size:clamp(18px,4.6vw,28px);line-height:1.5;color:#0a0a0a;text-align:center;letter-spacing:-.01em}
.ei-spl__w{display:inline-block;white-space:nowrap}
.ei-spl__m{display:inline-block;overflow:hidden;vertical-align:bottom;padding:0 .02em}
.ei-spl__c{display:inline-block;will-change:transform}
.ei-spl__h .ei-spl__w:last-child .ei-spl__c{color:#F5480F}
.ei-spl__re{font-family:'JetBrains Mono',monospace;font-size:11px;letter-spacing:.14em;text-transform:uppercase;background:none;border:1px solid rgba(10,10,10,.2);border-radius:2px;padding:6px 10px;color:#0a0a0a;cursor:pointer}
.ei-spl__re:hover{border-color:#F5480F;color:#F5480F}// Letters omhoog · NedDev · eigen werk.
// root = het element waarin de HTML staat
function init(root){
var w=root.querySelector('.ei-spl'),h=w.querySelector('[data-ei-spl]');
var reduce=matchMedia('(prefers-reduced-motion: reduce)').matches;
var words=h.textContent.trim().split(/\s+/);h.textContent='';h.setAttribute('aria-label',words.join(' '));
var chars=[];
words.forEach(function(word,i){var ws=document.createElement('span');ws.className='ei-spl__w';ws.setAttribute('aria-hidden','true');
word.split('').forEach(function(ch){var m=document.createElement('span');m.className='ei-spl__m';var c=document.createElement('span');c.className='ei-spl__c';c.textContent=ch;m.appendChild(c);ws.appendChild(m);chars.push(c);});
h.appendChild(ws);if(i<words.length-1)h.appendChild(document.createTextNode(' '));});
function play(){
if(reduce){chars.forEach(function(c){c.style.transform='none';c.style.opacity=1;});return;}
if(window.gsap){gsap.killTweensOf(chars);gsap.fromTo(chars,{yPercent:115,rotate:8,opacity:0},{yPercent:0,rotate:0,opacity:1,duration:.8,ease:'power4.out',stagger:.028});}
else{chars.forEach(function(c,i){c.style.transition='none';c.style.transform='translateY(115%)';c.style.opacity=0;void c.offsetWidth;c.style.transition='transform .8s cubic-bezier(.2,.9,.2,1) '+(i*.028)+'s,opacity .5s '+(i*.028)+'s';c.style.transform='none';c.style.opacity=1;});}
}
if(window.gsap&&window.ScrollTrigger&&!reduce){gsap.set(chars,{yPercent:115,opacity:0});ScrollTrigger.create({trigger:w,start:'top 85%',once:true,onEnter:play});}
else play();
w.querySelector('.ei-spl__re').addEventListener('click',play);
}
init(document.querySelector('.jouw-container'));