JSFiddle - React, Tailwind, and code Playground

by joepenzo

HTML

<p class="split-text">Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Nullam quis risus eget urna mollis ornare vel eu leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>


<h1 class="block-reveal" style="--reveal-speed: 2;">
    <span style="--delay: 2.0; --color: #c0ffee;">Cum sociis natoque</span>
    <span style="--delay: 2.2; --color: #c0ffee;">penatibus et</span>
</h1>

<br><br>

<h1 class="block-reveal">
   <span style="--delay: 1.0">Vestibulum id ligula porta</span>
   <span style="--delay: 1.2">felis euismod semper.</span>
   <span style="--delay: 1.4">Praesent commodo cursus magna,</span>
   <span style="--delay: 1.6">vel scelerisque nisl consectetur et.</span>
</h1>

<br><br>

<h2 class="block-reveal" style="--reveal-speed: 0.75">
    <span style="--delay: 1.0; --color: #ff0000">Een</span>
    <span style="--delay: 1.1; --color: #00ff00">Twee</span>
    <span style="--delay: 1.2; --color: #0000ff">Drie</span>
</h2>

SCSS

/* h1 {
  max-width: 700px;
  display: block;
}

* {
  box-sizing: border-box;
} */

p { 
    > * {
        border: 1px solid green;
    }
    width: 80%;
    white-space: pre;
    font-size: 40px;
}

/* 
:root {
  --base-delay: 0.5;
  --reveal-speed: 0.75;
  --stagger: 0.1;
}


.block-reveal {
  align-items: flex-start;
  display: inline-flex;
  flex-direction: column;
  font-size: 3.25rem;

  span {
    animation: show-text calc(var(--reveal-speed, 0.5) * 1s) calc(var(--delay, 1) * 1s) steps(1) both;
    overflow: hidden;
    position: relative;

    &:after {
      content: '';
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      background: var(--color, red);
      position: absolute;
      animation: block-reveal calc(var(--reveal-speed, 0.5) * 1s) calc(var(--delay, 1) * 1s) both;
    }
  }
}

 

@keyframes block-reveal {
  0% {
    transform: translate(-110%, 0);
  }

  45%, 55% {
    transform: translate(0, 0);
  }

  100% {
    transform: translate(110%, 0);
  }
}

@keyframes show-text {
  0% {
    color: transparent;
  }

  50%,
  100% {
    color: #000;
  }
} 
 */

TypeScript

function splitTextIntoSpansByLine(element: HTMLElement) {
    const originalText = element.textContent || "";
    element.innerHTML = ""; // Maak de originele inhoud leeg

    const tempSpan = document.createElement('span');
    tempSpan.style.whiteSpace = 'pre-wrap'; // Zorg dat nieuwe regels en witruimte behouden blijven
    tempSpan.style.visibility = 'hidden';
    tempSpan.style.position = 'absolute'; 
    tempSpan.style.width = getComputedStyle(element).width; // Breedte van het originele element

    document.body.appendChild(tempSpan); // Voeg de tijdelijke span toe aan de body

    let currentIndex = 0;
    let previousBottom = -1;
    let breakPoint = 0;

    while (currentIndex < originalText.length) {
        tempSpan.textContent = originalText.substring(currentIndex); // Stel tekst in om te evalueren

        const range = document.createRange();
        range.selectNodeContents(tempSpan);

        let charIndex = 0;
        previousBottom = -1;

        while (charIndex < tempSpan.textContent!.length) {
            range.setEnd(tempSpan.firstChild!, charIndex + 1);
            const rects = range.getClientRects();

            if (rects.length > 0 && rects[0].bottom !== previousBottom) {
                if (previousBottom !== -1) {
                    break; // Regelovergang gevonden
                }
                previousBottom = rects[0].bottom; // Update de vorige regel
            }

            charIndex++;
            breakPoint = currentIndex + charIndex;
        }

        // Voeg de tekst tot de regelovergang toe aan een nieuwe span
        const span = document.createElement('span');
        span.textContent = originalText.substring(currentIndex, breakPoint);
        element.appendChild(span);

        currentIndex = breakPoint;
    }

    document.body.removeChild(tempSpan); // Verwijder de tijdelijke span
}

// Pas de functie toe op alle elementen met de class 'split-text'
function splitTextOnClass(className: string) {
    const...