aki*_*uri 6 javascript css css3 css-transforms css-animations
我有一个3d框的网格,只有两个面(正面和底面).每个盒子都有自己的视角.悬停时,框旋转; 底面朝向前方.例如:
.grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 1000px;
margin: 50px auto;
}
.box-wrapper {
width: 25%;
height: 250px;
perspective: 1000px;
}
.box {
width: 100%;
height: 100%;
position: relative;
transition: transform .5s;
transform-style: preserve-3d;
}
.box .face {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
}
.box .face.front {
transform: translateZ(123.5px);
background-color: hsla(0, 100%, 50%, .5);
}
.box .face.bottom {
transform: rotateX(-90deg) translateZ(123.5px);
background-color: hsla(120, 100%, 50%, .5);
}
.box:hover {
transform: rotateX(90deg);
}Run Code Online (Sandbox Code Playgroud)
<div class="grid">
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
现在,此设置的问题是框之间的重叠.我可以手动摆脱重叠,为此,我需要做以下更改/计算:
width,height和margin所述s(右和底部).box-wrappertransform(translateZ)的.face.front和.face.bottom并且由于一个变化影响其他变化,这是有问题的.
例如,要消除上面设置(1000px容器)中的重叠,它需要进行以下更改:
.box-wrapper {
width: calc(25% - 29px); // why 29?
margin-right: 29px;
margin-bottom: 29px;
height: 221px;
}
.box .face.front {
transform: translateZ(110.5px); // half of box's width
}
.box .face.bottom {
transform: rotateX(-90deg) translateZ(110.5px);
}
Run Code Online (Sandbox Code Playgroud)
.grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 1000px;
margin: 50px auto;
}
.box-wrapper {
width: calc(25% - 29px);
margin-right: 29px;
margin-bottom: 29px;
height: 221px;
perspective: 1000px;
}
.box {
width: 100%;
height: 100%;
position: relative;
transition: transform .5s;
transform-style: preserve-3d;
}
.box .face {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
}
.box .face.front {
transform: translateZ(110.5px);
background-color: hsla(0, 100%, 50%, .5);
}
.box .face.bottom {
transform: rotateX(-90deg) translateZ(110.5px);
background-color: hsla(120, 100%, 50%, .5);
}
.box:hover {
transform: rotateX(90deg);
}Run Code Online (Sandbox Code Playgroud)
<div class="grid">
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
我还计划使这个移动设备友好,所以当窗口宽度改变时,我将改变容器(.grid)的宽度,并进行上述更改.因此,我所拥有的唯一变量是容器宽度,它将相对于窗口宽度而变化,并且盒子应占据容器宽度的25%.如何自动进行此计算?由于计算包括透视和变换,我还无法想出任何东西.
即使我手动计算(宽度,边距,变换)大屏幕断点的值(试错),在某些时候我需要自动使用JS,例如低于768px.
很明显,这个问题是从translateZ综合角度来看的。你正在通过积极的翻译让你的元素更接近你,而视角则创造了重叠。
为了避免这种情况,我们需要避免translateZ并使用另一个配置来创建类似的效果。这是一个想法:
.grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 1000px;
margin: 50px auto;
}
.box-wrapper {
width: 25%;
height: 250px;
perspective: 1000px;
}
.box {
width: 100%;
height: 100%;
position: relative;
transition: transform .5s, transform-origin 0.5s;
transform-style: preserve-3d;
}
.box .face {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
box-sizing:border-box;
}
.box .face.front {
background-color: hsla(0, 100%, 50%, .5);
}
.box .face.bottom {
transform: rotateX(-90deg) translateY(50%) translateZ(125px);
background-color: hsla(120, 100%, 50%, .5);
}
.box:hover {
transform: rotateX(90deg) translateY(-100%);
transform-origin:top;
}Run Code Online (Sandbox Code Playgroud)
<div class="grid">
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
正如您所看到的,前面的元素不再存在translateZ,因此最初不再有重叠,然后我调整transform-origin平移以补偿translateZ应用于底部元素的平移。
使用的所有值都是使用百分比的相对值,因此计算时不会有任何问题。我还添加了box-sizing:border-box在高度/宽度计算中包含边框,以便您可以准确地使用 中高度 ( 250px / 2 = 125px)的一半translateZ。
更新
我添加了一个过渡,以便transform-origin以某种方式从中心而不是完全从顶部进行旋转。
更新2
正如评论中所建议的,我们也可以更改transform-orgin为center center -125px
.grid {
display: flex;
flex-direction: row;
flex-wrap: wrap;
width: 1000px;
margin: 50px auto;
}
.box-wrapper {
width: 25%;
height: 250px;
perspective: 1000px;
}
.box {
width: 100%;
height: 100%;
position: relative;
transition: transform .5s;
transform-style: preserve-3d;
transform-origin:center center -125px;
}
.box .face {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
border: 1px solid black;
display: flex;
justify-content: center;
align-items: center;
box-sizing:border-box;
}
.box .face.front {
background-color: hsla(0, 100%, 50%, .5);
}
.box .face.bottom {
transform: rotateX(-90deg) translateY(50%) translateZ(125px);
background-color: hsla(120, 100%, 50%, .5);
}
.box:hover {
transform: rotateX(90deg);
}Run Code Online (Sandbox Code Playgroud)
<div class="grid">
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
<div class="box-wrapper">
<div class="box">
<div class="face front">front face</div>
<div class="face bottom">bottom-face</div>
</div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)