生成AI+スマホで作成「WordPress(ブログ)で使えるJavaScript」 入れ替わる文字列

最初の文字列
入れ替わった文字列
コードエディター 本文

<div class="stage">
    <div id="text-bottom" class="text-unit">最初の文字列</div>
    <div id="text-top" class="text-unit">入れ替わった文字列</div>
</div>

カスタムJavaScript

    window.onload = () => {
        // 2秒待機してから実行
        setTimeout(startAnimation, 1000);
    };

    function startAnimation() {
        const topEl = document.getElementById('text-top');
        const bottomEl = document.getElementById('text-bottom');
        
        const duration = 3000; // 削り取るスピード
        const startTime = performance.now();

        function step(currentTime) {
            const elapsed = currentTime - startTime;
            const progress = Math.min(elapsed / duration, 1);
            
            // progress: 0 (開始) -> 1 (終了)
            
            // 下の文字を上から削る (0%消えている -> 100%消えている)
            const bottomInset = progress * 100;
            bottomEl.style.clipPath = `inset(${bottomInset}% 0 0 0)`;

            // 上の文字を上から出す (100%隠れている -> 0%隠れている)
            // 下の文字が削られた分だけ、上の文字が見えてくる
            const topInset = 100 - (progress * 100);
            topEl.style.clipPath = `inset(0 0 ${topInset}% 0)`;

            if (progress < 1) {
                requestAnimationFrame(step);

カスタムCSS

        .stage {
            font-size: 2rem;
            font-weight: 900;
            height: 100px; /* 指定の高さ */
            width: 100%;
            display: flex;
            justify-content: center;
            align-items: center; /* 中央揃え */
            background: #fff;
            position: relative;
            overflow: hidden;
            font-family: sans-serif;
        }

        .text-unit {
            position: absolute;
            line-height: 100px; /* 高さと同じにすると中央にきます */
            white-space: nowrap;
        }

        #text-bottom {
            color: #333;
            z-index: 1;
        }

        #text-top {
            color: #e63946;
            z-index: 2;
            /* 最初は上端(0px)に配置し、高さ0(見えない状態)から開始 */
            transform: translateY(0); 
            clip-path: inset(0 0 100% 0); 
        }