正六面体上をクリックして回す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>
