【perspective】如何利用景深绘制一个宽高内角可控的梯形

895 阅读2分钟

一、什么是景深?

CSS 属性 perspective指定了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果。 z>0 的三维元素比正常大,而 z<0 时则比正常小,大小程度由该属性的值决定。

二、绘制梯形

其实绘制梯形的方法有很多,比如border、skew、svg、canvas...,可惜,我们的设计师要的是一个有圆角边框和高斯模糊背景效果的梯形,so,这就不得不利用景深的透视效果来实现了。

具体效果如下图:

image.png

要画出这个:底边400px,高80px,底边内角65°的梯形,除了perspective还会配合使用rotateX。因为我们看到的所谓梯形,实际上是一个矩形经过3d变换后映射到屏幕(z=0 平面)上的投影,而这个投影的具体形状与景深有关。

首先需要创建一个div(矩形),并添加样式
注意:为方便计算,将div的变换的中心点设置为bottom,x轴旋转值为

<div class="rectangle"></div>

.rectangle {
    transform: `perspective(${x}px) rotateX(5deg)`;
    height: `${y}px`;
    transform-origin: bottom;
    border: 2px solid #d7e0e7;
    border-radius: 32px 32px 5px 5px;
    backdrop-filter: blur(3px);
}

由上可知:
我们目前已知条件有四:

  1. 梯形底边宽度:w = 400
  2. 梯形高度(div的投影高度):h = 80
  3. 梯形底边内角值:Q = 65
  4. 矩形与屏幕(z=0 平面)的夹角为:V = 5

未知条件有二:

  1. 观察者与屏幕(z=0 平面)的距离:x
  2. 矩形高(div的实际高度):y

so,只要根据已知条件w、h、Q、V推断出未知条件x、y的值,我们的梯形就大功告成啦。

对于这些数字,只看文字说明可能有些抽象,看图可以帮助理解,请看下图:

微信图片_20220415100934.jpg

上图标记了红蓝两对相似三角形,由此可以得出两组等比关系:

  • a / b = h / c
  • a / b = x / (x + d)

图中标记了直角∟,由此可以得出两组三角函数关系:

  • c / y = cos(v)
  • d / y = sin(v)

所以

  • c = cos(v) * y
  • d = sin(v) * y

又因为

  • b = w / 2
  • h / (b - a) = tan(Q)

所以解以上方程式可得

  • y=(tan(Q) * (w / 2) * h) / ((tan(Q) * (w / 2) - h) * cos(v))
  • x=(sin(v) * y * h) / (cos(v) * y - h)

大功告成,完整代码如下:

<div class="rectangle"></div>

let Q = 65,
    w = 400,
    h = 80,
    v = 5,
    y =
      (Math.tan((Math.PI * Q) / 180) * (w / 2) * h) /
      ((Math.tan((Math.PI * Q) / 180) * (w / 2) - h) * Math.cos((Math.PI * v) / 180)),
    x = (y * h * Math.sin((Math.PI * v) / 180)) / (y * Math.cos((Math.PI * v) / 180) - h)
    
.rectangle {
    transform: `perspective(${x}px) rotateX(5deg)`;
    height: `${y}px`;
    transform-origin: bottom;
    border: 2px solid #d7e0e7;
    border-radius: 32px 32px 5px 5px;
    backdrop-filter: blur(3px);
}