3d 变换:DOM 顺序优先于 z 变换

3d transform: DOM order taking priority over z-transform

我正在尝试制作一个旋转的立方体,但是我发现立方体的边显示是根据它们在 DOM 中的顺序而不是它们的 3d 位置。

我正在部分遵循本教程:https://3dtransforms.desandro.com/cube

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>

为图像添加背景似乎可以解决问题:

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>