CSS3のアニメーションで、タイミングをJavaScriptで管理する

JavaScriptでスクロール位置を管理して、対象要素が画面上に表示されたらclassを追加して、CSS3のアニメーションを行う処理を実装してみます。

サンプルコード

スクロールで対象要素が表示されたら、フェードインしながら下から上に表示するアニメーションを実装してみます。

HTML

画像とテキストを左右に配置するレイアウトで、アニメーションさせる要素に対して.animation-scrollUp を追加しています。

<div class="image-block image-block_left">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img01.jpg" width="450" alt="" class="animation-scrollUp" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollUp">キャッチコピー的なテキスト</p>
			<p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>
<div class="image-block image-block_right">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img02.jpg" width="450" alt="" class="animation-scrollUp" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollUp">キャッチコピー的なテキスト</p>
			<p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>
<div class="image-block image-block_left">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img03.jpg" width="450" alt="" class="animation-scrollUp" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollUp">キャッチコピー的なテキスト</p>
			<p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>
<div class="image-block image-block_right">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img04.jpg" width="450" alt="" class="animation-scrollUp" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollUp">キャッチコピー的なテキスト</p>
			<p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>

CSS

まずはレイアウトを行っている部分のCSSです。

/* 要素配置のスタイル */
.image-block {
	padding: 150px 0;
	overflow: hidden;
}
.image-block_left {
	background: #ecf0f1;
}
.image-block_right {
	background: #cfe9fa;
}
.image-block_inner {
	width: 1000px;
	margin: 0 auto;
}
.image-block_img {
	
}
.image-block_left .image-block_img {
	float: left;
}
.image-block_right .image-block_img {
	float: right;
}
.image-block_text {
	width: 500px;
}
.image-block_left .image-block_text {
	float: right;
}
.image-block_right .image-block_text {
	float: left;
}
.image-block_ttl {
	color: #3498DB;
	font-size: 32px;
	margin-bottom: 20px;
}
.image-block_description {
	line-height: 1.8;
}

CSS

アニメーション部分のCSSです。
アニメーションはtransitionで行っていて、.is-animatedが追加されたタイミングでtransformとopacityの値を変更するようにしています。

/* アニメーションのスタイル */
.animation-scrollUp {
	-webkit-transform: translateY(40px);
	transform: translateY(40px);
	opacity: 0;
	-webkit-transition: 0.8s;
	transition: 0.8s;
}
.animation-scrollUp.is-animated {
	-webkit-transform: translateY(0);
	transform: translateY(0);
	opacity: 1;
}

JavaScript

スクロール毎に対象要素が画面内に表示されたかどうかを確認して、表示されている場合はclassを追加してアニメーションを実行させています。

$(function() {
	$(window).on('load scroll', function() {
		setAnimationClass();
	});

	var animationClass = 'animation-scrollUp'; // アニメーション対象のclass名
	var animationFinClass = 'is-animated'; // アニメーションが実行時に付与するclass名
	var animationStartPosition = 0.75; // アニメーションが実行されるスクロール位置

	// アニメーションが完了しているかどうかを管理する配列
	var animationFlagArr = [];
	for(var i = 0; i < $('.' + animationClass).length; i++) {
		animationFlagArr[i] = false;
	}

	function setAnimationClass() {
		// アニメーションの実行前に、アニメーション完了済の要素を確認しておく
		for(var i = 0; i < $('.' + animationClass).length; i++) {
			if($('.' + animationClass).eq(i).hasClass(animationFinClass)) {
				animationFlagArr[i] = true;
			}
		}

		// スクロール位置と画面高さを取得
		var scrollTop = $(window).scrollTop();
		var windowHeight = $(window).height();

		// アニメーション対象要素が開始位置までスクロールしている場合、classを付与する
		for(var i = 0; i < animationFlagArr.length; i++) {
			if(animationFlagArr[i] == false) {
				var thisElement = $('.' + animationClass).eq(i);
				var thisTop = thisElement.offset().top;
				if(scrollTop + (windowHeight * animationStartPosition) > thisTop) {
					thisElement.addClass(animationFinClass);
				}
			}
		}
	}
});

アニメーションのデモページ
 

サンプルコード2

テキストを1文字ずつ分解してアニメーションさせてみます。

HTML

基本的には先ほどと同じ構造で、アニメーションさせる要素に対して.animation-scrollRotateを追加しています。

<div class="image-block image-block_left">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img01.jpg" width="450" alt="" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p>
			<p class="image-block_description">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>
<div class="image-block image-block_right">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img02.jpg" width="450" alt="" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p>
			<p class="image-block_description">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>
<div class="image-block image-block_left">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img03.jpg" width="450" alt="" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p>
			<p class="image-block_description">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>
<div class="image-block image-block_right">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img04.jpg" width="450" alt="" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p>
			<p class="image-block_description">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>

CSS

アニメーションは.animation-scrollRotateではなく、その子要素のspanに対して設定しています。

/* アニメーションのスタイル */
.animation-scrollRotate span {
	display: inline-block;
	-webkit-transform: rotate(-90deg);
	transform: rotate(-90deg);
	opacity: 0;
	-webkit-transition: 0.8s;
	transition: 0.8s;
	-webkit-transition-property: transform, opacity;
	transition-property: transform, opacity;
}
.animation-scrollRotate.is-animated span {
	-webkit-transform: rotate(0deg);
	transform: rotate(0deg);
	opacity: 1;
}

JavaScript

アニメーション部分は先ほどとほぼ同じですが、最初に対象要素のテキストを1文字ずつ分解してspanで括るようにしています。

$(function() {
	$(window).on('load scroll', function() {
		setAnimationClass();
	});

	var animationClass = 'animation-scrollRotate'; // アニメーション対象のclass名
	var animationFinClass = 'is-animated'; // アニメーションが実行時に付与するclass名
	var animationStartPosition = 0.75; // アニメーションが実行されるスクロール位置

	// アニメーションが完了しているかどうかを管理する配列
	var animationFlagArr = [];
	for(var i = 0; i < $('.' + animationClass).length; i++) {
		animationFlagArr[i] = false;

		var thisText = $('.' + animationClass).eq(i).text().split('');
		var animationTextInsert = '';
		for(var j = 0; j < thisText.length; j++) {
			animationTextInsert += '<span>' + thisText[j] + '</span>'
		}
		$('.' + animationClass).eq(i).html(animationTextInsert);
	}

	function setAnimationClass() {
		// アニメーションの実行前に、アニメーション完了済の要素を確認しておく
		for(var i = 0; i < $('.' + animationClass).length; i++) {
			if($('.' + animationClass).eq(i).hasClass(animationFinClass)) {
				animationFlagArr[i] = true;
			}
		}

		// スクロール位置と画面高さを取得
		var scrollTop = $(window).scrollTop();
		var windowHeight = $(window).height();

		// アニメーション対象要素が開始位置までスクロールしている場合、classを付与する
		for(var i = 0; i < animationFlagArr.length; i++) {
			if(animationFlagArr[i] == false) {
				var thisElement = $('.' + animationClass).eq(i);
				var thisTop = thisElement.offset().top;
				if(scrollTop + (windowHeight * animationStartPosition) > thisTop) {
					thisElement.addClass(animationFinClass);
				}
			}
		}
	}
});

一文字ずつアニメーションさせるデモページ
 

アニメーションのタイミングを1文字ずつずらしたい場合、1文字ずつtransition-delayをずらして設定します。

CSS

/* アニメーションのスタイル */
.animation-scrollRotate span {
	display: inline-block;
	-webkit-transform: rotate(-90deg);
	transform: rotate(-90deg);
	opacity: 0;
	-webkit-transition: 0.8s;
	transition: 0.8s;
	-webkit-transition-property: transform, opacity;
	transition-property: transform, opacity;
}
.animation-scrollRotate.is-animated span {
	-webkit-transform: rotate(0deg);
	transform: rotate(0deg);
	opacity: 1;
}
.animation-scrollRotate span:nth-child(2)  {-webkit-transition-delay: 0.1s;transition-delay: 0.1s;}
.animation-scrollRotate span:nth-child(3)  {-webkit-transition-delay: 0.2s;transition-delay: 0.2s;}
.animation-scrollRotate span:nth-child(4)  {-webkit-transition-delay: 0.3s;transition-delay: 0.3s;}
.animation-scrollRotate span:nth-child(5)  {-webkit-transition-delay: 0.4s;transition-delay: 0.4s;}
.animation-scrollRotate span:nth-child(6)  {-webkit-transition-delay: 0.5s;transition-delay: 0.5s;}
.animation-scrollRotate span:nth-child(7)  {-webkit-transition-delay: 0.6s;transition-delay: 0.6s;}
.animation-scrollRotate span:nth-child(8)  {-webkit-transition-delay: 0.7s;transition-delay: 0.7s;}
.animation-scrollRotate span:nth-child(9)  {-webkit-transition-delay: 0.8s;transition-delay: 0.8s;}
.animation-scrollRotate span:nth-child(10) {-webkit-transition-delay: 0.9s;transition-delay: 0.9s;}
.animation-scrollRotate span:nth-child(11) {-webkit-transition-delay: 1.0s;transition-delay: 1.0s;}
.animation-scrollRotate span:nth-child(12) {-webkit-transition-delay: 1.1s;transition-delay: 1.1s;}
.animation-scrollRotate span:nth-child(13) {-webkit-transition-delay: 1.2s;transition-delay: 1.2s;}
.animation-scrollRotate span:nth-child(14) {-webkit-transition-delay: 1.3s;transition-delay: 1.3s;}
.animation-scrollRotate span:nth-child(15) {-webkit-transition-delay: 1.4s;transition-delay: 1.4s;}

一文字ずつタイミングをずらしてアニメーションさせるデモページ
 

サンプルコード3

アニメーションの種類を複数設定してみます。

HTML

画像、タイトル、本文のそれぞれでアニメーションを変更してみます。
それぞれ.animation-scrollScale、.animation-scrollRotate、animation-scrollUpとclassを追加しています。

<div class="image-block image-block_left">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img01.jpg" width="450" alt="" class="animation-scrollScale" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p>
			<p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>
<div class="image-block image-block_right">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img02.jpg" width="450" alt="" class="animation-scrollScale" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p>
			<p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>
<div class="image-block image-block_left">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img03.jpg" width="450" alt="" class="animation-scrollScale" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p>
			<p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>
<div class="image-block image-block_right">
	<div class="image-block_inner">
		<div class="image-block_img">
			<img src="./img04.jpg" width="450" alt="" class="animation-scrollScale" />
		</div>
		<div class="image-block_text">
			<p class="image-block_ttl animation-scrollRotate">キャッチコピー的なテキスト</p>
			<p class="image-block_description animation-scrollUp">キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。<br />
			キャッチコピーに対する説明文が入ります。キャッチコピーに対する説明文が入ります。</p>
		</div>
	</div>
</div>

CSS

transitionを使ってアニメーションを設定しています。

/* アニメーションのスタイル */
.animation-scrollUp {
	-webkit-transform: translateY(40px);
	transform: translateY(40px);
	opacity: 0;
	-webkit-transition: 0.8s;
	transition: 0.8s;
}
.animation-scrollUp.is-animated {
	-webkit-transform: translateY(0);
	transform: translateY(0);
	opacity: 1;
}

.animation-scrollRotate span {
	display: inline-block;
	-webkit-transform: rotate(-90deg);
	transform: rotate(-90deg);
	opacity: 0;
	-webkit-transition: 0.8s;
	transition: 0.8s;
	-webkit-transition-property: transform, opacity;
	transition-property: transform, opacity;
}
.animation-scrollRotate.is-animated span {
	-webkit-transform: rotate(0deg);
	transform: rotate(0deg);
	opacity: 1;
}
.animation-scrollRotate span:nth-child(2)  {-webkit-transition-delay: 0.1s;transition-delay: 0.1s;}
.animation-scrollRotate span:nth-child(3)  {-webkit-transition-delay: 0.2s;transition-delay: 0.2s;}
.animation-scrollRotate span:nth-child(4)  {-webkit-transition-delay: 0.3s;transition-delay: 0.3s;}
.animation-scrollRotate span:nth-child(5)  {-webkit-transition-delay: 0.4s;transition-delay: 0.4s;}
.animation-scrollRotate span:nth-child(6)  {-webkit-transition-delay: 0.5s;transition-delay: 0.5s;}
.animation-scrollRotate span:nth-child(7)  {-webkit-transition-delay: 0.6s;transition-delay: 0.6s;}
.animation-scrollRotate span:nth-child(8)  {-webkit-transition-delay: 0.7s;transition-delay: 0.7s;}
.animation-scrollRotate span:nth-child(9)  {-webkit-transition-delay: 0.8s;transition-delay: 0.8s;}
.animation-scrollRotate span:nth-child(10) {-webkit-transition-delay: 0.9s;transition-delay: 0.9s;}
.animation-scrollRotate span:nth-child(11) {-webkit-transition-delay: 1.0s;transition-delay: 1.0s;}
.animation-scrollRotate span:nth-child(12) {-webkit-transition-delay: 1.1s;transition-delay: 1.1s;}
.animation-scrollRotate span:nth-child(13) {-webkit-transition-delay: 1.2s;transition-delay: 1.2s;}
.animation-scrollRotate span:nth-child(14) {-webkit-transition-delay: 1.3s;transition-delay: 1.3s;}
.animation-scrollRotate span:nth-child(15) {-webkit-transition-delay: 1.4s;transition-delay: 1.4s;}

.animation-scrollScale {
	-webkit-transform: scale(1.2);
	transform: scale(1.2);
	opacity: 0;
	-webkit-transition: 0.8s;
	transition: 0.8s;
}
.animation-scrollScale.is-animated {
	-webkit-transform: scale(1);
	transform: scale(1);
	opacity: 1;
}

JavaScript

classなどを配列で管理するように変更して、複数のclassを設定できるように変更しています。
タイトル部分だけ1文字ずつアニメーションさせるため、19~28行目でspanを追加しています。

$(function() {
	$(window).on('load scroll', function() {
		setAnimationClass();
	});

	var animationClassArr = ['animation-scrollUp', 'animation-scrollRotate', 'animation-scrollScale']; // アニメーション対象のclass名
	var animationFinClassArr = ['is-animated', 'is-animated', 'is-animated']; // アニメーションが実行時に付与するclass名
	var animationStartPositionArr = [0.75, 0.75, 0.75]; // アニメーションが実行されるスクロール位置

	// アニメーションが完了しているかどうかを管理する配列
	var animationFlagArr = {};
	for(var i = 0; i < animationClassArr.length; i++) {
		animationFlagArr[animationClassArr[i]] = [];
		for(var j = 0; j < $('.' + animationClassArr[i]).length; j++) {
			animationFlagArr[animationClassArr[i]][j] = false;
		}
	}

	// .animation-scrollRotateのテキストにspan追加
	for(var i = 0; i < $('.' + animationClassArr[1]).length; i++) {
		var thisElem = $('.' + animationClassArr[1]).eq(i);
		var thisText = thisElem.text().split('');
		var animationTextInsert = '';
		for(var j = 0; j < thisText.length; j++) {
			animationTextInsert += '<span>' + thisText[j] + '</span>'
		}
		thisElem.html(animationTextInsert);
	}

	function setAnimationClass() {
		// アニメーションの実行前に、アニメーション完了済の要素を確認しておく
		for(var i = 0; i < animationClassArr.length; i++) {
			for(var j = 0; j < $('.' + animationClassArr[i]).length; j++) {
				if($('.' + animationClassArr[i]).eq(j).hasClass(animationFinClassArr[i])) {
					animationFlagArr[animationClassArr[i]][j] = true;
				}
			}
		}

		// スクロール位置と画面高さを取得
		var scrollTop = $(window).scrollTop();
		var windowHeight = $(window).height();

		// アニメーション対象要素が開始位置までスクロールしている場合、classを付与する
		for(var i = 0; i < animationClassArr.length; i++) {
			for(var j = 0; j < animationFlagArr[animationClassArr[i]].length; j++) {
				if(animationFlagArr[animationClassArr[i]][j] == false) {
					var thisElement = $('.' + animationClassArr[i]).eq(j);
					var thisTop = thisElement.offset().top;
					if(scrollTop + (windowHeight * animationStartPositionArr[i]) > thisTop) {
						thisElement.addClass(animationFinClassArr[i]);
					}
				}
			}
		}
	}
});

アニメーションを複数設定するデモページ
 

このエントリーをはてなブックマークに追加

関連記事

コメントを残す

メールアドレスが公開されることはありません。
* が付いている欄は必須項目です

CAPTCHA


コメントが承認されるまで時間がかかります。

2024年4月
 123456
78910111213
14151617181920
21222324252627
282930