立方体をドラック&ドロップで移動する

クリックして回る正六面体をドラック&ドロップで移動するJavaScriptの例です。
図形上をドラックしながらマウスアウトし、図形以外の領域でドロップするとドロップした時点まで、図形を移動させる。

1、マウスアップした時に、図形上以外の判断をする。
2、ポジションのトップをドロップしたY座標、レフトをX座標に設定する。
3、図形の中心点を再計算する。
  

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

▼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 flgMove = false;
	var flgOut = true;
	
	document.querySelector("#reset").onclick = function () {location.reload()};

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

	// ------------------------------------------------------------
	// クリックが離された時に実行される関数
	// ------------------------------------------------------------
	function MouseUpFunc(e){
		flgMove = false;
		angleX_A = angleX;
		angleY_A = angleY;
	}
	function MouseUpEventFunc(w){
		if (flgMove) {
			flgMove = false;
			angleX_A = angleX;
			angleY_A = angleY;
			if (!flgOut){
				DropFunc(w)
			}
		}
	}
	
	// ------------------------------------------------------------
	// マウスオーバー時に実行される関数
	// ------------------------------------------------------------
	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 = (xc - xa) / r;
		var gapY = (yc - ya) / r;
		gapX = Math.round((gapX % r) * 1000) / 1000;
		gapY = Math.round((gapY % r) * 1000) / 1000;
		angleX_C = - Math.asin(gapY) / Math.PI * 180;
		if ( isNaN(angleX_C)){angleX_C = 0};
		angleY_C = - Math.acos(gapX) / Math.PI * 180;
		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;
			};

	}

	// ------------------------------------------------------------
	// マウス移動時に角度を求める関数
	// ------------------------------------------------------------
	function DropFunc(w){
//		カーソル位置を求める		
		var psLeft = w.clientX;
		var psTop = w.clientY;

//		図形を移動させる
		if ( psLeft != "")
			{document.getElementById("main").style.left = psLeft + "px"};
		if ( psTop != "")
			{document.getElementById("main").style.top = psTop + "px"};

		bounds = element.getBoundingClientRect();
		xa = bounds.left + r;
		ya = bounds.top + r;
		flgOut = true;
	}

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

		// マウス押下時に実行されるイベント
		element.addEventListener("mousedown" , MouseDownFunc);
		// マウスオーバー時に実行されるイベント
		element.addEventListener("mouseover" , MouseOverFunc);
		// マウスカーソルが移動するたびに実行されるイベント
		element.addEventListener("mousemove" , MouseMoveFunc);
		// マウスアウト時に実行されるイベント
		element.addEventListener("mouseout" , MouseOutFunc);

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

		// マウス押下時に実行されるイベント
		element.attachEvent("onmousedown" , MouseDownFunc);
		// マウスオーバー時に実行されるイベント
		element.attachEvent("onmouseover" , MouseOverFunc);
		// マウスカーソルが移動するたびに実行されるイベント
		element.attachEvent("onmousemove" , MouseMoveFunc);
		// マウスアウト時に実行されるイベント
		element.attachEvent("onmouseout" , MouseOutFunc);

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

		// マウスボタンを離すと実行されるイベント
		window.addEventListener("mouseup" , MouseUpEventFunc);

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

		// マウスボタンを離すと実行されるイベント
		document.attachEvent("onmouseup" , MouseUpEventFunc);

	}

};
</script>

▼CSS

<style>
body{
	width: 100%;
	height:100%;
}
#wrap{
	width: 100%;
	height:100%;
	position:relative;
}
#reset{
	margin:30px 30px;
}
#main {
	position:absolute;
	top:200px;
	left: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;
	user-select: none;
	-moz-user-select: none; /* Firefox */
	-webkit-user-select: none; /* Safari、Chromeなど */
	-ms-user-select: none; /* IE10から*/
}
#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="buttonBox">
		<button id="reset">リセット</button>
	</div>
<!-- 正六面体 -->
	<div id="main">
		<div id="cube">
			<svg class="surface" id="front" viewBox="-100 -100 200 200" >
				<g>
					<rect x="-100" y="-100" width="200" hight="200"></rect>
					<text x="-50" y="40">1</text>
				</g>
			</svg>
			<svg class="surface" id="back" viewBox="-100 -100 200 200" >
				<g>
					<rect x="-100" y="-100" width="200" hight="200"></rect>
					<text x="-50" y="40">2</text>
				</g>
			</svg>
			<svg class="surface" id="right" viewBox="-100 -100 200 200" >
				<g>
					<rect x="-100" y="-100" width="200" hight="200"></rect>
					<text x="-50" y="40">3</text>
				</g>
			</svg>
			<svg class="surface" id="left" viewBox="-100 -100 200 200" >
				<g>
					<rect x="-100" y="-100" width="200" hight="200"></rect>
					<text x="-50" y="40">4</text>
				</g>
			</svg>
			<svg class="surface" id="top" viewBox="-100 -100 200 200" >
				<g>
					<rect x="-100" y="-100" width="200" hight="200"></rect>
					<text x="-50" y="40">5</text>
				</g>
			</svg>
			<svg class="surface" id="bottom" viewBox="-100 -100 200 200" >
				<g>
					<rect x="-100" y="-100" width="200" hight="200"></rect>
					<text x="-50" y="40">6</text>
				</g>
			</svg>
		</div>
	</div>
</div>

デモページは、こちら