3d框网格(仅两个面)

时间:2018-07-26 08:03:35

标签: javascript css css3 css-animations css-transforms

我有一个只有两个面(正面和底面)的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);
}
<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>

现在,此设置的问题是盒子之间重叠。我可以手动消除重叠,然后要做以下更改/计算:

  • 更改width的{​​{1}},heightmargin(右侧和底部)
  • 更改.box-wrappertransform的{​​{1}}(translateZ

并且由于一项更改会影响其他更改,因此是有问题的。

例如,要摆脱上面设置(1000像素容器)中的重叠部分,需要进行以下更改:

.face.front

.face.bottom
.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);
}

我还计划使此移动设备友好,以便随着窗口宽度的更改,我将更改容器(.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); })的宽度,并进行上述更改。因此,我仅有的变量是容器宽度,该宽度将相对于窗口宽度而变化,并且盒子应占据容器宽度的25%。如何自动进行此计算?由于计算包括透视图和变换,因此我什么都还没有。

即使我手动为大屏幕断点计算值(宽度,边距,变换)(尝试错误),在某些时候我也需要使用JS自动进行处理,例如768px以下。

1 个答案:

答案 0 :(得分:3)

很明显,这个问题来自result: id | user | partner | company ------------------------------ 1 | 2 | 2 | comp2 2 | 2 | 2 | comp2 4 | 3 | 2 | comp3 并结合了观点。通过积极的翻译,您正在使您的元素更接近您,而透视图正在创造重叠。

为了避免这种情况,我们可以避免使用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;
}

如您所见,前元素不再有<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>,因此最初没有更多的重叠,然后我调整translateZ和平移以补偿应用于{底部元素。

所有使用的值都是使用百分比的相对值,因此进行计算不会有任何问题。我还添加了transform-origin以在高度/宽度计算中包括边框,以便您可以精确使用translateZ中一半的高度(box-sizing:border-box)。

更新

我在250px / 2 = 125px上添加了一个过渡,以便从中心而不是从顶部完全旋转。

更新2

根据评论中的建议,我们也可以将translateZ更改为transform-origin

transform-orgin
center center -125px