正如您在 codepen.io 下看到的,我使用 CSS 在 3D 结构中构建了 3D 立方体(橙色)的透视图。
:root {
--side: 40px;
--rowCols: 3;
--wh: 121px;
--mside: -40px;
--twoSides: -80px;
}
body {
background-color: blue;
}
.canvas {
position: absolute;
left: 0px;
top: 10px;
transform-style: preserve3d;
perspective: 850px;
}
.grid {
position: absolute;
left: 200px;
top: 75px;
transform-style: preserve-3d;
animation: spin 15s infinite linear;
}
.grid .face {
position: absolute;
height: var(--wh);
width: var(--wh);
margin: 0;
background-image: repeating-linear-gradient(#ccc 0 1px, transparent 1px 100%),
repeating-linear-gradient(90deg, #ccc 0 1px, transparent 1px 100%);
background-size: var(--side) var(--side);
}
.cube {
left: 200px;
top: 75px;
position: absolute;
width: calc(var(--side) + 1);
height: calc(var(--side) + 1);
transform-style: preserve-3d;
/*transform: translateZ(var(--side));*/
animation: spin 15s infinite linear;
}
.cube .cface {
width: var(--side);
height: var(--side);
position: absolute;
border: 1px solid black;
display: flex;
background-color: rgb(238, 141, 14);
}
.cube .cface:nth-child(1) {
transform: translateZ(var(--side));
}
.cube .cface:nth-child(2) {
transform-origin: center right;
transform: rotateY(90deg);
}
.cube .cface:nth-child(3) {
transform-origin: center left;
transform: rotateY(-90deg);
}
.cube .cface:nth-child(4) {
transform-origin: top center;
transform: rotateX(90deg);
}
.cube .cface:nth-child(5) {
transform-origin: top center;
transform: rotateX(90deg) translateZ(var(--mSides));
}
@keyframes spin {
from {
transform: rotate3d(1, 1, 0, 0deg);
}
to {
transform: rotate3d(1, 1, 0, 360deg);
}
}
我设法使用 JS 函数 setValues() 动态构建它,其中“side”是橙色立方体的边宽度(以 px 为单位),“rowsCols”是每边的立方体数量。 我想将橙色立方体放置在定义的结构中,但我没有找到如何在所有 3D 轴上移动一个单位。 有人知道怎么做吗?
代码演示:
setValues(40, 3)
function setValues(side, rowsCols) {
let r = document.querySelector(':root')
r.style.setProperty('--side', `${side}px`)
r.style.setProperty('--rowCols', `${rowsCols}`)
r.style.setProperty('--wh', `${side * rowsCols + 1}px`)
r.style.setProperty('--mside', `-${side}px`)
r.style.setProperty('--twoSides', `-${side * 2}px`)
let str = ""
let max = (rowsCols + 1) * 2
for (let n = 0; n < max; n++) {
str = `${str}<div class="face"></div>\n`
}
//console.log(str)
document.getElementById("grid").innerHTML = str
str = ""
let pix = side
let f = 1
for (; f <= rowsCols; f++) {
str = `${str}.grid .face:nth-child(${f}){transform: translateZ(${pix}px);}\n`
pix += side
}
pix = 0
for (; f < max; f++) {
str = `${str}.grid .face:nth-child(${f}){transform-origin: center right; transform: rotateY(90deg) translateZ(${pix}px);}\n`
pix -= side
}
//console.log(str)
document.getElementById("style").innerHTML = str
}
:root {
--side: 40px;
--rowCols: 3;
--wh: 121px;
--mside: -40px;
--twoSides: -80px;
}
body {
background-color: blue;
}
.canvas {
position: absolute;
left: 0px;
top: 10px;
transform-style: preserve3d;
perspective: 850px;
}
.grid {
position: absolute;
left: 200px;
top: 75px;
transform-style: preserve-3d;
animation: spin 15s infinite linear;
}
.grid .face {
position: absolute;
height: var(--wh);
width: var(--wh);
margin: 0;
background-image: repeating-linear-gradient(#ccc 0 1px, transparent 1px 100%), repeating-linear-gradient(90deg, #ccc 0 1px, transparent 1px 100%);
background-size: var(--side) var(--side);
}
.cube {
left: 200px;
top: 75px;
position: absolute;
width: calc(var(--side) + 1);
height: calc(var(--side) + 1);
transform-style: preserve-3d;
/*transform: translateZ(var(--side));*/
animation: spin 15s infinite linear;
}
.cube .cface {
width: var(--side);
height: var(--side);
position: absolute;
border: 1px solid black;
display: flex;
background-color: rgb(238, 141, 14);
}
.cube .cface:nth-child(1) {
transform: translateZ(var(--side));
}
.cube .cface:nth-child(2) {
transform-origin: center right;
transform: rotateY(90deg);
}
.cube .cface:nth-child(3) {
transform-origin: center left;
transform: rotateY(-90deg);
}
.cube .cface:nth-child(4) {
transform-origin: top center;
transform: rotateX(90deg);
}
.cube .cface:nth-child(5) {
transform-origin: top center;
transform: rotateX(90deg) translateZ(var(--mSides));
}
@keyframes spin {
from {
transform: rotate3d(1, 1, 0, 0deg);
}
to {
transform: rotate3d(1, 1, 0, 360deg);
}
}
<style id="style"></style>
<div class="canvas">
<div class="grid" id="grid">
<div class="face"></div>
</div>
<div class="cube">
<div class="cface"></div>
<div class="cface"></div>
<div class="cface"></div>
<div class="cface"></div>
<div class="cface"></div>
<div class="cface"></div>
</div>
</div>
过了一段时间,我找到了让橙色立方体成为网格结构或更好地说类的一部分的方法。我修改了一些 HTML、CSS 和 JS。新版本已在 [codepen.io V2][1] 中提供 HTML:
<style id="style"></style>
<div class="canvas">
<div class="grid" id="grid"></div>
</div>
</div>
CSS:
:root {
--side: 40px;
--rowCols: 3;
--wh: 121px;
--mside: -40px;
--twoSides: -80px;
}
body {
background-color: blue;
}
.canvas {
position: absolute;
left: 60px;
top: 60px;
transform-style: preserve3d;
perspective: 800px;
}
.grid {
position: absolute;
transform-style: preserve-3d;
animation: spin 15s infinite linear;
}
.grid .face {
position: absolute;
height: var(--wh);
width: var(--wh);
background-image:
repeating-linear-gradient(#000 0 1px, transparent 1px 100%),
repeating-linear-gradient(90deg, #000 0 1px, transparent 1px 100%);
background-size: var(--side) var(--side);
}
.cube {
position: absolute;
width: calc(var(--side) + 1);
height: calc(var(--side) + 1);
transform-style: preserve-3d;
}
.cube .cface {
width: var(--side);
height: var(--side);
position: absolute;
border: 1px solid black;
display: flex;
background-color: rgb(238, 141, 14);
}
.cube .cface:nth-child(2) {
transform: translateZ(var(--side));
}
.cube .cface:nth-child(3) {
transform-origin: center right;
transform: rotateY(90deg);
}
.cube .cface:nth-child(4) {
transform-origin: center left;
transform: rotateY(-90deg);
}
.cube .cface:nth-child(5) {
transform-origin: top center;
transform: rotateX(90deg);
}
.cube .cface:nth-child(6) {
transform-origin: bottom center;
transform: rotateX(-90deg);
}
@keyframes spin {
from {
transform: rotate3d(1, 1, 1, 0deg);
}
to {
transform: rotate3d(1, 1, 1, 360deg);
}
}
setValues(40, 3)
function setValues(side, rowsCols){
let r = document.querySelector(':root')
r.style.setProperty('--side', `${side}px`)
r.style.setProperty('--rowCols', `${rowsCols}`)
r.style.setProperty('--wh', `${side * rowsCols + 1}px`)
r.style.setProperty('--mside', `-${side}px`)
r.style.setProperty('--twoSides', `-${side * 2}px`)
let str = ""
let max = (rowsCols + 1) * 2
for (let n = 0; n < max; n++){
str = `${str}<div class="face"></div>\n`
}
//console.log(str)
str = `${str}<div class="cube">\n`
for (let n = 0; n < 6; n++){
str = `${str}<div class="cface"></div>\n`
}
document.getElementById("grid").innerHTML = str + `</div>`
str = ""
let pix = side
let f = 1
for (; f <= rowsCols; f++){
str = `${str}.grid .face:nth-child(${f}){transform: translateZ(${pix}px);}\n`
pix += side
}
pix = 0
for (; f < max; f++){
str = `${str}.grid .face:nth-child(${f}){transform-origin: center right; transform: rotateY(90deg) translateZ(${pix}px);}\n`
pix -= side
}
//console.log(str)
document.getElementById("style").innerHTML = str
}
[1]: https://codepen.io/Philippe-Lagarrigue/pen/yLwjKoR