使用透视渲染HTML元素?

9

目标是以透视方式呈现HTML元素,如下面的示例所示。

我们尝试使用CSS skew变换,但这些变换看起来不正确,因为它们扭曲了元素的长宽比或者创建了其他的扭曲效果。

以下是我们尝试过的CSS扭曲变换。这些都不像下面的示例那样好看。

Codepen: https://codepen.io/anon/pen/MMzdPx

transform: skew(20deg, -15deg);

transform: skew(45deg, -25deg);

transform: skew(45deg, -30deg);

你如何实现这种HTML元素的透视渲染?

enter image description here enter image description here enter image description here enter image description here


1
只使用3D变换吗? - James Coyle
你尝试过在CSS中使用perspective属性吗?https://jsfiddle.net/joshnh/dxGTL/ - Allan Jebaraj
2
https://stackoverflow.com/q/48777549/8620333 - Temani Afif
@AllanJebaraj 可能值得注意的是,perspective 在 IE 中只有部分兼容。 - metaDesign
3个回答

12

就像你说的那样,使用透视和一些旋转。

img {
  width:150px;
  margin:20px;
}
img.first {
  transform:perspective(500px) rotateY(20deg);
}
img.last {
  transform:perspective(500px) rotateY(-20deg);
}
<img src="https://i.imgur.com/DGAOsPz.png" class="first">
<img src="https://i.imgur.com/DGAOsPz.png" class="last">

img {
  width:150px;
  margin:30px;
  transform:perspective(500px)  rotateY(15deg) rotateX(50deg) rotateZ(-20deg);
}
<img src="https://i.imgur.com/DGAOsPz.png" >

更多详细信息请参考相关问题:

如果在属性结尾设置视角,CSS 3D转换无法正常工作


我不确定提问者想要透视投影还是平行投影。上面的代码示例使用透视投影,但如果您想要平行投影,只需将 perspective(500px) 更改为 perspective(0) 即可。 - Rory O'Kane

3

像这样的东西。 我使用CSS自定义属性,使计算更加明显。

请注意: 变换属性的顺序非常重要。它从右到左进行评估:

来自MDN transform CSS

变换函数按从左到右的顺序相乘,这意味着复合变换实际上是从右到左按顺序应用的。

这意味着,transform: rotateX(90deg) translateX(100px)transform: translateX(100px) rotateX(90deg)不同。前者先进行平移然后旋转,而后者在平移之前进行旋转。

.box {
  width: 130px;
  height: 268px;
  background-size: cover;
}
.box:nth-child(4n+1) {
  background: url(https://picsum.photos/id/100/136/276);
}
.box:nth-child(4n+2) {
  background: url(https://picsum.photos/id/200/136/276);
}
.box:nth-child(4n+3) {
  background: url(https://picsum.photos/id/300/136/276);
}
.box:nth-child(4n+4) {
  background: url(https://picsum.photos/id/400/136/276);
}

.container {
  transform: perspective(1200px) rotateX(60deg) rotateZ(-35deg) translate3d(-100px, -200px, -500px);
}

.skew {
  position: absolute;
  top: 200px;
  left: 50%;
  --width: 140px;
  --height: 278px;
  --x: 0;
  --y: 0;
  --offsetX: calc(var(--x) * var(--width));
  --offsetY: calc(var(--y) * var(--height));
  transform: translate(var(--offsetX), var(--offsetY));
}
.skew:nth-child(5n + 1) {
  --x: -2;
}
.skew:nth-child(5n + 2) {
  --x: -1;
}
.skew:nth-child(5n + 3) {
  --x: 0;
}
.skew:nth-child(5n + 4) {
  --x: 1;
}
.skew:nth-child(5n + 5) {
  --x: 2;
}
.skew:nth-child(n + 1):nth-child(-n + 5) {
  --y: -2;
}
.skew:nth-child(n + 6):nth-child(-n + 10) {
  --y: -1;
}
.skew:nth-child(n + 11):nth-child(-n + 15) {
  --y: 0;
}
.skew:nth-child(n + 16):nth-child(-n + 20) {
  --y: 1;
}
.skew:nth-child(n + 21):nth-child(-n + 25) {
  --y: 2;
}
<div class="container">
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
  <div class="skew box"></div>
</div>


0

你必须构建元素,可以这么说。以下是来自你的 CodePen 的代码:

<div class="perspective">
<div class="skew">
<div class="front"></div>
<div class="back"></div>
<div class="left"></div>
<div class="right"></div>
</div>
</div>

修改了 CSS:

.perspective {
position: relative;
-webkit-perspective: 1242px; /* Safari 4-8 */
perspective: 1242px;
height: 2688px;
}

.front {
width: 1242px;
height: 2688px;
max-width: 100%;
max-height: 100%;
position: absolute;
transform: rotateX(45deg) rotateY(-60deg) translateZ(-80em);
background: url(https://i.imgur.com/DGAOsPz.png);
}

.skew {
transform-style: preserve-3d;
transform: rotateX(10deg) rotateY(80deg);
height: 2560px;
width: 100%;
}

仍需要在CSS中添加侧边和背景,但您可以将此粘贴到您的CodePen中并查看其工作方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接