CSS 3D
布局
代码
细节
结论
AWS 安全上线!
感谢@rolandcsibrei的想法,我更新了这篇文章。
作为一名前端开发人员,我经常使用 CSS。
有时,我会为了好玩而尝试 CSS。
最近我发现了一篇关于CSS 中的3D 变换的文章,它给了我新实验的想法。
简而言之,我已经完成了构建交互式3D 对象的想法。
渲染过程背后的想法很简单。
布局
飞机
有一个对象(我称之为平面)定义了对象的高度和宽度。默认情况下,该平面是不可见的。
<div class="plane"></div>
.plane {
transform-style: preserve-3d;
animation: rotate 6s linear infinite;
}
@keyframes rotate {
from {
transform: rotate3d(1, 1, 1, 0deg);
}
to {
transform: rotate3d(1, 1, 1, 360deg);
}
}
唯一旋转的物体是平面,其他所有部分都只是跟随平面旋转。
脸
接下来,我创建其他对象(我将它们称为“面”)。每个面都放置在相应的位置,并具有相应的角度。
<div class="plane">
<div class="face"></div>
<div class="face"></div>
<div class="face"></div>
<div class="face"></div>
<div class="face"></div>
<div class="face"></div>
</div>
.face {
background: #ffffff11;
border: 1px solid #ffffff22;
box-shadow: inset 0 0 8px 8px #ffffff22;
position: absolute;
overflow: hidden;
}
代码
物体被封闭在由三个属性描述的空间中:宽度、高度和深度。
在所描述的空间内,我可以放置 1 到 N 个部分(我将它们称为“条”)。每个条由六个面组成。条沿着平面从上到下排列。
每个面都必须正确配置才能形成一个物体。
配置包括宽度、高度、旋转和平移等设置。
常量
我已经将面的顺序以及它们的数量定义为常量,以便稍后使用它们:
const faceFront = 0;
const faceBack = 1;
const faceRight = 2;
const faceLeft = 3;
const faceTop = 4;
const faceBottom = 5;
const faces = 6;
计算脸部尺寸
为了正确计算脸部的尺寸,我使用了这个简单的辅助函数。
/**
* @param {number} order
* @param {number} faceSteps
* @param {number} width
* @param {number} height
* @param {number} depth
* @return {[number, number]}
*/
function calcSize(order, faceSteps, width, height, depth) {
switch (order) {
case faceFront:
case faceBack:
return [width, height / faceSteps];
case faceRight:
case faceLeft:
return [depth * 2, height / faceSteps];
case faceTop:
case faceBottom:
return [width, depth * 2];
}
}
该函数根据面顺序和对象的设置,以数字数组的形式返回宽度和高度。
计算变换
该函数根据给定的参数生成转换规则。
/**
* @param {number} order
* @param {number} nHeight
* @param {number} nSizeY
* @param {number} planeDepth
* @param {number} planeWidth
* @param {number} sizeX
* @param {number} faceHeight
* @return {string}
*/
function transform(
order,
nHeight,
nSizeY,
planeDepth,
planeWidth,
sizeX,
faceHeight
) {
switch (order) {
case faceFront:
return `translate3d(0, ${nHeight}px, ${planeDepth}px)`;
case faceBack:
return `rotateY(180deg) translate3d(0, ${nHeight}px, ${planeDepth}px)`;
case faceRight:
return `rotateY(90deg) translate3d(0, ${nHeight}px, ${sizeX / -2}px)`;
case faceLeft:
return `rotateY(-90deg) translate3d(0, ${nHeight}px, ${sizeX / 2 -
planeWidth}px)`;
case faceTop:
return `rotateX(90deg) translate3d(0, 0, ${nSizeY - nHeight}px)`;
case faceBottom:
return `rotateX(-90deg) translate3d(0, 0, ${nHeight +
faceHeight -
nSizeY}px)`;
}
}
这些规则用于将面部放置到各自的位置并将它们旋转到所需的角度。
配置面部
配置功能将把计算出的尺寸以及变换应用于平面。
/**
* @param {HTMLDivElement} face
* @param {number} faceNumber
* @param {number} faceHeight
* @param {number} faceStep
* @param {number} planeWidth
* @param {number} planeHeight
* @param {number} planeDepth
*/
function configure(
face,
faceNumber,
faceHeight,
faceStep,
planeWidth,
planeHeight,
planeDepth
) {
const order = faceNumber % faces;
const nHeight = ((faceNumber - order) / 3) * faceHeight;
const [sizeX, sizeY] = calcSize(
order,
faceStep,
planeWidth,
planeHeight,
planeDepth
);
const nSizeY = sizeY / 2;
face.className = "face";
face.style.width = `${sizeX}px`;
face.style.height = `${sizeY}px`;
face.style.transform = transform(
order,
nHeight,
nSizeY,
planeDepth,
planeWidth,
sizeX,
faceHeight
);
}
稍后,配置的面将被附加到相应的平面以创建一个条。
构建对象
让我们将其包装在构建函数中。
/**
* @param {HTMLDivElement} container
* @param {number} bars
* @param {number} width
* @param {number} height
* @param {number} depth
*/
function build(container, bars, width, height, depth) {
if (!container) {
return;
}
container.style.width = `${width}px`;
container.style.height = `${height}px`;
const planeWidth = width / 2;
const planeHeight = height / 2;
const planeDepth = depth / 2;
const faceStep = bars * 2 - 1;
const faceHeight = planeHeight / faceStep;
const plane = document.createElement("div");
plane.className = "plane";
plane.style.width = `${planeWidth}px`;
plane.style.height = `${planeHeight}px`;
for (var i = 0; i < bars * faces; i++) {
const face = document.createElement("div");
configure(
face,
i,
faceHeight,
faceStep,
planeWidth,
planeHeight,
planeDepth
);
plane.appendChild(face);
}
container.appendChild(plane);
}
构建函数接受对象的初始设置:父容器、条数、对象的宽度、高度和深度。
该函数创建平面,然后构建面并将其附加到平面。
所有面都构建完成后,平面将附加到提供的容器中。
工作演示的源代码可在此处获得霓虹灯 3D 条演示(已更新)。
添加视角(更新)
按照我的例子,3D 对象被放入容器中。
为了添加透视图,我将相应的 CSS 规则应用到容器,如下所示:
container.style.perspective = "500px";
稍后,平面将被附加到该容器中,透视效果将使物体的外观更加美观!
const root = document.getElementById("root");
const container = document.createElement("div");
container.className = "container";
container.style.perspective = "500px";
build(container, 3, 500, 500, 250);
root.appendChild(container);
值得一提的是,在原始示例中,透视 CSS 规则应用于平面,但经过几次实验后,我决定将其应用于容器。
因此,不要害怕尝试并在其他地方应用此规则,甚至在多个地方!
细节
如果由于某种原因,您的浏览器不支持尚未实验的 CSS 功能transform-style,则不会出现 3D 效果,但投影仍然可见。
静态部分位于 CSS 定义中。动态部分在每次参数更新时计算。
结论
通过此新功能,可以使用简单的 3D 对象来丰富网页。
我有一些关于如何应用它的想法!
它可以作为您的 Web 应用程序的预加载器。
可以将一些数据可视化。
此外,还可以实现一些花哨的 3D 旋转器/服务员/加载指示器!
鏂囩珷鏉ユ簮锛�https://dev.to/peacefullatom/css-3d-43gg