[JavaScript]一文字ずつ表示するアニメーション(+画面内にはいったら開始)

まるでタイピングしている様に一文字ずつ表示していくアニメーションを作成してみます。
画面内に入ったら表示が始まる設定も解説します。

コードの利用は自己責任でお願いします。

デモ&使い方

まるでタイピングしている様に一文字ずつ表示

<p class="typeing" data-speed="100">まるでタイピングしている様に一文字ずつ表示</p>

表示速度も変更可能です

<p class="typeing" data-speed="300">表示速度も変更可能です</p>

class「typeing」を設定したテキストにアニメーションが付きます。
属性「data-speed」で表示スピードを設定できます。

CSS

.typeing {
    opacity: 0;
}

.typeing.active {
    opacity: 1;
}

表示時にちらつかない様に、Opacityの設定のみしておきます。

JavaScript

const typeTarget = document.querySelectorAll('.typeing');

typeTarget.forEach(el => {
    let typeContent = el.textContent;
    let typeSprit = typeContent.split('');
    let typeSpeed = el.getAttribute('data-speed');
    el.textContent = '';
    el.classList.add('active');

    let typeLength = 0;
    let typeInterval = setInterval(() => {
        if (typeSprit[typeLength] == undefined) {
            clearInterval(typeInterval);
            return false;
        }
        entry.target.textContent += typeSprit[typeLength];
        typeLength++;
    }, typeSpeed);

});

簡単な解説:
クラスが付与された要素の文字を一文字ずつとりだして配列に入れ、テキストを一旦空白にします。
その後、配列に入れた文字をsetintervalで指定した秒数ごとにテキストに挿入することでアニメーション表示を行なっています。

画面内に入ったら開始

上記のみだとページを開くと同時に全ての表示が始まってしまうので、画面内に入ったら表示が始まるものも作ってみます。
IntersectionObserverを使用します。

const typeTarget = document.querySelectorAll('.typeing');

let options = {
    rootMargin: '0px',
    threshold: .5
}

let callback = (entries, observer) => {
    entries.forEach(entry => {
        if (entry.intersectionRatio > .5 && entry.target.classList.contains('active') == false) {
            let typeContent = entry.target.textContent;
            let typeSprit = typeContent.split('');
            let typeSpeed = entry.target.getAttribute('data-speed');
            entry.target.textContent = '';
            entry.target.classList.add('active');

            let typeLength = 0;
            let typeInterval = setInterval(() => {
                if (typeSprit[typeLength] == undefined) {
                    clearInterval(typeInterval);
                    return false;
                }
                entry.target.textContent += typeSprit[typeLength];
                typeLength++;
            }, typeSpeed);

        }
    });
}

let observer = new IntersectionObserver(callback, options);

typeTarget.forEach(e => {
    observer.observe(e);
});

このテキストは画面内に入ったら表示が始まるので、試してみてください。

以上で完成です。

タイトルとURLをコピーしました