【フェーダー】タイプライター風にテキストを表示

ページ表示時にタイプライター風にテキストを表示します。カーソルの点滅動作はCSSで実装します。

タイプライター風テキスト

htmlのコードは下記になります。カーソルは空のspanタグで表示します。

<p id="js-visual_txt" class="visual_txt"><b>タイプライター風テキスト</b><span class="visual_cursor"></span></p>

続いてCSSのコードです。
テキストとカーソルはフレックスボックスで横並びにします。テキストはspanタグで内包してbタグ内に出力しますが、このspanタグもフレックスボックスで横並びにします。spanタグには動的にカスタムデータ属性を付与しますが、カスタムデータ属性の値がload以外の時は横幅を0で設定し、値がloadになった時点で1emにします。
カーソルには点滅するanimationを指定します。点滅は止めないためanimation-iteration-count: infiniteを指定します。また点滅の動作は@keyframes以外にanimation-timing-function: steps(1)とanimation-direction: alternateで実現しています。

.visual_txt {
	font-size: 40px;
	font-weight: bold;
	display: flex;
	align-items: center;
	justify-content: center;
	opacity: 0;
}
.visual_txt.isLoaded {
	opacity: 1;
}
.visual_txt > b {
	display: flex;
	align-items: center;
}
.visual_txt > b > [data-char] {
	display: block;
	width: 0;
	overflow: hidden;
	transition-property: width;
	transition-duration: 0s;
}
.visual_txt > b > [data-char="load"] {
	width: 1em;
}
.visual_cursor {
	display: block;
	width: 2px;
	height: 40px;
	background: #000;
	animation-name: cursor;
	animation-duration: 0.5s;
	animation-iteration-count: infinite;
	animation-timing-function: steps(1);
	animation-fill-mode: backwards;
	animation-direction: alternate;
}
@keyframes cursor {
	0% {
		opacity: 0;
	}
	50% {
		opacity: 1;
	}
	100% {
		opacity: 1;
	}
}
@media screen and (max-width: 680px) {
	.visual_txt {
		font-size: 20px;
	}
	.visual_cursor {
		width: 1px;
		height: 20px;
	}
}

最後にjQueryのコードです。
まず1番目の処理として、spritStr関数を呼び出してテキストを1文字ずつspanタグで内包します。その際カスタムデータ属性をinitの値で付与します。次にタイプライター風に時間差でテキストが表示されるように、1文字ずつspanタグのCSSにtransition-delayを設定します。最後にprop(‘outerHTML’)で要素自身を含めたhtmlを変数htmlに代入していきます。これを文字の数だけ繰り返して、spanタグをbタグ内にセットします。
2番目の処理はテキストとカーソルを含むpタグにクラス名isLoadedを付与します。これでpタグのopacityは1となりますが、spanタグはwidth: 0のためまだ非表示の状態です。
最後に3番目の処理として、spanタグのカスタムデータ属性の値をinitからloadへ変更します。これでspanタグのwidthが1emとなります。ポイントはsetTimeoutを入れてinitとloadの状態に時間差を付けることです。この処理がないとtransition-delayが発動できず、全ての文字が1度に表示されてしまいます。

$(function() {
	function spritStr(str) {
		var html = '',
			obj;
		for (i = 0; i < str.length; i++) {
			obj = $('<span data-char="init">' + str.substr(i, 1) + '</span>');
			$(obj).css({
				'transition-delay': i * 0.2 + 's'
			});
			html += $(obj).prop('outerHTML');
		}
		return html;
	}
	$('#js-visual_txt > b').html(spritStr($('#js-visual_txt > b').text()));
	$('#js-visual_txt').addClass('isLoaded');
	setTimeout(function () {
		$('#js-visual_txt > b > [data-char="init"]').attr('data-char', 'load');
	}, 100);
});
タイトルとURLをコピーしました