变换后的元素宽度和位置(translateZ和scale)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了变换后的元素宽度和位置(translateZ和scale)相关的知识,希望对你有一定的参考价值。
我正在尝试创建一个水平视差。有两个元素:具有可变内容的列表,以及与列表具有相同宽度的背景。视差给出了背景在列表后面移动的深度感。
这是一个代码段,请检查CSS注释作为后续跟踪:
document.querySelector('#transform').onchange = () => {
document.querySelector('.background').classList.toggle('background--transformed')
}
/*
its scrolls content and sets the value for the perspective
to enable the parallax effect
*/
.parallax {
perspective: 1px;
transform-style: preserve-3d;
overflow-y: hidden;
overflow-x: scroll;
}
/*
wrapper element for both list and background
used to make the background match the size of the list,
as the list grows it will expand the container and the
background will follow.
*/
.content {
position: relative;
display: inline-block;
}
/*
horizontal list
*/
.list {
display: inline-flex;
}
.list-item {
width: 20vw;
height: 80vh;
margin: 10vh 0;
background-color: red;
opacity: 0.9;
}
.list-item+.list-item {
margin-left: 1vw;
}
/*
background element that fill the entire width of it's parent
*/
.background {
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: black;
height: 100vh;
z-index: -1;
background: url(https://images.unsplash.com/photo-1499242165110-131f6ccd0c9a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80);
background-size: auto 100%;
}
/*
translates the element back into space, and scales it to the double
to match the original size. And this is what fails!
*/
.background--transformed {
transform: translateZ(-1px) scale(2);
}
.option {
position: fixed;
top: 0;
left: 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" />
<div class="parallax">
<div class="content">
<ul class="list">
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
</ul>
<div class="background"></div>
</div>
</div>
<div class="option">
<input type="checkbox" id="transform" name="transform">
<label for="transform">transform</label>
</div>
请注意,当启用translate
时(勾选左上角的复选框),背景大小会比列表大(向右滚动以查看)。
理论上,根据为透视设置的值,缩放到double应该“重置”大小。但我肯定在这里遗漏了一些东西......
答案
您的问题是2个元素(具有透视的元素和具有变换的元素)具有不同的大小。
因此,默认的起点是中心,不匹配。
将perspective-origin和transform-origin设置为相同的值(并且对一个,或多或少的居中进行仲裁),它们将匹配:
document.querySelector('#transform').onchange = () => {
document.querySelector('.background').classList.toggle('background--transformed')
}
/*
its scrolls content and sets the value for the perspective
to enable the parallax effect
*/
.parallax {
perspective: 1px;
transform-style: preserve-3d;
overflow-y: hidden;
overflow-x: scroll;
perspective-origin: 300px 220px;
}
/*
wrapper element for both list and background
used to make the background match the size of the list,
as the list grows it will expand the container and the
background will follow.
*/
.content {
position: relative;
display: inline-block;
}
/*
horizontal list
*/
.list {
display: inline-flex;
}
.list-item {
width: 20vw;
height: 80vh;
margin: 10vh 0;
background-color: red;
opacity: 0.9;
}
.list-item+.list-item {
margin-left: 1vw;
}
/*
background element that fill the entire width of it's parent
*/
.background {
position: absolute;
top: 0;
left: 0;
width: 100%;
background-color: black;
height: 100vh;
z-index: -1;
background: url(https://images.unsplash.com/photo-1499242165110-131f6ccd0c9a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1500&q=80);
background-size: auto 100%;
}
/*
translates the element back into space, and scales it to the double
to match the original size. And this is what fails!
*/
.background--transformed {
transform: translateZ(-1px) scale(2);
transform-origin: 300px 220px;
}
.option {
position: fixed;
top: 0;
left: 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css" rel="stylesheet" />
<div class="parallax">
<div class="content">
<ul class="list">
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
<li class="list-item"></li>
</ul>
<div class="background"></div>
</div>
</div>
<div class="option">
<input type="checkbox" id="transform" name="transform">
<label for="transform">transform</label>
</div>
以上是关于变换后的元素宽度和位置(translateZ和scale)的主要内容,如果未能解决你的问题,请参考以下文章
react-window构造的虚拟列表使用react-resizable动态调整宽度和使用react-drag-listview拖拽变换列位置的问题
react-window构造的虚拟列表使用react-resizable动态调整宽度和使用react-drag-listview拖拽变换列位置的问题