縦書きのテキストを、ネイティブなJavaScriptを使い「タイピング風」に一文字ずつ表示させてみます。
「端的で、メッセージ性の強いクリエイティブに使える」スニペットなので、引き出しの一つにでもなるよう参考にしてみてください。
IntersectionObserver
Intersection Observer APIを、Google翻訳で訳すと「交差点オブザーバーAPI」という名前です。これは要素と要素の交差を検知するAPIです。
スクロールに対応したアニメーションは、「Intersection Observer API」で要素の検知をして、アニメーションをCSSで別途作ることで、簡単にスクロールアニメーションを実装することができます。
以下に詳しくあるので、こちらもあわせて参考にしてみてください。
参考 Intersection Observer APIMDN web docs縦書きタイピングテキストのサンプル
早速サンプルです。
以下のブロックがウィンドウ内に入ると、真ん中にある「朝は、一杯のコーヒー。」のテキストがタイピングされるように縦書きで一文字ずつ表示されます。
ウィンドウ内に入るとテキストが表示されるので、もう一度タイピングの様子を見たい場合は、下にスクロールしてから再度このブロックをウィンドウに入れてみてください。
もう一度戻るとタイピング風にテキストが表示されます。
実装の手順と方法
コードの解説の前に、実装の手順と方法について解説します。
はじめに、設置したい場所にHTMLを記述します。
<div class="bgimg">
<video src="https://dubdesign.net/wp-content/uploads/2022/06/movie.mp4" autoplay loop muted></video>
<div class="text">朝は、一杯のコーヒー。</div>
</div>
次に、JavaScriptのコードをページに記述します。
コードは <body>〜</body>
で、</body>
の閉じタグ(クロージングタグ)の前に記述しましょう。
const doObserve = (element) => {
const targets = document.querySelectorAll('.text'); /* ターゲットの指定 */
const options = {
root: null,
rootMargin: '0px',
threshold: 0
};
const observer = new IntersectionObserver((items) => {
items.forEach((item) => {
if (item.isIntersecting) {
item.target.classList.add('typing'); /* スクロールでターゲットに付与するclassの指定 */
} else {
item.target.classList.remove('typing'); /* 表示域から外れた時にターゲットから削除するclassの指定 */
}
});
}, options);
Array.from(targets).forEach((target) => {
observer.observe(target);
});
};
doObserve('.observe_target');
最後に、CSSを記述します。
.bgimg {
position: relative;
}
.bgimg video {
width: 100%;
object-fit: cover;
height: 400px;
filter: blur(1px);
}
.text.typing {
display: inline-block;
overflow: hidden;
white-space: nowrap;
border-bottom: 2px solid transparent;
animation: typing 3s steps(23), caret 0.3s steps(1) infinite;
margin: 0;
line-height: 1.7;
max-width: 300px;
font-size: 1.5rem;
max-height: 300px;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
height: 100%;
position: absolute;
top: 30px;
left: 50%;
transform: translateX(-50%);
font-weight: 600;
letter-spacing: 0.04rem;
color: #FFF;
text-shadow: 0px 0px 4px #000;
}
@keyframes typing {
from {
height: 0;
}
}
@keyframes caret {
50% {
border-bottom-color: currentColor;
}
}
これで完成です。
ざっくりとしたコードの解説
コードは、HTML・JavaScript・CSSの3種です。順に解説していきます。
HTML
HTMLは、「bgimg」のclass名がつく親要素を作り、その中にmp4の動画と、縦書きのテキストを格納します。
<div class="bgimg">
<video src="https://dubdesign.net/wp-content/uploads/2022/06/movie.mp4" autoplay loop muted></video>
<div class="text">朝は、一杯のコーヒー。</div>
</div>
特にこれといった内容はありません。
JavaScript
JavaScriptは、ざっくり言うと「ターゲットの指定」を行い、条件分岐で処理方法をそれぞれ記述します。
const doObserve = (element) => {
const targets = document.querySelectorAll('.text'); /* ターゲットの指定 */
const options = {
root: null,
rootMargin: '0px',
threshold: 0
};
const observer = new IntersectionObserver((items) => {
items.forEach((item) => {
if (item.isIntersecting) {
item.target.classList.add('typing'); /* スクロールでターゲットに付与するclassの指定 */
} else {
item.target.classList.remove('typing'); /* 表示域から外れた時にターゲットから削除するclassの指定 */
}
});
}, options);
Array.from(targets).forEach((target) => {
observer.observe(target);
});
};
doObserve('.observe_target');
具体的には、冒頭にある option
で「root」のキーを「null」に設定することで、要素がウィンドウに入ったかどうかの検知ができるようになります。
そして、検知された時に実行される処理は、まず IntersectionObserver
を作成し、要素に対しての検知を行なっていくと、検知したオブジェクトを取得できるようになります。
CSS
この記事の特徴「縦書き」の部分は、-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
の2行のコードで縦書きになります。
.bgimg {
position: relative;
}
.bgimg video {
width: 100%;
object-fit: cover;
height: 400px;
filter: blur(1px);
}
.text.typing {
display: inline-block;
overflow: hidden;
white-space: nowrap;
border-bottom: 2px solid transparent;
animation: typing 3s steps(23), caret 0.3s steps(1) infinite;
margin: 0;
line-height: 1.7;
max-width: 300px;
font-size: 1.5rem;
max-height: 300px;
-ms-writing-mode: tb-rl;
writing-mode: vertical-rl;
height: 100%;
position: absolute;
top: 30px;
left: 50%;
transform: translateX(-50%);
font-weight: 600;
letter-spacing: 0.04rem;
color: #FFF;
text-shadow: 0px 0px 4px #000;
}
@keyframes typing {
from {
height: 0;
}
}
@keyframes caret {
50% {
border-bottom-color: currentColor;
}
}
タイピングのアニメーションは、@keyframes typing
の height:0;
をスタート時の高さで指定して、徐々に高さを展開していくことでタイピングのアニメーションで表示させています。
さいごに
JavaScriptでアニメーションをつける・つけないは別にして、縦書きのテキストにさせる方法も覚えておくと便利です。
今回の記事では、縦に1行の場合のタイピングでしたが、縦に2行ある場合のアニメーションは、また別の記事にしてみようと思います。