Подтвердить что ты не робот

Formular для вычисления ширины/высоты (относительно родительского) контейнера с translateZ внутри родительского контейнера с перспективой

Что такое формуляр для вычисления ширины/высоты дочерних элементов с translateZ внутри родительского контейнера с набором perspective (ключевое слово: "parallax" ) относительно его родителей width/height?

Я хотел бы создать сайт с эффектом параллакса на обеих осях. Мне удалось выяснить все, что мне нужно для моего макета, кроме одного. Как рассчитать ширину/высоту детей, когда он превышает 100%. Из-за того, что родители смотрят на перспективу и переводили детейZ, ширина/высота детей снизу визуально не выравниваются с шириной и высотой родителей.

Формуляр для масштабирования дочерних элементов: 1 + (translateZ * -1) / perspective. Но я не смог найти формуляр для ширины/высоты. BTW: Когда детская ширина/высота <= 100% все работает нормально.
Но см. Результат на изображении ниже, когда ширинa >= 100% (контейнеры имеют верхнее смещение, чтобы сделать видимыми вещи).

введите описание изображения здесь

Чтобы быть точным, подход в моем конкретном случае состоит в том, чтобы все дочерние элементы имели визуально одинаковые ширины/высоты.


в SASS (предпочтительный): PEN или SassMeister
в CSS: PEN


ссылки из спецификаций, которые могут помочь:
https://www.w3.org/TR/css-transforms-1/#recomposing-to-a-3d-matrix
https://www.w3.org/TR/css-transforms-1/#mathematical-description


"Googled" много, но не нашел ничего, указывающего на меня в правильном направлении. Спасибо заранее...

html, body {
  height: 100%;
  overflow: hidden;
  width: 100%;
}

#projection {
  perspective: 1px;
  perspective-origin: 0 0;
  height: 100%;
  overflow: auto;
  width: 100%;
}

.pro {
  transform: scale(1) translate(0px, 0px) translateZ(0px);
  height: 100%;
  position: absolute;
  transform-origin: 0 0;
  transform-style: preserve-3d;
  width: 100%;
}

.pro--1 {
  transform: scale(4) translate(0px, 0px) translateZ(-3px);
  width: 110%;
}

.pro--2 {
  transform: scale(3) translate(0px, 50%) translateZ(-2px);
  width: 110%;
}

.pro--3 {
  transform: scale(2) translate(0px, 100%) translateZ(-1px);
  width: 110%;
}

.pro {
  background: #333;
  box-shadow: inset 0 0 0 5px orange;
  color: orange;
  font-size: 4em;
  line-height: 1em;
  text-align: center;
}

.pro--2 {
  background: rgba(75, 75, 75, 0.5);
  box-shadow: inset 0 0 0 5px green;
  color: green;
  line-height: 4em;
}

.pro--3 {
  background: rgba(75, 75, 75, 0.5);
  box-shadow: inset 0 0 0 5px white;
  color: white;
  line-height: 7em;
}
<div id="projection">
  <div class="pro pro--1">pro--1</div>
  <div class="pro pro--2">pro--2</div>
  <div class="pro pro--3">pro--3</div>
</div>
4b9b3361

Ответ 1

Формуляр для вычисления ширины/высоты дочерних элементов с translateZ внутри родительского контейнера с заданной перспективой: $scale = 1 + (translateZ * -1) / perspective.


Где бросить этот формуляр в transform: scale( $scale ).
perspective - это значение перспективы для родителей, а translateZ - значение translateZ. См. Фрагмент внизу или SASS mockup, как вам нравится.


Итак, на самом деле ответ был задан в вопросе!
Хотя это правильный ответ на заданный вопрос, это совсем не решило мою конкретную проблему, поэтому вот следующий вопрос.


Кредиты: @Trolleymusic, которые хотя бы открыли мои глаза .


Пример CSS:

/* formular: 1 + (translateZ * -1) / perspective */

#parent {
  perspective: 10px;
}

.child--1 { /* 1 + (-100 * -1) / 10 */
  transform: translateZ(-100px) scale( 11 );
}

.child--2 { /* 1 + (-200 * -1) / 10 */
  transform: translateZ(-200px) scale( 21 );
}

.child--3 { /* 1 + (1 * -1) / 10 */
  transform: translateZ(1px) scale( 0.9 );
}

Ответ 2

Вы уже решили свою проблему. Ваш код делает именно то, что вам нужно, это просто проблема с макетом CSS.

https://codepen.io/anon/pen/xLWGzp?editors=0100

Из-за изменений перспективы, если вы повесите все с центра оси x, все начнет правильно выравниваться:

(Я просто добавляю изменения кода здесь, я оставил все остальное одинаково)

#projection
    perspective-origin: center top

.pro
    transform-origin: center top

Теперь все выстраивается лучше, но все равно немного - вы можете изменить переменную $width на что-либо, кроме 100%, чтобы увидеть проблему (60% является хорошим)

Таким образом, проблема теперь связана с позиционированием элементов, когда вы устанавливаете position: absolute, по умолчанию они расположены слева, изменяют ширину и добавляют масштаб и преобразование, и вы получаете эту равную ширину/равное положение, поэтому центрируйте их, добавив:

#projection
    position: relative

.pro
    left: 50%
    margin-left: $width * -.5

(информация здесь о том, почему это работает в центре: https://css-tricks.com/quick-css-trick-how-to-center-an-object-exactly-in-the-center/)

Итак, теперь, чтобы дважды проверить $width, я проверил его с 20% до 150%, и он отлично работает.

Ответ 3

Я немного изменил стиль, чтобы сделать вещи более заметными.

Результат кажется мне подходящим. Может быть, я что-то недопонимаю?

html, body {
  height: 100%;
  overflow: hidden;
  width: 100%;
}

#projection {
  perspective: 1px;
  perspective-origin: 0 0;
  height: 50%;
  overflow: visible;
  width: 50%;
  margin-left: 50px;
  background-color: grey;
}

.pro {
  transform: scale(1) translate(0px, 0px) translateZ(0px);
  height: 50%;
  position: absolute;
  transform-origin: 0 0;
  transform-style: preserve-3d;
  width: 100%;
}

.pro--1 {
  transform: scale(4) translate(0px, 0px) translateZ(-3px);
  width: 110%;
}

.pro--2 {
  transform: scale(3) translate(0px, 120%) translateZ(-2px);
  width: 110%;
}

.pro--3 {
  transform: scale(2) translate(0px, 240%) translateZ(-1px);
  width: 110%;
}

.pro--1 {
  background: rgba(0, 0, 75, 0.5);
  color: blue;
  line-height: 1em;
  text-align: center;
}

.pro--2 {
  background: rgba(0, 75, 0, 0.5);
  color: green;
  line-height: 4em;
}

.pro--3 {
  background: rgba(75, 0, 0, 0.5);
  color: red;
  line-height: 7em;
}
<div id="projection">
  <div class="pro pro--1">pro--1</div>
  <div class="pro pro--2">pro--2</div>
  <div class="pro pro--3">pro--3</div>
</div>