משפט הירו קבוע ומילה אחת בו מתחלפת כל שתי שניות: יוצאת למעלה, הבאה נכנסת מלמטה, והרוחב של השורה מתכוונן חלק. ארבע חלופות בלולאה.
מתי משתמשים: הירו של עסק שפונה לכמה קהלים או מציע כמה שירותים. אחת לעמוד, ותמיד עם מילה ראשונה שעומדת לבד אם JS לא נטען.
הדמו כאן עיצובי-ניטרלי בכוונה. כשהמהלך נכנס לפרויקט, מיובאת רק ההתנהגות: הצבעים, הרדיוסים, הפונטים והצללים יורשים את העיצוב של אותו פרויקט.
הקוד כאן עומד בפני עצמו. כל טוקן עיצוב נושא ברירת מחדל, מחלקות העזר של המאגר מוטמעות בו, ותגי הסקריפט מסודרים לפי הסדר הנכון. פרויקט שמגדיר --accent או --line משלו יורש אותם אוטומטית. הרכיב הזה מסתמך על dir="rtl".
/* מחלקות עזר של המאגר שהרכיב הזה משתמש בהן */
.stage{padding:var(--sec, clamp(120px, 12vw, 260px)) var(--gutter, clamp(24px, 5vw, 96px));position:relative}
.stage.tight{padding-block:clamp(48px,5vw,90px)}
.stage.full{padding-inline:0}
/* G88 · מילה שמתחלפת בהירו בלולאה */
.rw{text-align:center;max-width:46ch;margin-inline:auto}
.rw-keep{white-space:nowrap}
.rw h2{font-size:var(--fs-h2, clamp(28px, 1.9vw + 0.5rem, 52px));line-height:1.25;margin:0}
.rw-slot{display:inline-grid;justify-items:start;vertical-align:bottom;text-align:start;overflow:hidden;color:var(--accent, #4a3aff);height:1.25em;width:var(--w,auto);transition:/* qa-allow: layout, רוחב המילה משתנה בהגדרה, scaleX היה מעוות את האותיות */width .5s cubic-bezier(.2,.6,.2,1)}
.rw-slot span{grid-area:1/1;white-space:nowrap;opacity:0;translate:0 100%}
.rw-slot span:first-child{opacity:1;translate:0 0}
@media (prefers-reduced-motion: reduce){.rw-slot{transition:none}}
<div class="stage"><div class="rw"><h2>אנחנו בונים אתרים <span class="rw-keep">ל<span class="rw-slot"><span>קליניקות</span><span>משרדי עורכי דין</span><span>חנויות אונליין</span><span>סטודיו לעיצוב</span></span></span><br>שמביאים פניות, לא רק מחמאות.</h2></div></div>
(function(){
const slot=document.querySelector(".rw-slot"),words=gsap.utils.toArray(".rw-slot span");
const reduce=matchMedia("(prefers-reduced-motion: reduce)").matches;
const widths=words.map(w=>w.getBoundingClientRect().width);
slot.style.setProperty("--w",widths[0]+"px");
let i=0;
function next(){
const cur=words[i],nx=words[(i+1)%words.length];i=(i+1)%words.length;
slot.style.setProperty("--w",widths[i]+"px");
if(reduce){gsap.set(cur,{opacity:0});gsap.set(nx,{opacity:1,translate:"0 0"});return;}
gsap.timeline()
.to(cur,{translate:"0 -100%",opacity:0,duration:.5,ease:"power3.in"},0)
.fromTo(nx,{translate:"0 100%",opacity:0},{translate:"0 0",opacity:1,duration:.55,ease:"power3.out"},.25);
}
setTimeout(next,900); setInterval(next,reduce?3000:2200); // החלפה ראשונה מהר, אחר כך בקצב קריאה
addEventListener("resize",()=>{words.forEach((w,k)=>widths[k]=w.getBoundingClientRect().width);slot.style.setProperty("--w",widths[i]+"px");});
})();