立方体をクリックしながら回す

正六面体上をクリックして回すJavaScriptの例です。

参考1:角度から座標を求める計算式
    X座標 = 半径 * Math.cos(Y軸角度 / 180 * Math.PI)
    Y座標 = 半径 * Math.sin(X軸角度 / 180 * Math.PI)
    注)Y軸角度は-90°から90°の指定となる。また、X軸角度は-180°から180°の指定となる。
参考2:座標から角度を求める計算式
    X角度 = Math.asin(Y座標 / 半径 / Math.PI * 180)
    Y角度 = Math.acos(X座標 / 半径 / Math.PI * 180)
    注)Math.asinの計算値が-90°から90°以外はNaNとなる。また、Math.acosの計算値が-180°から180°以外はNaNとなる。

1、クリックされた時点の座標から角度を求める。
2、前回クリックが離された時点の角度を求める。
3、移動された座標から角度を求める。
4、「移動された角度」から「クリックされた時点の角度」を引き「前回クリックが離された角度」を足す。
  この計算で、今回動す角度が決定される。

注)マウスの移動方向と回転方向は相対関係となるので、回転値も相対値を取る。

↓以下がテストのソースサンプルです。

▼JavaScript

<script type="text/javascript">
// 匿名関数内で実行
window.onload = function (){

	// 各エレメントを取得
	var element = document.getElementById("cube");
	var bounds = element.getBoundingClientRect();
	var r = 100;
	var xa = bounds.left + r;
	var ya = bounds.top + r;
	var angleX = -20;
	var angleY = -20;
	var angleX_A = -20;
	var angleY_A = -20;
	var angleX_B = 0;
	var angleY_B = 0;
	var angleX_C = 0;
	var angleY_C = 0;
	var angleX_Out = -20;
	var angleY_Out = -20;

	var flgMove = false;
	var flgOut = true;

	// ------------------------------------------------------------
	// クリック時に実行される関数
	// ------------------------------------------------------------
	function MouseDownFunc(e){
		if (!flgMove){
			flgMove = true;
			xb = e.clientX;
			yb = e.clientY;
			var gapX = Math.round(((xb - xa) * 1000 ) / 1000);
			var gapY = Math.round(((yb - ya) * 1000 ) / 1000);
			angleX_B = 0 - Math.round(Math.asin(gapY / r) / Math.PI * 180 *1000) / 1000;
			if ( isNaN(angleX_B)){angleX_B = 0};
			angleY_B = 0 - Math.round(Math.acos(gapX / r) / Math.PI * 180 *1000) / 1000;
			if ( isNaN(angleY_B)){angleY_B = 0};
		}
	}

	// ------------------------------------------------------------
	// クリックが離された時に実行される関数
	// ------------------------------------------------------------
	function MouseUpFunc(e){
		flgMove = false;
		angleX_A = angleX;
		angleY_A = angleY;
	}
	function MouseUpEventFunc(w){
		flgMove = false;
		angleX_A = angleX;
		angleY_A = angleY;
	}
	
	// ------------------------------------------------------------
	// マウスオーバー時に実行される関数
	// ------------------------------------------------------------
	function MouseOverFunc(e){
		flgOut = true;
	}

	// ------------------------------------------------------------
	// マウスカーソルが移動するたびに実行される関数
	// ------------------------------------------------------------
	function MouseMoveFunc(e){
		if(flgMove){
			RotateFunc(e);
		}
	}

	// ------------------------------------------------------------
	// マウスアウト時に実行される関数
	// ------------------------------------------------------------
	function MouseOutFunc(e){
		flgOut = false;
	}

	// ------------------------------------------------------------
	// マウス移動時に角度を求める関数
	// ------------------------------------------------------------
	function RotateFunc(e){
//		カーソル位置を求める		
		var xc = e.clientX;
		var yc = e.clientY;
//		回転率を求める
		var gapX = Math.round(((xc - xa) * 1000 ) / 1000) % r;
		var gapY = Math.round(((yc - ya) * 1000 ) / 1000) % r;
		angleX_C = 0 - Math.round(Math.asin(gapY / r) / Math.PI * 180 *1000) / 1000;
		if ( isNaN(angleX_C)){angleX_C = 0};
		angleY_C = 0 - Math.round(Math.acos(gapX / r) / Math.PI * 180 *1000) / 1000;
		if ( isNaN(angleY_C)){angleY_C = 0};
//		クリックされた角度から移動された角度を引き元の角度を足す
		angleX = (angleX_C - angleX_B + angleX_A);
		angleY = (angleY_C - angleY_B + angleY_A);

//		図形を回転させる
		var AngleRotate =""
		if ( angleX == parseFloat(angleX))
			{AngleRotate = AngleRotate + "rotateX(" + angleX + "deg)"};
		if ( angleY == parseFloat(angleY))
			{AngleRotate = AngleRotate + "rotateY(" + angleY + "deg)"};
		if ( AngleRotate != "")
			{document.getElementById("cube").style.transform = AngleRotate};

	}

	// ------------------------------------------------------------
	// イベントのリッスンを開始する
	// ------------------------------------------------------------
	// イベントリスナーに対応している
	if(element.addEventListener){

		// マウス押下時に実行されるイベント
//		element.addEventListener("click" , MouseDownFunc);
		// クリックを離した時に実行されるイベント
//		element.addEventListener("mouseup" , MouseUpFunc);
		// マウス押下時に実行されるイベント
		element.addEventListener("mousedown" , MouseDownFunc);
		// マウスオーバー時に実行されるイベント
		element.addEventListener("mouseover" , MouseOverFunc);
		// マウスカーソルが移動するたびに実行されるイベント
		element.addEventListener("mousemove" , MouseMoveFunc);
		// マウスカーソルが図形から外れるたびに実行されるイベント
//		element.addEventListener("mouseout" , MouseOutFunc);

	// アタッチイベントに対応している
	}else if(element.attachEvent){

		// マウス押下時に実行されるイベント
//		element.attachEvent("onClick" , MouseDownFunc);
		// クリックを離した時に実行されるイベント
//		element.attachEvent("onmouseup" , MouseUpFunc);
		// マウス押下時に実行されるイベント
		element.attachEvent("onmousedown" , MouseDownFunc);
		// マウスオーバー時に実行されるイベント
		element.attachEvent("onmouseover" , MouseOverFunc);
		// マウスカーソルが移動するたびに実行されるイベント
		element.attachEvent("onmousemove" , MouseMoveFunc);
		// マウスカーソルが図形から外れるたびに実行されるイベント
//		element.attachEvent("onmouseout" , MouseOutFunc);

	}
	// ------------------------------------------------------------
	// イベントのリッスンを開始する
	// ------------------------------------------------------------
	// イベントリスナーに対応している
	if(window.addEventListener){

		// マウスボタンを押すと実行されるイベント
//			window.addEventListener("mousedown" , MouseDownEventFunc);
		// マウスカーソルを移動するたびに実行されるイベント
//		window.addEventListener("mousemove" , MouseMoveEventFunc);
		// マウスボタンを離すと実行されるイベント
		window.addEventListener("mouseup" , MouseUpEventFunc);

	// アタッチイベントに対応している
	}else if(document.attachEvent){

		// マウスボタンを押すと実行されるイベント
//		document.attachEvent("onmousedown" , MouseDownEventFunc);
		// マウスカーソルを移動するたびに実行されるイベント
//		document.attachEvent("onmousemove" , MouseUpEventFunc);
		// マウスボタンを離すと実行されるイベント
		document.attachEvent("onmouseup" , MouseUpEventFunc);

	}


};
</script>

▼CSS

<style>
body{
	width: 100%;
	height:100%;
}
#wrap{
	width: 100%;
	height:100%;
}
#main {
	margin:200px 200px;
}
#cube {
	margin:0;
	position: relative;
	transform-style: preserve-3d;
	transform-origin:100px 100px;
	transform: rotateX(-20deg) rotateY(-20deg);
}
.surface {
	position: absolute;
	left: 0;
	top: 0;
	width: 200px;
 	height: 200px;
	text-align: center;
	line-height: 200px;
	box-sizing: border-box;
	border: 2px solid black;
}
text{
	fill:black;
	font-size:130px;
}
#front {
	transform: rotateY(0deg) translateZ(100px);
	background:red;/*赤*/
	opacity: 0.6;

}
#back {
	transform: rotateX(180deg) translateZ(100px);
	background:pink;/*ピンク*/
	opacity: 0.6;
}
#right{
	transform: rotateY(90deg) translateZ(100px);
	background:blue;/*青*/
	opacity: 0.6;
}
#left {
	transform: rotateY(-90deg) translateZ(100px);
	background:skyblue;/*水色*/
	opacity: 0.6;
}
#top {
	transform: rotateX(90deg) translateZ(100px);
	background:green;/*緑*/
	opacity: 0.6;
}
#bottom {
	transform: rotateX(-90deg) translateZ(100px);
	background:yellow;/*黄色*/
	opacity: 0.6;
}
</style>

▼HTML

<div id="wrap">
<!-- 正六面体 -->
	<div id="main">
		<div id="cube">
			<svg class="surface" id="front" viewBox="-100 -100 200 200" >
				<rect x="-100" y="-100" width="200" hight="200"></rect>
				<text x="-50" y="40">1</text>
			</svg>
			<svg class="surface" id="back" viewBox="-100 -100 200 200" >
				<rect x="-100" y="-100" width="200" hight="200"></rect>
				<text x="-50" y="40">2</text>
			</svg>
			<svg class="surface" id="right" viewBox="-100 -100 200 200" >
				<rect x="-100" y="-100" width="200" hight="200"></rect>
				<text x="-50" y="40">3</text>
			</svg>
			<svg class="surface" id="left" viewBox="-100 -100 200 200" >
				<rect x="-100" y="-100" width="200" hight="200"></rect>
				<text x="-50" y="40">4</text>
			</svg>
			<svg class="surface" id="top" viewBox="-100 -100 200 200" >
				<rect x="-100" y="-100" width="200" hight="200"></rect>
				<text x="-50" y="40">5</text>
			</svg>
			<svg class="surface" id="bottom" viewBox="-100 -100 200 200" >
				<rect x="-100" y="-100" width="200" hight="200"></rect>
				<text x="-50" y="40">6</text>
			</svg>
		</div>
	</div>
</div>

デモページは、こちら