我有两个带有3d变换(rotationY(的盒子。每个人都有几乎相同的价值观,一个观点看起来不错,另一个观点有点错误,但仍然有一些正确的观点。
顶部的第一个盒子没有突出,但它有一个透视图。此外,3°集装箱的大200%
第二个盒子做了一个美丽的3d效果。
在这里,我举了一个我试图解释的例子。
$(".eye").on('click', function () {
$( '.man' ).toggleClass('open');
})
* { padding: 0; margin: 0; }
.eye { padding: 6px 8px; }
.universe {
background: rgb(0 0 255 / 0.3);
position: absolute;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.dark {
background: rgb(0 255 0 / 0.3);
width: 25%;
height: 25%;
}
.god {
background: rgb(255 0 0 / 0.3);
transform-style: preserve-3d;
transform: perspective(800px);
}
.man {
position: absolute;
transform-origin: top left;
transition: 1s all linear;
}
.man.open {
transform: rotateY(-60deg);
}
.life {
background: rgb(255 255 0 / 0.36);
width: 25vw;
height: 25vh;
}
.no.god {
height: 100%;
}
.no.man {
position: relative;
}
.yes.god {
height: 200%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="universe">
<div class="dark">
<div class="god">
<div class="man">
<div class="life">Nothing happens until something moves.</div>
</div>
</div>
</div>
<button class="eye"> OPEN </button>
<div class="dark no">
<div class="god no">
<div class="man no">
<div class="life no">Nothing happens until something moves.</div>
</div>
</div>
</div>
<button class="eye"> OPEN </button>
<div class="dark yes">
<div class="god yes">
<div class="man yes">
<div class="life yes">Nothing happens until something moves.</div>
</div>
</div>
</div>
</div>
我认为有些地方出了问题,但不知道为什么。有人能解释一下它为什么会这样吗?
每个都有几乎相同的值,一个透视图看起来很好,
不,它们没有相同的值。一种是使用position:absolute
,另一种是position:relative
,这产生了很大的差异。如果检查god
元素,则在使用创建问题的position:absolute
(第一种情况(时会注意到其高度为0。
这里有一个简化的代码来更好地显示您的问题:
.box {
display: inline-block;
vertical-align:top;
width: 100px;
perspective: 200px;
position: relative;
margin: 20px;
background:blue;
}
.box>div {
position: relative;
padding: 10px;
background: red;
color: #fff;
transition: 1s all linear;
transform-origin: top left;
}
body:hover .box > div {
transform: rotateY(-40deg);
}
<div class="box">
<div>Some text here</div>
</div>
<div class="box">
<div style="position:absolute;">Some text here</div>
</div>
为了得到更准确的解释,我们需要参考规范
透视可以通过使Z轴上较高的元素(更靠近观看者(看起来更大,而离得更远的元素看起来更小,来为场景增加深度感。缩放与
d/(d − Z)
成比例,其中d
,即perspective
的值,是从绘图平面到观看者眼睛的假定位置的距离。其次,
perspective
和perspective-origin
属性可以应用于元素,以影响其三维变换的子元素的渲染,为他们提供一个共享的视角,让他们感觉生活在同一个三维场景中。
然后我们可以看到数学部分:
透视矩阵计算如下:
从单位矩阵开始。
通过计算的
perspective-origin
的X和Y值进行转换乘以从
perspective()
变换函数获得的矩阵,其中长度由透视属性的值提供通过
perspective-origin
的计算X和Y值取反进行转换
技巧在与perspective-origin
相关的步骤(1((4(中。如果我们检查定义,我们可以阅读:
perspective-origin
的值表示透视原点与参考框左上角的偏移
注意引用框,它是这里的关键,因为这是out情况下的变量(god
元素(。如果我们再加上默认值为50% 50%
,我们就会得到答案:
<percentage>
水平透视偏移的百分比相对于参照框的宽度。垂直偏移的百分比是相对于参考框的高度的。水平偏移和垂直偏移的值表示与参照框左上角的偏移。
现在我们有了所有的信息来了解正在发生的事情。在元素高度为0的第一种情况下,原点在顶部中心(我们只考虑宽度的50%
(,而在第二种情况下原点是中心,因为我们的元素的高度不同于0,更准确地说,高度等于变换元素的高度,这给了我们一个完美的结果。
如果我们改变perspective-origin
并考虑像素值,我们将对两者产生相同的结果:
.box {
display: inline-block;
vertical-align:top;
width: 100px;
perspective: 200px;
perspective-origin:50px 30px;
position: relative;
margin: 20px;
background:blue;
}
.box>div {
position: relative;
padding: 10px;
background: red;
color: #fff;
transition: 1s all linear;
transform-origin: top left;
}
body:hover .box > div {
transform: rotateY(-40deg);
}
<div class="box">
<div>Some text here</div>
</div>
<div class="box">
<div style="position:absolute;">Some text here</div>
</div>
总之,perspective-origin
的默认值是50% 50%
,百分比基于我们应用透视图的元素的大小。现在很明显,如果大小改变,原点将不再相同,这将从逻辑上给我们一个不同的趋势。
为了避免这种情况,我们要么为原点设置像素值,要么考虑直接在相关元素(我们想要变换的元素(上使用perspective()
,在这种情况下,我们确信结果是相同的,因为两个元素都是相同的:
.box {
display: inline-block;
vertical-align:top;
width: 100px;
position: relative;
margin: 20px;
background:blue;
}
.box>div {
position: relative;
padding: 10px;
background: red;
color: #fff;
transition: 1s all linear;
transform-origin: center left;
transform: perspective(200px) rotateY(0);
}
body:hover .box > div {
transform: perspective(200px) rotateY(-40deg);
}
<div class="box">
<div>Some text here</div>
</div>
<div class="box">
<div style="position:absolute;">Some text here</div>
</div>
<div class="box" style="height:500px;">
<div style="position:absolute;">Some text here</div>
</div>
在上面应该注意到,perspective-origin
是不相关的,transform-origin
定义了原点,因为我们使用的是透视图的转换函数版本。
相关问题:
透视和平移Z对角移动
如何在透视模式下计算旋转角度以使宽度适合所需尺寸?
CSS三维转换没有';如果透视设置在属性的末尾,则不起作用