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