<div class="wrapper">
<div class="container">
<p class="text" data-char-span data-text-animation="fadeIn">
吾輩は猫である。
</p>
<p class="text" data-char-span data-text-animation="fadeIn">
名前はまだない。
</p>
</div>
<p class="note">再読み込みするにはReturnを押してください↓↓↓</p>
</div>
.wrapper {
--_base-height: 95svh;
--_note-height: 1lh;
min-height: var(--_base-height);
}
.container {
min-height: calc(var(--_base-height) - var(--_note-height));
padding-top: var(--_note-height);
display: grid;
place-content: center;
}
.text {
font-size: max(20px, 5vw);
font-weight: 700;
line-height: 1.5;
letter-spacing: 0.1em;
text-align: center;
}
.note {
text-align: right;
}
.alternative {
position: fixed !important;
inset: 0 !important;
display: block !important;
inline-size: 4px !important;
block-size: 4px !important;
contain: strict !important;
pointer-events: none !important;
opacity: 0 !important;
}
/* アニメーション前 */
[data-text-animation="fadeIn"] span {
opacity: 0;
transition: opacity 1s;
}
/* アニメーション後 */
[data-text-animation="fadeIn"] span.is-active {
opacity: 1;
}
// 1文字づつspanタグで囲う関数
const wrapCharactersWithSpan = (element, className = "") => {
const text = element.textContent.trim();
const characters = text.split("");
let wrappedContent = "";
characters.forEach((char, index) => {
if (char === " ") {
wrappedContent += '<span aria-hidden="true"> </span>';
} else {
wrappedContent += `<span class="${className}" aria-hidden="true" translate="no" style="--index: ${index};">${char}</span>`;
}
});
wrappedContent += `<span class="alternative">${text}</span>`;
element.innerHTML = wrappedContent;
};
const chars = document.querySelectorAll("[data-char-span]");
// 1文字づつspanタグで囲う関数を実行
chars.forEach((char) => {
wrapCharactersWithSpan(char);
});
// テキストアニメーションの一連の処理
const fadeInChars = document.querySelectorAll(
'[data-text-animation="fadeIn"] span'
); // アニメーション対象の要素をNodeListとして取得
const spansArray = Array.from(fadeInChars); // NodeListを配列に変換
// ランダムに要素を選択してアクティブ化する関数
const addActiveClassRandomly = () => {
if (spansArray.length === 0) return; // 配列が空の場合は処理を終了
const randomIndex = Math.floor(Math.random() * spansArray.length); // 0から配列の長さ-1までのランダムな整数を生成
const randomSpan = spansArray[randomIndex]; // ランダムに選択された要素を取得
randomSpan.classList.add("is-active"); // 選択された要素にis-activeを追加
spansArray.splice(randomIndex, 1); // 処理済みの要素を配列から削除
if (spansArray.length > 0) {
// 配列の要素数が0になるまで
setTimeout(addActiveClassRandomly, 100); // 100ミリ秒後に再帰的に関数を呼び出し
}
};
addActiveClassRandomly(); // アニメーション処理の開始
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.