3d-преобразование: DOM-порядок имеет приоритет над z-преобразованием - PullRequest
0 голосов
/ 14 марта 2020

Я пытаюсь сделать вращающийся куб, однако я обнаружил, что стороны куба отображаются в зависимости от их порядка в DOM, а не от их трехмерного положения.

  • Is есть что-то, чего мне не хватает, чтобы заставить это использовать 3d-позицию над порядком DOM?

Я частично следую этому уроку: https://3dtransforms.desandro.com/cube

  • Фрагмент кода необходимо просматривать в полноэкранном режиме, чтобы увидеть элемент управления для 3d-переходов
  • После проверки стека браузера проблема, по-видимому, возникает только в Chrome

document.addEventListener('DOMContentLoaded', function(){
    let control = document.querySelector("#control")
    let cube = document.querySelector('.cube')
    let re = /show\-.*/
    control.addEventListener('change', (evt)=>{
        cube.classList.forEach((value, key, parent)=>{
            if (re.test(value)){
                cube.classList.remove(value)
            }
        })
        cube.classList.add(`show-${control.value}`)
    })
})
body{
    margin: 0;
    width: 100vw;
    height: 100vh;
    
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    flex-direction: column;
}
.scene {
    width: 200px;
    height: 200px;
    perspective: 600px;
  }
  
  .cube {
    width: 100%;
    height: 100%;
    position: relative;
    transform-style: preserve-3d;
  }
  
  .cube__face {
    position: absolute;
    width: 200px;
    height: 200px;
  }

.cube__face--front  { transform: rotateY(  0deg) translateZ(100px); }
.cube__face--right  { transform: rotateY( 90deg) translateZ(100px); }
.cube__face--back   { transform: rotateY(180deg) translateZ(100px); }
.cube__face--left   { transform: rotateY(-90deg) translateZ(100px); }
.cube__face--top    { transform: rotateX( 90deg) translateZ(100px); }
.cube__face--bottom { transform: rotateX(-90deg) translateZ(100px); }

.cube.show-front  { transform: translateZ(-100px) rotateY(   0deg); }
.cube.show-right  { transform: translateZ(-100px) rotateY( -90deg); }
.cube.show-back   { transform: translateZ(-100px) rotateY(-180deg); }
.cube.show-left   { transform: translateZ(-100px) rotateY(  90deg); }
.cube.show-top    { transform: translateZ(-100px) rotateX( -90deg); }
.cube.show-bottom { transform: translateZ(-100px) rotateX(  90deg); }

.cube { transition: transform 3s; }
<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="style.css">
        <script src="main.js"></script>
    </head>

    <body>
        <div class="scene">
            <div class="cube">
                <img class="cube__face cube__face--back" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--right" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--left" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--top" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--bottom" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--front" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
            </div>
        </div>
        <div class="controls">
            <select name="control" id="control" value="front">
                <option value="front">front</option>
                <option value="back">back</option>
                <option value="right">right</option>
                <option value="left">left</option>
                <option value="top">top</option>
                <option value="bottom">bottom</option>
            </select>
        </div>
    </body>

</html>

1 Ответ

1 голос
/ 14 марта 2020

Добавление фона к изображениям, кажется, исправляет проблему:

document.addEventListener('DOMContentLoaded', function(){
    let control = document.querySelector("#control")
    let cube = document.querySelector('.cube')
    let re = /show\-.*/
    control.addEventListener('change', (evt)=>{
        cube.classList.forEach((value, key, parent)=>{
            if (re.test(value)){
                cube.classList.remove(value)
            }
        })
        cube.classList.add(`show-${control.value}`)
    })
})
body{
    margin: 0;
    width: 100vw;
    height: 100vh;
    
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    flex-direction: column;
}
.scene {
    width: 200px;
    height: 200px;
    perspective: 600px;
  }
  
  .cube {
    width: 100%;
    height: 100%;
    position: relative;
    transform-style: preserve-3d;
  }
  
  .cube__face {
    position: absolute;
    width: 200px;
    height: 200px;
  }

.cube__face--front  { transform: rotateY(  0deg) translateZ(100px); }
.cube__face--right  { transform: rotateY( 90deg) translateZ(100px); }
.cube__face--back   { transform: rotateY(180deg) translateZ(100px); }
.cube__face--left   { transform: rotateY(-90deg) translateZ(100px); }
.cube__face--top    { transform: rotateX( 90deg) translateZ(100px); }
.cube__face--bottom { transform: rotateX(-90deg) translateZ(100px); }

.cube.show-front  { transform: translateZ(-100px) rotateY(   0deg); }
.cube.show-right  { transform: translateZ(-100px) rotateY( -90deg); }
.cube.show-back   { transform: translateZ(-100px) rotateY(-180deg); }
.cube.show-left   { transform: translateZ(-100px) rotateY(  90deg); }
.cube.show-top    { transform: translateZ(-100px) rotateX( -90deg); }
.cube.show-bottom { transform: translateZ(-100px) rotateX(  90deg); }

.cube { transition: transform 3s; }

img {
  background:#ffde39;
}
<!DOCTYPE html>
<html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <link rel="stylesheet" href="style.css">
        <script src="main.js"></script>
    </head>

    <body>
        <div class="scene">
            <div class="cube">
                <img class="cube__face cube__face--back" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--right" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--left" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--top" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--bottom" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
                <img class="cube__face cube__face--front" src="https://media.giphy.com/media/l4KhKRcaYb43LVqq4/source.gif">
            </div>
        </div>
        <div class="controls">
            <select name="control" id="control" value="front">
                <option value="front">front</option>
                <option value="back">back</option>
                <option value="right">right</option>
                <option value="left">left</option>
                <option value="top">top</option>
                <option value="bottom">bottom</option>
            </select>
        </div>
    </body>

</html>
...