簡體   English   中英

如何在點擊時正確旋轉立方體?

[英]How to properly rotate a cube on click?

所以我正在嘗試的是基本上通過單擊位於立方體上或浮在其旁邊的按鈕來旋轉立方體。 現在我讓它們保持浮動,因為我經常試用它,這樣就更容易了,但將它們放在立方體上根本就沒有問題。

實際問題是並非所有旋轉軸似乎都被平等對待。 我的意思是,如果我沿X旋轉,Y軸和Z軸也會旋轉。 但是,如果我沿Y(或Z)旋轉,Z軸(或Y軸)旋轉但X軸始終保持相同。 在我的代碼中,這意味着無論多維數據集如何旋轉,通過單擊紅色方塊“3”或“4”觸發的沿X軸的旋轉將始終向上或向下旋轉立方體,而其他按鈕旋轉立方體根據其位置。 不要介意數字1,2,5和6被切換。 這是我能找到的最接近解決方案但是隨機旋轉立方體一段時間遲早會導致奇怪的移動。

我的代碼:

 var rotationX = 0; var rotationY = 0; var rotationZ = 0; var rotation = 0; var translate = 0; function showDebug() { var deBugInfo = '<p>X: '+rotationX + '</p>'; deBugInfo += '<p>Y: '+rotationY + '</p>'; deBugInfo += '<p>Z: '+rotationZ + '</p>'; $('#deBug').html(deBugInfo); } function cubeRotate() { $('#cube').css('transform', 'rotateX('+rotationX+'deg) rotateY('+rotationY+'deg) rotateZ('+rotationZ+'deg)'); showDebug(); } /* function buttonsRotate() { $('#buttons').css('transform', 'rotate('+rotation+'deg) translate('+0+')'); showDebug(); } */ $(function () { $('#dir1').on('click', function () { //var myStyle = $('#cube').css('transform'); //console.log(myStyle); //rotationY = rotationY - 90; rotationY -= 90; cubeRotate(); }); $('#dir2').on('click', function () { rotationY += 90; cubeRotate(); }); $('#dir3').on('click', function () { rotationX -= 90; cubeRotate(); rotation -= 90; // buttonsRotate(); }); $('#dir4').on('click', function () { rotationX += 90; cubeRotate(); rotation += 90; // buttonsRotate(); }); $('#dir5').on('click', function () { rotationZ += 90; cubeRotate(); }); $('#dir6').on('click', function () { rotationZ -= 90; cubeRotate(); }); }); 
 * { margin: 0; padding: 0; box-sizing: border-box; } body { font-size: 16px; font-family: sans-serif; width: 100%; height: 100%; position: absolute; -webkit-perspective: 100vmax; /* Safari 4-8 */ -webkit-perspective-origin: 50% 50%; /* Safari 4-8 */ perspective: 100vmax; perspective-origin: 50% 50%; overflow: hidden; } #cube { margin: auto; position: absolute; top: 50%; left: 50%; transform-style: preserve-3d; transition-duration: 0.5s; } .cubeface { position: absolute; height: 60vmin; width: 60vmin; margin-left: -30vmin; margin-top: -30vmin; opacity: 0.5; } .cubeface:nth-child(1) { transform: rotateY(0deg) translateY(0px) translateZ(30vmin); background-color: black; } .cubeface:nth-child(2) { transform: rotateY(90deg) translateY(0px) translateZ(30vmin); background-color: #343434; } .cubeface:nth-child(3) { transform: rotateY(180deg) translateY(0px) translateZ(30vmin); background-color: #525252; } .cubeface:nth-child(4) { transform: rotateY(270deg) translateY(0px) translateZ(30vmin); background-color: #818181; } .cubeface:nth-child(5) { transform: rotateX(90deg) translateZ(30vmin) translateY(0px); background-color: #a0a0a0; } .cubeface:nth-child(6) { transform: rotateX(-90deg) translateZ(30vmin) translateY(0px); background-color: #d8d8d8; } .content { width: 100%; height: 100%; position: absolute; border-radius: 50%; background-color: #a7ff8d; color: #f00; font-size: 3em; } .arrow { margin: auto; position: absolute; left: 50%; top: 90vmin; width: 5vmin; height: 5vmin; margin-left: -2.5vmin; margin-top: -2.5vmin; } .achse { height: 2px; width: 65vmin; background: #f00; position: absolute; top: 0; left: 0; transform-origin: 0; backface-visibility: visible; transform-style: preserve-3d; } .achseY { background: #0f0; transform: rotateZ(-90deg) rotateX(45deg); } .achseZ { background: #00f; transform: rotateY(-90deg) rotateX(45deg); } .achseX { transform: rotateX(45deg); } #deBug { background: #000; color: #FFF; font-size: 2em; padding: 1em; position: absolute; top: 0; right: 0; } #buttons { width: 100%; height: 100%; z-index: 5; } #dir1 { margin-left: -27.5vmin; background-color: red; z-index: 5; } #dir2 { margin-left: -17.5vmin; background-color: red; z-index: 5; } #dir3 { margin-left: -7.5vmin; background-color: red; z-index: 10; } #dir4 { margin-left: 2.5vmin; background-color: red; z-index: 10; } #dir5 { margin-left: 12.5vmin; background-color: red; z-index: 5; } #dir6 { margin-left: 22.5vmin; background-color: red; z-index: 5; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Test</title> <link rel="stylesheet" href="styles/screen.css"> <script src="scripts/jquery-3.3.1.min.js"></script> <script src="scripts/app.js"></script> </head> <body> <div id="deBug"> </div> <div class='arrow' id='dir3'>X-</div> <div class='arrow' id='dir4'>X+</div> <div id="buttons"> <div class='arrow' id='dir1'>Y-</div> <div class='arrow' id='dir2'>Y+</div> <div class='arrow' id='dir5'>Z+</div> <div class='arrow' id='dir6'>Z-</div> </div> <div id="cube"> <div class="cubeface" id="A"> <div class="content" id="main"> <p>A</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir3 up"> </div> <div class="dir4 down"> </div> </div> <div class="cubeface" id="B"> <div class="content" id=""> <p>B</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir5 up"> </div> <div class="dir6 down"> </div> </div> <div class="cubeface" id="C"> <div class="content" id=""> <p>C</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir4 up"> </div> <div class="dir3 down"> </div> </div> <div class="cubeface" id="D"> <div class="content" id=""> <p>D</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir6 up"> </div> <div class="dir5 down"> </div> </div> <div class="cubeface" id="E"> <div class="content" id=""> <p>E</p> </div> <div class="dir6 right"> </div> <div class="dir5 left"> </div> <div class="dir3 up"> </div> <div class="dir4 down"> </div> </div> <div class="cubeface" id="F"> <div class="content" id=""> <p>F</p> </div> <div class="dir5 right"> </div> <div class="dir6 left"> </div> <div class="dir3 up"> </div> <div class="dir4 down"> </div> </div> <div class="achse achseX"></div> <div class="achse achseY"></div> <div class="achse achseZ"></div> </div> </body> </html> 

我試過給每一個元素“transform-style:preserve-3d”。 沒工作。 我認為它實際上可以更好地使用立方體上的按鈕,但這是一個問題,以后回答,而不是這里的主題。

如果有人知道如何獲得所有AXES EQUALLY,請告訴我,我對這個立方體慢慢瘋狂:D

謝謝!

編輯:

2018_04_18:還與設置變換原點無關。

2018_04_19:更新了代碼段,以便按鈕不再旋轉但已修復,因此您始終可以單擊它們。

2018_04_20:

筆者發現了兩個可能有用的例子(它們都是用鼠標拖動立方體,我不確定這是否與問題有關)...

  1. https://codepen.io/jordizle/pen/haIdo/這個立方體有一個很好的方面,側面自動旋轉,以便它們可以正確讀取。 但是,如果將其旋轉到第1或第6側,它會顯示與我的立方體相同的問題,因為它不會向左或向右旋轉。

  2. https://codepen.io/ge1doot/pen/PqZKbv在這個例子中,問題似乎已經解決了。 無論立方體的位置如何,您都可以隨時向各個方向旋轉。 (但我不需要分割它的功能)我的問題是我不能真正看到他們使用的潦草之間的區別,因此我不知道為什么第二個旋轉完美但我有一種感覺是正確的軌道。 如果有人可以比較它們並解決這個謎,那將是非常好的;)

你的問題是由Euler Order引起的。 基本上,它是以什么順序使用軸來計算最終旋轉。

CSS變換Euler Order是最常見的一個:X,Y,Z。

首先計算X軸,因此它始終固定在靜止位置。 您無法在CSS中更改Euler順序。 即使你可以,歐拉秩序的第一軸也將“不被平等對待”。

Euler Rotation的另一個問題是Gimbal Lock。 單擊X,單擊Y,然后在演示中單擊Z. 現在嘗試旋轉X和Z.它們是一樣的! 你剛剛遇到過Gimbal Lock,它很難解決,而且不能用CSS修復。

相對旋轉 - 軸旋轉與立方體

 function rotate(axis, degrees) { cube.outerHTML = `<div class='gimbal' id='container' style="transition: all 0.5s; transform-style: preserve-3d; transform: rotate${axis}(0deg); position: relative; transition-timing-function: ease-in-out; width: 0; height: 0; transform-origin: 50vw 50vh;">${cube.outerHTML}</div>`; window.setTimeout(function () { container.style.transform = `rotate${axis}(${degrees}deg)`; container.removeAttribute('id'); }, 10); } $('#dir1').on('click', function () { rotate('Y', '90'); }); $('#dir2').on('click', function () { rotate('Y', '-90'); }); $('#dir3').on('click', function () { rotate('X', '90'); }); $('#dir4').on('click', function () { rotate('X', '-90'); }); $('#dir5').on('click', function () { rotate('Z', '90'); }); $('#dir6').on('click', function () { rotate('Z', '-90'); }); rotate('X', '0'); 
 * { margin: 0; padding: 0; box-sizing: border-box; } html, body { font-size: 16px; font-family: sans-serif; width: 100%; height: 100%; -webkit-perspective: 100vmax; /* Safari 4-8 */ -webkit-perspective-origin: 50% 50%; /* Safari 4-8 */ perspective: 100vmax; perspective-origin: 50% 50%; overflow: hidden; } #cube { margin: auto; position: absolute; top: 50vh; left: 50vw; transform-style: preserve-3d; } .cubeface { position: absolute; height: 60vmin; width: 60vmin; margin-left: -30vmin; margin-top: -30vmin; opacity: 0.5; } .cubeface:nth-child(1) { transform: rotateY(0deg) translateY(0px) translateZ(30vmin); background-color: black; } .cubeface:nth-child(2) { transform: rotateY(90deg) translateY(0px) translateZ(30vmin); background-color: #343434; } .cubeface:nth-child(3) { transform: rotateY(180deg) translateY(0px) translateZ(30vmin); background-color: #525252; } .cubeface:nth-child(4) { transform: rotateY(270deg) translateY(0px) translateZ(30vmin); background-color: #818181; } .cubeface:nth-child(5) { transform: rotateX(90deg) translateZ(30vmin) translateY(0px); background-color: #a0a0a0; } .cubeface:nth-child(6) { transform: rotateX(-90deg) translateZ(30vmin) translateY(0px); background-color: #d8d8d8; } .content { width: 100%; height: 100%; position: absolute; border-radius: 50%; background-color: #a7ff8d; color: #f00; font-size: 3em; } .arrow { margin: auto; position: absolute; left: 50%; top: 90vmin; width: 5vmin; height: 5vmin; margin-left: -2.5vmin; margin-top: -2.5vmin; } .achse { height: 2px; width: 65vmin; background: #f00; position: absolute; top: 0; left: 0; transform-origin: 0; backface-visibility: visible; transform-style: preserve-3d; } .achseY { background: #0f0; transform: rotateZ(-90deg) rotateX(45deg); } .achseZ { background: #00f; transform: rotateY(-90deg) rotateX(45deg); } .achseX { transform: rotateX(45deg); } #deBug { background: #000; color: #FFF; font-size: 2em; padding: 1em; position: absolute; top: 0; right: 0; } #buttons { width: 100%; height: 100%; z-index: 5; } #dir1 { margin-left: -27.5vmin; background-color: red; z-index: 5; } #dir2 { margin-left: -17.5vmin; background-color: red; z-index: 5; } #dir3 { margin-left: -7.5vmin; background-color: red; z-index: 10; } #dir4 { margin-left: 2.5vmin; background-color: red; z-index: 10; } #dir5 { margin-left: 12.5vmin; background-color: red; z-index: 5; } #dir6 { margin-left: 22.5vmin; background-color: red; z-index: 5; } 
 <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Test</title> <link rel="stylesheet" href="styles/screen.css"> <script src="scripts/jquery-3.3.1.min.js"></script> <script src="scripts/app.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> </head> <body> <div id="cube" class="gimbal"> <div class="cubeface" id="A"> <div class="content" id="main"> <p>A</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir3 up"> </div> <div class="dir4 down"> </div> </div> <div class="cubeface" id="B"> <div class="content" id=""> <p>B</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir5 up"> </div> <div class="dir6 down"> </div> </div> <div class="cubeface" id="C"> <div class="content" id=""> <p>C</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir4 up"> </div> <div class="dir3 down"> </div> </div> <div class="cubeface" id="D"> <div class="content" id=""> <p>D</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir6 up"> </div> <div class="dir5 down"> </div> </div> <div class="cubeface" id="E"> <div class="content" id=""> <p>E</p> </div> <div class="dir6 right"> </div> <div class="dir5 left"> </div> <div class="dir3 up"> </div> <div class="dir4 down"> </div> </div> <div class="cubeface" id="F"> <div class="content" id=""> <p>F</p> </div> <div class="dir5 right"> </div> <div class="dir6 left"> </div> <div class="dir3 up"> </div> <div class="dir4 down"> </div> </div> </div> <div id="buttons"> <div class='arrow' id='dir1'>Y+</div> <div class='arrow' id='dir2'>Y-</div> <div class='arrow' id='dir3'>X+</div> <div class='arrow' id='dir4'>X-</div> <div class='arrow' id='dir5'>Z+</div> <div class='arrow' id='dir6'>Z-</div> </div> </body> </html> 


全球旋轉 - 軸不要與立方體一起旋轉

 function rotate(axis, degrees) { let outermostRotator = $('body > .gimbal').get(0); outermostRotator.outerHTML = `<div class='gimbal' id='container' style="transition: all 0.5s; transform-style: preserve-3d; transform: rotate${axis}(0deg); position: relative; transition-timing-function: ease-in-out; width: 0; height: 0; transform-origin: 50vw 50vh;">${outermostRotator.outerHTML}</div>`; window.setTimeout(function () { container.style.transform = `rotate${axis}(${degrees}deg)`; container.removeAttribute('id'); }, 10); } $('#dir1').on('click', function () { rotate('Y', '90'); }); $('#dir2').on('click', function () { rotate('Y', '-90'); }); $('#dir3').on('click', function () { rotate('X', '90'); }); $('#dir4').on('click', function () { rotate('X', '-90'); }); $('#dir5').on('click', function () { rotate('Z', '90'); }); $('#dir6').on('click', function () { rotate('Z', '-90'); }); rotate('X', '0'); 
 * { margin: 0; padding: 0; box-sizing: border-box; } html, body { font-size: 16px; font-family: sans-serif; width: 100%; height: 100%; -webkit-perspective: 100vmax; /* Safari 4-8 */ -webkit-perspective-origin: 50% 50%; /* Safari 4-8 */ perspective: 100vmax; perspective-origin: 50% 50%; overflow: hidden; } #cube { margin: auto; position: absolute; top: 50vh; left: 50vw; transform-style: preserve-3d; } .cubeface { position: absolute; height: 60vmin; width: 60vmin; margin-left: -30vmin; margin-top: -30vmin; opacity: 0.5; } .cubeface:nth-child(1) { transform: rotateY(0deg) translateY(0px) translateZ(30vmin); background-color: black; } .cubeface:nth-child(2) { transform: rotateY(90deg) translateY(0px) translateZ(30vmin); background-color: #343434; } .cubeface:nth-child(3) { transform: rotateY(180deg) translateY(0px) translateZ(30vmin); background-color: #525252; } .cubeface:nth-child(4) { transform: rotateY(270deg) translateY(0px) translateZ(30vmin); background-color: #818181; } .cubeface:nth-child(5) { transform: rotateX(90deg) translateZ(30vmin) translateY(0px); background-color: #a0a0a0; } .cubeface:nth-child(6) { transform: rotateX(-90deg) translateZ(30vmin) translateY(0px); background-color: #d8d8d8; } .content { width: 100%; height: 100%; position: absolute; border-radius: 50%; background-color: #a7ff8d; color: #f00; font-size: 3em; } .arrow { margin: auto; position: absolute; left: 50%; top: 90vmin; width: 5vmin; height: 5vmin; margin-left: -2.5vmin; margin-top: -2.5vmin; } .achse { height: 2px; width: 65vmin; background: #f00; position: absolute; top: 0; left: 0; transform-origin: 0; backface-visibility: visible; transform-style: preserve-3d; } .achseY { background: #0f0; transform: rotateZ(-90deg) rotateX(45deg); } .achseZ { background: #00f; transform: rotateY(-90deg) rotateX(45deg); } .achseX { transform: rotateX(45deg); } #deBug { background: #000; color: #FFF; font-size: 2em; padding: 1em; position: absolute; top: 0; right: 0; } #buttons { width: 100%; height: 100%; z-index: 5; } #dir1 { margin-left: -27.5vmin; background-color: red; z-index: 5; } #dir2 { margin-left: -17.5vmin; background-color: red; z-index: 5; } #dir3 { margin-left: -7.5vmin; background-color: red; z-index: 10; } #dir4 { margin-left: 2.5vmin; background-color: red; z-index: 10; } #dir5 { margin-left: 12.5vmin; background-color: red; z-index: 5; } #dir6 { margin-left: 22.5vmin; background-color: red; z-index: 5; } 
 <!doctype html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1"> <title>Test</title> <link rel="stylesheet" href="styles/screen.css"> <script src="scripts/jquery-3.3.1.min.js"></script> <script src="scripts/app.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> </head> <body> <div id="cube" class="gimbal"> <div class="cubeface" id="A"> <div class="content" id="main"> <p>A</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir3 up"> </div> <div class="dir4 down"> </div> </div> <div class="cubeface" id="B"> <div class="content" id=""> <p>B</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir5 up"> </div> <div class="dir6 down"> </div> </div> <div class="cubeface" id="C"> <div class="content" id=""> <p>C</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir4 up"> </div> <div class="dir3 down"> </div> </div> <div class="cubeface" id="D"> <div class="content" id=""> <p>D</p> </div> <div class="dir1 right"> </div> <div class="dir2 left"> </div> <div class="dir6 up"> </div> <div class="dir5 down"> </div> </div> <div class="cubeface" id="E"> <div class="content" id=""> <p>E</p> </div> <div class="dir6 right"> </div> <div class="dir5 left"> </div> <div class="dir3 up"> </div> <div class="dir4 down"> </div> </div> <div class="cubeface" id="F"> <div class="content" id=""> <p>F</p> </div> <div class="dir5 right"> </div> <div class="dir6 left"> </div> <div class="dir3 up"> </div> <div class="dir4 down"> </div> </div> </div> <div id="buttons"> <div class='arrow' id='dir1'>Y+</div> <div class='arrow' id='dir2'>Y-</div> <div class='arrow' id='dir3'>X+</div> <div class='arrow' id='dir4'>X-</div> <div class='arrow' id='dir5'>Z+</div> <div class='arrow' id='dir6'>Z-</div> </div> </body> </html> 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM