使用 Flex 和 Grid 布局实现 3D 骰子!

网站建设3年前发布
42 0 0

大家好,我是 CUGGZ。,在前端面试中,经常会问到如何使用 CSS 实现骰子/麻将布局。今天我们就来用 CSS 创建一个 3D 骰子,通过本文可以学到;,使用transform 来实现3D形状;,给 3D 骰子实现旋转动画;,使用 Flex 布局来实现骰子布局;,使用 Grid 布局来实现骰子布局。,首先,来定义骰子六个面的 HTML 结构:,下面来实现每个面和每个点的的基本样式:,实现效果如下:,20230305211315529eaa16962f179edc5085c8805bff5973a122917,HTML 结构如下:,实现第一个面,只需要让它水平和垂直方向都居中即可:,代码实现如下:,现在第一面是这样的:,20230305211317a2c62f3810bb026b88082011ca404ccdff148f468,HTML 结构如下:,首先来将第二个面的父元素设置为flex布局,并添加以下属性:,现在点的位置如下:,20230305220603e196a2661b3266accc9658a03ee64bce346d26488,这时,第一个点在正确的位置:左上角。而第二个点需要在右下角。因此,下面来使用 align-self 属性单独调整第二个点的位置:,现在第二面是这样的:,202303052202361675857661a00aa54d9945a7825724e7e246ce697,HTML 结构如下:,可以通过在第二面放置另一个中心点来实现第三面。,现在第三面是这样的:,20230305220237f56eea18692d0a1614a888ed573f0bdd296f66258,如果想要第一个点在右上角,第三个点在左下角,可以将第一个点的 align-self 更改为 flex-end,第二个点不变,第三个点无需设置,默认在最左侧:,现在第三面是这样的:,2023030522023804d8f67714557f2c2d3297ac75367ae8a0f426723,HTML 结构如下:,在四个点的面中,可以将其分为两行,每行包含两列。一行将在 flex-start ,另一行将在 flex-end 。并添加 justify-content: space-between 以便将其放置在骰子的左侧和右侧。,接下来需要对两列点分别进行布局:,现在第四面是这样的:,20230305211343f64aa4517b961a254026203032635559fd43f3377,HTML 结构如下:,第五面和第四面的差异在于多了中间的那个点。所以,可以基于第四面,来在中间增加一列,样式如下:,现在第五面是这样的:,2023030521134493e1c9878cfafaf660a416b130512a6611b59c117,还需要对中间的点进行调整,可以设置 justify-content 为 center 让它垂直居中:,现在第五面是这样的:,2023030522060575d1b5a48671c5a4a4108837daac56e911dad0966,HTML 结构如下:,第六个面的布局和第四个几乎完全一样,只不过每一列多了一个元素,布局实现如下:,现在第六面是这样的:,20230305211327022632964f70cd4ba299384e5d38fe0f73d8ca687,骰子每个面其实可以想象成一个 3 x 3 的网格,其中每个单元格代表一个点的位置:,要创建一个 3 x 3 的网格,只需要设置一个容器元素,并且设置三个大小相同的行和列:,这里的 fr 单位允许将行或列的大小设置为网格容器可用空间的一部分,这上面的例子中,我们需要三分之一的可用空间,所以设置了 1fr 三次。,我们还可以使用 repeat(3, 1fr) 将 1fr 重复 3 次,来代替 1fr 1fr 1fr。还可以使用定义行/列的 grid-template 速记属性将上述代码进行简化:,每个面所需要定义的 HTML 就像是这样:,所有的点将自动放置在每个单元格中,从左到右:,20230305211327485ad4b358341be56a56491bd36a0d54fc9cd8156,现在我们需要为每个骰子值定位点数。开始时我们提到,可以将每个面分成 3 x 3 的表格,但是这些表格并不是每一个都是我们需要的,分析骰子的六个面,可以发现,我们只需要以下七个位置的点:,我们可以使用 grid-template-areas 属性将此布局转换为 CSS:,因此,我们可以不使用传统的单位来调整行和列的大小,而只需使用名称来引用每个单元格。其语法本身提供了网格结构的可视化,名称由网格项的网格区域属性定义。中间列中的点表示一个空单元格。,下面来使用 grid-area 属性为网格项命名,然后,网格模板可以通过其名称引用该项目,以将其放置在网格中的特定区域中。:nth-child() 伪选择器允许单独定位每个点。,现在六个面的样式如下:,2023030521134409486f199560ee39541306393a4d7ca85bf7f3789,可以看到,1、3、5的布局仍然是不正确的,只需要重新定位每个骰子的最后一个点即可:,这时所有点的位置都正确了:,20230305211330f8b9e1e03622bc57439498865ac224cc668f4d981,对于上面的 CSS,对应的 HTML分别是父级为一个div标签,该面有几个点,子级就有几个span标签。代码如下:,整体的 CSS 代码如下:,上面我们分别使用 Flex 和 Grid 布局实现了骰子的六个面,下面来这将六个面组合成一个正方体。,首先对六个面进行一些样式修改:,定义它们的父元素:,其中,transform-style: preserve-3d; 表示所有子元素在3D空间中呈现。这里的transform 的角度不重要,主要是便于后面查看。,此时六个面的这样的:,2023030521133195eea89473864511a3d3876ed645b5ecbccabe798,看起来有点奇怪,所有面都叠加在一起。不要急,我们来一个个调整位置。,首先将第一个面在 Z 轴移动 100px:,第一面就到了所有面的上方:,2023030521134503080232201e94a0e46417e03461521d155bf0992,因为每个面的宽高都是 200px,所以将第六面沿 Z 轴向下调整 100px:,第六面就到了所有面的下方:,20230305211346f1d7a2a40d644a7b39e1432bbd91d2d5e0a0c2741,下面来调整第二面,将其在X轴向后移动 100px,并沿着 Y 轴旋转 -90 度:,此时六个面是这样的:,2023030521133533a445c8835829a7f80347ce402429d92a8487663,下面来调整第二面的对面:第五面,将其沿 X 轴的正方向移动 100px,并沿着 Y 轴方向选择 90 度:,此时六个面是这样的:,20230305211336712cff8408226c9188f859b2f70ac3932633cf273,下面来调整第三面,道理同上:,此时六个面是这样的:,20230305211337376964c46b2b27618423748affbe74a529bfcf434,最后来调整第五面:,此时六个面就组成了一个完整的正方体:,2023030521134813ab9a18603d84ee945654ee688df00537cb3c111,下面来为这个骰子设置一个动画,让它转起来:,最终的效果如下:,20230305211338416372a65dad6c717902358a9c0984aad4e97e139,3D 骰子-Flex:https://codepen.io/cugergz/pen/jOzYGyV,3D 骰子-Grid:https://codepen.io/cugergz/pen/GROMgEe

© 版权声明

相关文章