3d 变换:DOM 顺序优先于 z 变换
3d transform: DOM order taking priority over z-transform
我正在尝试制作一个旋转的立方体,但是我发现立方体的边显示是根据它们在 DOM 中的顺序而不是它们的 3d 位置。
- 我是否遗漏了一些东西来让它在 DOM 订单上使用 3d 位置?
我正在部分遵循本教程:https://3dtransforms.desandro.com/cube
- 必须在全页模式下查看代码片段才能看到 3d 转换控件
- 检查 browserstack 后,问题似乎只发生在 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>
为图像添加背景似乎可以解决问题:
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>
我正在尝试制作一个旋转的立方体,但是我发现立方体的边显示是根据它们在 DOM 中的顺序而不是它们的 3d 位置。
- 我是否遗漏了一些东西来让它在 DOM 订单上使用 3d 位置?
我正在部分遵循本教程:https://3dtransforms.desandro.com/cube
- 必须在全页模式下查看代码片段才能看到 3d 转换控件
- 检查 browserstack 后,问题似乎只发生在 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>
为图像添加背景似乎可以解决问题:
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>