[JS] アニメーションの基礎 その2

タグ :

jQuery の勉強をまとめるシリーズです。
今回も前記事に引き続きアニメーションの基礎的なメソッドについてまとめます。

複数のアニメーション動作を同時に行うようにするためには前記事で説明したメソッドでは出来ません。同時に動作しているように見せることは可能かもしれませんが、全く同時に動作させることは出来ないでしょう。
今回は複数アニメーションを同時に行うメソッドについてまとめます。

複数のアニメーション動作

サンプルとして前記事同様にメインメニューからサブメニューを表示する際の動作にアニメーションを用います。さらに今回は複数の動作が分かるように、文字サイズと領域幅も変更させてみました。

[ 構文 ]
.animate({プロパティ}, 動作時間, 動かし方, コールバック関数)
[ コード ]
$(function() {
	$('.menu ul li').hover(
		function() {
			var txt = $('span',this).text();
			$(this).animate({
				width: '150px',
				height: '35px',
				paddingTop: '5px',
				paddingLeft: '60px',
				fontSize: '15pt'
			},500).css('background','red');
			$('>ul',this).delay(500).slideDown(500, function() {
				$('p.message').text(txt + "を展開中");
			});
		},
		function() {
			$('>ul',this).slideUp(300, function() {
				$('p.message').text("非表示");
			});
			$(this).delay(300).animate({
				width: '100px',
				height: '30px',
				paddingTop: '10px',
				paddingLeft: '25px',
				fontSize: '12pt'
			},300).css('background','#aaa');
		}
	);
});

3行目〜15行目でメインメニューのマウスオーバー時にサブメニューを表示させる処理になります。
16行目〜27行目がメインメニューのマウスアウト時にサブメニューを非表示にする処理になります。

<h4>アニメーション基礎 - 複数</h4>
<p class="message">非表示</p>
<div class="menu">
	<ul class="main">
		<li><span>メニュー1</span>
			<ul>
				<li>サブ1</li><li>サブ2</li>
			</ul>
		</li>
		<li><span>メニュー2</span>
			<ul>
				<li>サブ3</li><li>サブ4</li><li>サブ5</li>
			</ul>
		</li>
		<li><span>メニュー3</span>
			<ul>
				<li>サブ6</li><li>サブ7</li>
			</ul>
		</li>
	</ul>
</div>

5,10,15行目の li 要素がメインメニューの項目になります。
7,12,17行目の li 要素がサブメニューの項目になります。

p.message {
	margin-left: 50px;
}
div.menu ul li {
	list-style: none;
	width: 100px;
	height: 30px;
	float: left;
	cursor: pointer;
	background: #aaa;
	padding: 10px 0px 0px 25px;
}
div.menu ul li ul {
	margin-top: 5px;
	margin-left: -100px;
	display: none;
}
div.menu ul li ul li {
	font-size: 12pt;
}

16行目でサブメニュー部分を非表示にしています。

	... 省略 ...
<ul class="main">
	<li style="font-size:15pt; width:150px; height:35px; padding-top:5px; padding-left:60px; background-color:red;">
		<ul style="display:block;">
	... 省略 ...

HTML の 6,11,16行目のスタイルが上記のように変更されます。

ページロード時はメインメニューのみが表示され、サブメニューは非表示にしています。
メインメニューへのマウスオーバーにより各メニューに対応したサブメニューが表示されます。その表示動作の前にアニメーションにより「領域幅・高さの拡大」「フォントサイズの拡大」を実行しています。
メニュー領域からのマウスアウトによりサブメニューが非表示になります。その非表示動作の後にアニメーションにより「領域幅・高さの縮小」「フォントサイズの縮小」を実行しています。
また、メソッドチェーンの実行としてスタイルも変更していますが、過去記事でやっているので割愛します。

細かな設定

上記の記述でも十分うまく動作させることは可能ですが、animate() の設定には以下のように細かく設定することができます。この細かな設定によって、より柔軟な動作が可能となります。

$(this).animate(
	{プロパティ},
	{
		queue: true,
		duration: 1000,
		easing: 'linear',
		complete: function(){...}
	}
);
設定 説明 デフォルト
queue false と記述すると複数のアニメーションを同時に実行します。
true と記述すると複数のアニメーションを一つずつ順番に実行します。
true
duration アニメーションが完了するまでに掛かる時間になります。 1000
easing アニメーションの動かし方を設定できます。これの設定にはプラグインが必要です。デフォルトの ‘linear’ は直線的に変化させる指定になります。 ‘linear’
complete 動作完了後に行う処理を記述します。 (無し)

上記の設定の「queue」を true に設定するとアニメーションを一つずつ実行するのですが、設定したプロパティが順番に実行される訳ではありません。アニメーションはメソッドチェーンによりつなげる事が可能なのですが、そのつないだアニメーションメソッドを順番にするか否かを決めているのが「queue」です。
上記のサンプルで試してみましょう。jQuery のコード以外は同じです。

[ コード ]
$(function() {
	$('.menu ul li').hover(
		function() {
			var txt = $('span',this).text();
			$(this)
			.animate({
				width: '150px',
				height: '35px',
				paddingTop: '5px',
				paddingLeft: '60px'
			},{
				queue: true,
				duration: 500,
				easig: 'linear'
			}).animate({
				fontSize: '15pt'
			},500).css('background','red');
			$('>ul',this).delay(500).slideDown(500, function() {
				$('p.message').text(txt + "を展開中");
			});
		},
		function() {
			$('>ul',this).slideUp(300, function() {
				$('p.message').text("非表示");
			});
			$(this).delay(300).animate({
				width: '100px',
				height: '30px',
				paddingTop: '10px',
				paddingLeft: '25px',
				fontSize: '12pt'
			},300).css('background','#aaa');
		}
	);
});

12行目〜14行目が設定箇所です。
15行目〜17行目でアニメーションを分けています。

<h4>アニメーション基礎 - 複数</h4>
<p class="message">非表示</p>
<div class="menu">
	<ul class="main">
		<li><span>メニュー1</span>
			<ul>
				<li>サブ1</li><li>サブ2</li>
			</ul>
		</li>
		<li><span>メニュー2</span>
			<ul>
				<li>サブ3</li><li>サブ4</li><li>サブ5</li>
			</ul>
		</li>
		<li><span>メニュー3</span>
			<ul>
				<li>サブ6</li><li>サブ7</li>
			</ul>
		</li>
	</ul>
</div>

5,10,15行目の li 要素がメインメニューの項目になります。
7,12,17行目の li 要素がサブメニューの項目になります。

p.message {
	margin-left: 50px;
}
div.menu ul li {
	list-style: none;
	width: 100px;
	height: 30px;
	float: left;
	cursor: pointer;
	background: #aaa;
	padding: 10px 0px 0px 25px;
}
div.menu ul li ul {
	margin-top: 5px;
	margin-left: -100px;
	display: none;
}
div.menu ul li ul li {
	font-size: 12pt;
}

16行目でサブメニュー部分を非表示にしています。

	... 省略 ...
<ul class="main">
	<li style="font-size:15pt; width:150px; height:35px; padding-top:5px; padding-left:60px; background-color:red;">
		<ul style="display:block;">
	... 省略 ...

HTML の 6,11,16行目のスタイルが上記のように変更されます。

最初のサンプルのコードと比較してみると、「フォントサイズ拡大」部分のアニメーションが区別されていることが分かると思います。animate() を2つ用意し、一つ目(6行目〜14行目)では「領域の拡大」二つ目(15行目〜17行目)では「フォントサイズの拡大」を行います。
一つ目のアニメーション設定の部分(12行目)で「queue」が true に設定してありますが、ここを false に設定すると、最初のサンプルと同じ動作になります。

キュー(queue)を使用することで、一つ一つの動作完了を明確に知る事ができ、バグ対策になると思います。動作が完了していない状態で次の動作を実行させようとすると、今回のサンプルのようなバグが発生します。
今回のサンプルでは動作はぎこちないものになってしまっていますが、それはやり方によってどうとでもなると思います。各アニメーション動作の時間を調整して、気にならない程度に抑えるとか、、、やり方は色々です。

また、そのやり方をサポートするメソッドを参考までに。。。

[ 動作の停止 ]
$(‘:animated’).queue(‘fx’,[ ]).stop()
実行中の動作を停止します。
[ 動作数を確認 ]
$(セレクター).queue(‘fx’).length
その要素に対して実行される動作の数を確認できます。
[ 動作を追加 ]
$(セレクター).queue(function() {
 $(this).animate({プロパティ});
 $(this).dequeue();
});
その要素に新たに動作を追加します。

まとめ

アニメーションを使用すると簡単に動作をスムーズにすることができます。ですが、マウス操作などを絡めてスムーズな動作を求めると、一気に難しくなります。動作の実行時間による制限や、予期せぬ動作の干渉がバグを引き起こしてしまうからです。
このバグを如何に無くしていくかがアニメーションを扱う上で壁になってくると思います。もちろん簡単なアニメーションならそんなに難しく考える必要はありません。が、簡単なアニメーションでは見ている人に飽きられてしまうでしょう。より複雑で斬新な動きであればあるほど、見る人の気を引きます。

そういったアニメーションを作成するには、プログラムの分岐・ループ・計算式が必須になります。
また、それ以上に必要な能力として「センス」が必須です。
センスがある人は、その動作を実現するために動作アルゴリズムを考えるだけで済みますが、センスの無い人は世に出回っているサンプル的な動作を参考にするしかありません。今や沢山のサンプルがあるので、それほど気にする事でもないですが、、、

独自のアニメーションを作成する楽しさもあると思いますので、頑張って作成していきたいと思います。

Share

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

Comment

コメントを残す

*がついている欄は必須項目です。

  • Twitter
  • Facebook
  • Google Plus
  • RSS Feed