Ширина и положение элемента при преобразовании (translateZ и scale) - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь создать горизонтальный параллакс.Существует два элемента: список с переменным содержимым и фон , ширина которого равна ширине списка.Параллакс дает ощущение глубины, где фон движется за списком.

Вот фрагмент кода, пожалуйста, проверьте комментарии 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 (установите флажок в левом верхнем углу) размер фона увеличивается больше, чем в списке (выделитеправо видеть).

Теоретически, масштабирование до двойного значения должно «сбрасывать» размер в соответствии со значениями, установленными для перспективы.Но я наверняка что-то здесь упускаю ...

1 Ответ

0 голосов
/ 25 января 2019

Ваша проблема в том, что 2 элемента (один с перспективой и другой с преобразованием) имеют разные размеры.

Таким образом, исходные значения по умолчанию center не совпадают.

Задайте для параметра origin-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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...