回転型切替コンテンツを実現するCSS3を使ったjQueryのスクリプト

JavaScript

ちょっと前から構想を練っていたスクリプトです。まー同じようなものは探せばどこかにあるでしょうけどね~。でも考えたからには作っておきゃなきゃって感じで制作しました。

CSS3とjQueryのコンビネーション。とっても素敵です。でもクロスブラウザなjQueryでもCSS3の全てには対応しきれないところが残念です。でもまあ作っててとっても楽しかったです。

Demo

必要なファイル

対応ブラウザ

  • Google Chrome
  • Safari4~
  • Firefox4(beta)~

※Windowsのみの確認です。

他のブラウザでもどーにか別の動作で見ることは出来るようにしています。美しくはありませんが。。。また、Opera10.6は動きがスムーズではないので対応ブラウザから外しています。

コーディング&設定

HTML

HTMLヘッダー内でjquery.jsを読み込む。

<script src="jquery.js" type="text/javascript"></script>

#rotaMenuにメニューを#rotationWrapにコンテンツをそれぞれ4つづつ用意します。

4つ以下はいいのですが、4つを超えるコンテンツを配置することは出来ません。何故ならコンテンツの左上を中心として風車のようにコンテンツを配置するからです。

.roteの内容はなんでもいいです。

<ul id="rotaMenu">
	<li><a href="#box1">メニュー1</a></li>
	<li><a href="#box2">メニュー2</a></li>
	<li><a href="#box3">メニュー3</a></li>
	<li><a href="#box4">メニュー4</a></li>
</ul>

<div id="rotationWrap">
	<div id="rotation">
		<div id="box1" class="rota">
			<p>テキストテキストテキスト</p>
		</div>
		<div id="box2" class="rota">
			<p>テキストテキストテキスト</p>
		</div>
		<div id="box3" class="rota">
			<p>テキストテキストテキスト</p>
		</div>
		<div id="box4" class="rota">
			<p>テキストテキストテキスト</p>
		</div>
	</div>
</div>

CSS

元々CSS3を使ったスクリプトなので、装飾にもCSS3をふんだんに使って装飾してます。

ul#rotaMenu {
	display: inline-block;
	margin-bottom: 10px;
}
ul#rotaMenu li {
	margin-right: 10px;
	float: left;
}
ul#rotaMenu li a {
	display: block;
	width: 100px;
	background-color: #eee;
	background: -webkit-gradient(linear,center top,center bottom,from(#fff),to(#ddd));
	background: -moz-linear-gradient(top, #fff, #ddd);
	background: -o-gradient(linear,center top,center bottom,from(#fff),to(#ddd));
	border: 1px solid #ccc;
	-webkit-border-radius: 5px;
	-moz-border-radius: 5px;
	-webkit-box-shadow: 0 0 3px #ccc;
	-moz-box-shadow: 0 0 3px #ccc;
	padding: 5px;
	color: #666;
	text-shadow: 1px 1px 0 #fff;
	text-align: center;
	text-decoration: none;
	font-size: 18px;
}
ul#rotaMenu li a:hover {
	background: -webkit-gradient(linear,center top,center bottom,from(#ddd),to(#fff));
	background: -moz-linear-gradient(top, #ddd, #fff);
}
ul#rotaMenu li a#active {
	background-color: #666;
	background: -webkit-gradient(linear,center top,center bottom,from(#666),to(#333));
	background: -moz-linear-gradient(top, #666, #333);
	border: 1px solid #333;
	color: #ddd;
	text-shadow: -1px -1px 0 #333;
}
div#rotationWrap {
	width: 798px;
	background-color: #eee;
	background: -webkit-gradient(linear, center top, center bottom, from(#f7f7f7), to(#eee));
	background: -moz-linear-gradient(top, #f7f7f7, #eee);
	border: 1px solid #fff;
	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	-webkit-box-shadow: 0 0 5px #bbb;
	-moz-box-shadow: 0 0 5px #bbb;
	overflow: hidden;
	-webkit-transition: all 0.5s ease-in-out;
	-moz-transition: all 0.5s ease-in-out;
	-o-transition: all 0.5s ease-in-out;
}
div#rotation {
	position: relative;
	-webkit-transform-origin: 0 0;
	-moz-transform-origin: 0 0;
	-o-transform-origin: 0 0;
	-webkit-transition: all 0.5s ease-in-out;
	-moz-transition: all 0.5s ease-in-out;
	-o-transition: all 0.5s ease-in-out;
}
div#rotation div.rota {
	width: 780px;
	padding: 10px;
	-webkit-transform-origin: 0 0;
	-moz-transform-origin: 0 0;
	-o-transform-origin: 0 0;
}
div#rotation div.rota p {
	color: #333;
	text-shadow: 1px 1px 0 #fff;
	line-height: 1.5;
}

※2011/09/01 上記CSSを修正しました。(見が目が少し気になったので。)

JavaScript

以下のスクリプトを記述。

$(function(){

	//対象要素設定
	var wrap = $("#rotationWrap");
	var rotaArea = $("#rotation");
	var menu = $("#rotaMenu a");
	var rotaBox = $("div.rota",rotaArea);

	//初期表示設定
	$(window).bind("load",function(){ //ロード終了後実行
		wrap.css({
			height: rotaBox.eq(0).prop("offsetHeight") //#rotationWrapの高さを一つめのdiv.rota高さに合わせる
		});
	});
	menu.eq(0).attr("id","active"); //一つめのdiv.rotaにのid属性activeを加える
	if(!jQuery.support.opacity){ //IE6,7,8に適用
		rotaBox.not(":eq(0)").css({
			visibility: "hidden" //一つめ以外のdiv.rotaを非表示にする
		});
	};
	
	//メニューアクティブ変更クリックイベント
	menu.click(function(){ //クリックされた#rotaMenu aに対してid属性activeを移動する
		menu.not(this).removeAttr("id");
		$(this).attr("id","active");
	});

	//css設定
	rotaBox.css({
		position: "absolute",
		top: "0",
		left: "0"
	});

	//div.rotaに対しての設定
	rotaBox.each(function(){ //div.rotaをそれぞれを90度づつずらして回転させる
		var index = rotaBox.index(this);
		var angle = 90*index;
		var rotate = "rotate(-"+angle+"deg)";
		$(this).css({
			"-webkit-transform": rotate,
			"-moz-transform": rotate,
			"-o-transform": rotate,
			"-ms-transform": rotate,
			"transform": rotate
		});
	});

	//コンテンツ回転クリックイベント
	menu.click(function(){ //#rotaMenu aをクリックで#rotationを回転させる
		var index = menu.index(this);
		var boxHeight = rotaBox.eq(index).prop("offsetHeight");
		var angle = 90*index;
		var rotate = "rotate("+angle+"deg)";
		rotaArea.css({
			height: boxHeight,
			"-webkit-transform": rotate,
			"-moz-transform": rotate,
			"-o-transform": rotate,
			"-ms-transform": rotate,
			"transform": rotate
		});
		if(!jQuery.support.opacity){ //IE6,7,8に適用
			rotaBox.eq(index).css({ //クリックしたdiv.rotaを表示する
				visibility: "visible"
			});
			rotaBox.not("':eq("+index+")'").css({ //クリックした以外のdiv.rotaを非表示にする
				visibility: "hidden"
			});
		};
		wrap.css({ //表示されているdiv.rotaにあわせて#rotationWrapの高さを変更する
			height: boxHeight
		});
		return false;
	});

});

※2011/09/01 jQueryのバージョンアップにより上記スクリプトが動かなくなっていましたので修正しました。

※2010/10/27 上記スクリプトの記述を変更しました。

解説

全ての.rotaposition: absolute;で重ねて左上を中心にそれぞれ90度ずつずらし、枠からはみ出るコンテンツはoverflow: hidden;で見えなくします。

.rotaの親要素#rotationの角度をtransform: roteto();で設定し、1つ目のメニューをクリックすると0度、2つ目で-90度、3つ目で-180度、4つ目で-270度となるよう回転させます。CSSでtransformを設定していますので、風車の様にアニメーションでグルグルとまわります。

#rotationの親要素#rotationWrapに設定している枠は見えているコンテンツの高さに合わせて調整されるようにします。

一応おまけでアクティブ状態のメニューはCSSが切り替わるよう設定しました。

あとがき

記事の内容とは関係ない話ですけど、ブログで記事を書くようになりましたが、自分の文章が定まりません。はじめはきちんとか書こうと思っていましたが、すぐに辛くなってきました。ですので、そのときの気分で書くことにしました。記事ごとに文言や文脈などコロコロ変わっていると思います。でもそのほうが楽しいし楽だからいいかなって思ってます。なにより続けたいですから。続けなきゃじゃなくてね。

Top