クリックして回る正六面体をドラック&ドロップで移動する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>