formular用于计算容器的宽度/高度(相对于父级),其中带有透视的父容器内的translateZ

时间:2017-08-08 21:12:47

标签: css css3 sass parallax css-transforms

使用translateZ设置perspective(关键字:“parallax”)相对于其父级宽度/高度的父容器中1 + (translateZ * -1) / perspective计算子元素的宽度/高度的公式是什么?

我想在两个轴上创建一个具有视差效果的网站。除了一件事,我能够弄清楚我的模型需要的一切。当它超过100%时,如何计算儿童的宽度/高度。 由于父母的观点和儿童的翻译,儿童的宽度/高度在视觉上不再与父母的宽度/高度对齐。

缩放子元素的公式是: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; }。但我无法找到宽度/高度的公式。顺便说一句:当孩子的宽度/高度<= 100%时,一切正常 但是当 width&gt; = 100%时,请查看下图中的结果(容器有顶部偏移以使事物可见)。

enter image description here

为了更正,在我的特定情况下,方法是让所有子元素在视觉上具有相同的宽度/高度。

在SASS(首选)中的

:CSS中的PENSassMeister <PEN

来自规范的链接可能会有所帮助:
https://www.w3.org/TR/css-transforms-1/#recomposing-to-a-3d-matrix
https://www.w3.org/TR/css-transforms-1/#mathematical-description

“谷歌搜索”很多,但没有找到任何指向我正确方向的东西。提前致谢...

<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>
@mixin  projection($translateZ: 0, $translateX: 0, $translateY: 0, $width: 0, $height: 0, $perspective: $perspective)

  // strip and sanitize units for further calculations
  // units must be "px" for both $translateZ and $perspective
  $unit: unit( $translateZ )
  @if '' != $unit
    $translateZ: $translateZ / ($translateZ * 0 + 1)
    @if 'px' != $unit
      @warn '$translateZ must have "px" as unit!'

  $unit: unit( $perspective )
  @if '' != $unit
    $perspective: $perspective / ($perspective * 0 + 1)
    @if 'px' != $unit
      @warn '$perspective must have "px" as unit!'

  $unit: 0px // yeah - technically this is no unit

  // calculate scaling factor
  $scale: 1 + ($translateZ * -1) / $perspective

  // sanitize units for translateX, translateY, translateZ
  $translateZ: $translateZ + $unit
  @if unitless( $translateX )
    $translateX: $translateX + $unit
  @if unitless( $translateY )
    $translateY: $translateY + $unit

  // render css "transform: scale() translate(x, y) translateZ()"
  transform: scale( $scale ) translate($translateX, $translateY) translateZ( $translateZ + $unit )

$width: 110% // 100% works like a charme
$translateZ--1: -3 // "px" will be added in mixin
$translateZ--2: -2
$translateZ--3: -1
$perspective: 1

html, body
  height: 100%
  overflow: hidden
  width: 100%

#projection
  perspective: $perspective + 0px
  perspective-origin: 0 0
  height: 100%
  overflow: auto
  width: 100%

.pro
  @include projection()
  height: 100%
  position: absolute
  transform-origin: 0 0
  transform-style: preserve-3d
  width: 100%

.pro--1
  @include projection( $translateZ--1 )
  width: $width

.pro--2
  @include projection( $translateZ--2, 0, 50% )
  width: $width

.pro--3
  @include projection( $translateZ--3, 0, 100% )
  width: $width

SASS

{{1}}

3 个答案:

答案 0 :(得分:3)

您已经解决了问题。您的代码完全按照您的需要执行,现在只是一个CSS布局问题。

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

由于透视变化,如果你将所有东西都悬挂在x轴中心,一切都会正常排列:

(我只是在这里添加代码更改,我已将其他所有内容保持不变)

#projection
    perspective-origin: center top

.pro
    transform-origin: center top

现在所有内容都排得更好,但仍然有点偏离 - 您可以将$width变量更改为除100%以外的任何内容以查看问题({{ 1}}是一个很好的一个)

所以问题现在只是由于元素的定位,当你设置60%它们的默认位置在左边,改变宽度并添加比例和变换时你会得到相同的 - width / not-equal-position,所以通过添加:

来居中
position: absolute

(这里有关于为什么适用于中心的信息:https://css-tricks.com/quick-css-trick-how-to-center-an-object-exactly-in-the-center/

所以现在摇晃#projection position: relative .pro left: 50% margin-left: $width * -.5 进行仔细检查,我从$width进行了测试,直到20%,并且运行正常。

答案 1 :(得分:2)

我稍微改变了风格,使事情更加明显。

结果对我来说似乎没问题。可能是我误会了什么?

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>

答案 2 :(得分:0)

使用set perspective在父容器内使用translateZ计算子元素的宽度/高度的公式是:
$ scale = 1 + (translateZ * -1) / perspective

将此公式放在transform: scale( $scale )perspective是父母的观点值,translateZ也是元素translateZ值。根据需要,请参阅底部的代码段SASS mockup

所以实际上答案是在问题中给出的!
虽然这是问题的正确答案,但这根本不能解决我的具体问题 here is a follow-up-question

致谢:@Trolleymusic至少以his answer的方式打开了我的眼睛。

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 );
}