I'm trying to make a rotating cube, however I'm finding that the sides of the cube are being displayed depending on their order in the DOM rather than their 3d position.
I'm partially following this tutorial: 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>
Adding background to the images seems to fix the isssue:
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>