效果篇-实现3D骰子-《前端知识进阶》

admin 2025-11-01 15:18:02 编程 来源:ZONE.CI 全球网 0 阅读模式
  • 1. 使用 Flex 布局实现六个面
    • (1)一个点
    • (2)两个点
    • (3)三个点
    • (4)四个点
    • (5)五个点
    • (6)六个点
  • 2. 使用 Grid 布局实现六个面
  • 3. 实现 3D 骰子

    在CSS 中创建 3D 骰子,通过本文可以学到以下知识;

    • 使用 CSS 中的 transform 来定义3D形状;
    • 使用 CSS 中的 Flex 布局来实现骰子布局;
    • 使用 CSS 中的 Grid 布局来实现骰子布局。

      1. 使用 Flex 布局实现六个面

      首先,来定义骰子六个面的 HTML 结构: ```html
    1. 下面来实现**每个面**和**每个点**的的基本样式:
    2. ```css
    3. .dice {
    4. width: 200px;
    5. height: 200px;
    6. padding: 20px;
    7. background-color: tomato;
    8. border-radius: 10%;
    9. }
    10. .dot {
    11. display: inline-block;
    12. width: 50px;
    13. height: 50px;
    14. border-radius: 50%;
    15. background-color: white;
    16. }

    实现效果如下:、image.png

    (1)一个点

    HTML 结构如下:

    1. <div class="dice first-face">
    2. <span class="dot"></span>
    3. </div>

    实现第一个面,只需要让它水平和垂直方向都居中即可:

    • justify-content:center:使点与主轴(水平)的中心对齐。
    • align-items:center:使点与交叉轴(垂直)的中心对齐。

    代码实现如下:

    1. .first-face {
    2. display: flex;
    3. justify-content: center;
    4. align-items: center;
    5. }

    现在第一面是这样的:image.png

    (2)两个点

    HTML 结构如下:

    1. <div class="dice second-face">
    2. <span class="dot"></span>
    3. <span class="dot"></span>
    4. </div>

    首先来将第二个面的父元素设置为flex布局,并添加以下属性:

    • justify-content: space-between:将子元素放置在 flex 容器的开头和结尾。

      1. .second-face {
      2. display: flex;
      3. justify-content : space-between;
      4. }

      现在点的位置如下:image.png这时,第一个点在正确的位置:左上角。而第二个点需要再右下角。因此,下面来使用 align-self 属性单独调整第二个点的位置:

    • align-self: flex-end:将项目对齐到 Flex 容器的末尾。

      1. .second-face .dot:nth-of-type(2) {
      2. align-self: flex-end;
      3. }

      现在第二面是这样的:image.png

      (3)三个点

      HTML 结构如下:

      1. <div class="dice third-face">
      2. <span class="dot"></span>
      3. <span class="dot"></span>
      4. <span class="dot"></span>
      5. </div>

      可以通过在第二面放置另一个中心点来实现第三面。

    • align-self: flex-end:将项目对齐到 Flex 容器的末尾。

    • align-self: center:将项目对齐到 Flex 容器的中间。 ```css .third-face { display: flex; justify-content : space-between; }

    .third-face .dot:nth-of-type(2) { align-self: center; }

    .third-face .dot:nth-of-type(3) { align-self: flex-end; }

    1. 现在第三面是这样的:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/1500604/1659278950956-8a6edfd8-bfb1-404e-903d-5133994b1f72.png#clientId=u874b64c7-19b7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=258&id=ud40d757f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=516&originWidth=514&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17605&status=done&style=none&taskId=udd7a425a-14b7-4af2-8ec0-7830400e74a&title=&width=257)<br />如果想要第一个点在右上角,第三个点在左下角,可以将第一个点的 align-self 更改为 flex-end,第二个点不变,第三个点无需设置,默认在最左侧:
    2. ```css
    3. .third-face {
    4. display: flex;
    5. justify-content : space-between;
    6. }
    7. .third-face .dot:nth-of-type(1) {
    8. align-self :flex-end;
    9. }
    10. .third-face .dot:nth-of-type(2) {
    11. align-self :center;
    12. }

    现在第三面是这样的:image.png

    (4)四个点

    HTML 结构如下:

    1. <div class="dice fourth-face">
    2. <div class="column">
    3. <span class="dot"></span>
    4. <span class="dot"></span>
    5. </div>
    6. <div class="column">
    7. <span class="dot"></span>
    8. <span class="dot"></span>
    9. </div>
    10. </div>

    在四个点的面中,可以将其分为两行,每行包含两列。一行将在 flex-start ,另一行将在 flex-end 。并添加 justify-content: space-between 以便将其放置在骰子的左侧和右侧。

    1. .fourth-face {
    2. display: flex;
    3. justify-content: space-between
    4. }

    接下来需要对两列点分别进行布局:

    • 将列设置为 flex 布局;
    • flex-direction 设置为 column,以便将点放置在垂直方向上
    • justify-content 设置为 space-between,它将使第一个点在顶部,第二个点在底部。
      1. .fourth-face .column {
      2. display: flex;
      3. flex-direction: column;
      4. justify-content: space-between;
      5. }
      现在第四面是这样的:image.png

      (5)五个点

      HTML 结构如下:
      1. <div class="fifth-face dice">
      2. <div class="column">
      3. <span class="dot"></span>
      4. <span class="dot"></span>
      5. </div>
      6. <div class="column">
      7. <span class="dot"></span>
      8. </div>
      9. <div class="column">
      10. <span class="dot"></span>
      11. <span class="dot"></span>
      12. </div>
      13. </div>
      第五面和第四面的差异在于多了中间的那个点。所以,可以基于第四面,来在中间增加一列,样式如下: ```css .fifth-face { display: flex; justify-content: space-between }

    .fifth-face .column { display: flex; flex-direction: column; justify-content: space-between; }

    1. 现在第五面是这样的:<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/1500604/1659280111595-18e0d316-e8e9-4f6c-85ac-921d97cd0f7a.png#clientId=u874b64c7-19b7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=265&id=ue679fe59&margin=%5Bobject%20Object%5D&name=image.png&originHeight=530&originWidth=508&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17637&status=done&style=none&taskId=u76e543ac-bf04-46df-b5c8-1dac8199efd&title=&width=254)<br />还需要对中间的点进行调整,可以设置 justify-content 为 center 让它垂直居中:
    2. ```css
    3. .fifth-face .column:nth-of-type(2) {
    4. justify-content: center;
    5. }

    现在第五面是这样的:image.png

    (6)六个点

    HTML 结构如下:

    1. <div class="dice sixth-face">
    2. <div class="column">
    3. <span class="dot"></span>
    4. <span class="dot"></span>
    5. <span class="dot"></span>
    6. </div>
    7. <div class="column">
    8. <span class="dot"></span>
    9. <span class="dot"></span>
    10. <span class="dot"></span>
    11. </div>
    12. </div>

    第六个面的布局和第四个几乎完全一样,只不过每一列多了一个元素,布局实现如下:

    1. .sixth-face {
    2. display: flex;
    3. justify-content: space-between
    4. }
    5. .sixth-face .column {
    6. display: flex;
    7. flex-direction: column;
    8. justify-content: space-between;
    9. }

    现在第六面是这样的:image.png

    2. 使用 Grid 布局实现六个面

    骰子每个面其实可以想象成一个 3 x 3 的网格,其中每个单元格代表一个点的位置:

    1. +---+---+---+
    2. | a | b | c |
    3. +---+---+---+
    4. | d | e | f |
    5. +---+---+---+
    6. | g | h | i |
    7. +---+---+---+

    要创建一个 3 x 3 的网格,只需要设置一个容器元素,并且设置三个大小相同的行和列:

    1. .dice {
    2. display: grid;
    3. grid-template-rows: 1fr 1fr 1fr;
    4. grid-template-columns: 1fr 1fr 1fr;
    5. }

    这里的 fr 单位允许将行或列的大小设置为网格容器可用空间的一部分,这上面的例子中,我们需要三分之一的可用空间,所以设置了 1fr 三次。

    我们还可以使用 repeat(3, 1fr) 将 1fr 重复 3 次,来代替 1fr 1fr 1fr。还可以使用定义行/列的 grid-template 速记属性将上述代码进行简化:

    1. .dice {
    2. display: grid;
    3. grid-template: repeat(3, 1fr) / repeat(3, 1fr);
    4. }

    每个面所需要定义的 HTML 就像是这样:

    1. <div class="dice">
    2. <span class="dot"></span>
    3. <span class="dot"></span>
    4. <span class="dot"></span>
    5. <span class="dot"></span>
    6. </div>

    所有的点将自动放置在每个单元格中,从左到右:image.png现在我们需要为每个骰子值定位点数。开始时我们提到,可以将每个面分成 3 x 3 的表格,但是这些表格并不是每一个都是我们需要的,分析骰子的六个面,可以发现,我们只需要以下七个位置的点:

    1. +---+---+---+
    2. | a | | c |
    3. +---+---+---+
    4. | e | g | f |
    5. +---+---+---+
    6. | d | | b |
    7. +---+---+---+

    我们可以使用 grid-template-areas 属性将此布局转换为 CSS:

    1. .dice {
    2. display: grid;
    3. grid-template-areas:
    4. "a . c"
    5. "e g f"
    6. "d . b";
    7. }

    因此,我们可以不使用传统的单位来调整行和列的大小,而只需使用名称来引用每个单元格。其语法本身提供了网格结构的可视化,名称由网格项的网格区域属性定义。 中间列中的句点表示一个空单元格。

    下面来使用 grid-area 属性为网格项命名,然后,网格模板可以通过其名称引用该项目,以将其放置在网格中的特定区域中。 :nth-child() 伪选择器允许单独定位每个点。

    1. .dot:nth-child(2) {
    2. grid-area: b;
    3. }
    4. .dot:nth-child(3) {
    5. grid-area: c;
    6. }
    7. .dot:nth-child(4) {
    8. grid-area: d;
    9. }
    10. .dot:nth-child(5) {
    11. grid-area: e;
    12. }
    13. .dot:nth-child(6) {
    14. grid-area: f;
    15. }

    现在六个面的样式如下:image.png可以看到,1、3、5的布局仍然是不正确的,只需要重新定位每个骰子的最后一个点即可:

    1. .dot:nth-child(odd):last-child {
    2. grid-area: g;
    3. }

    这时所有点的位置都正确了:image.png对于上面的 CSS,对应的 HTML分别是父级为一个div标签,该面有几个点,子级就有几个span标签。代码如下:

    1. <div class="dice-box">
    2. <div class="dice first-face">
    3. <span class="dot"></span>
    4. </div>
    5. <div class="dice second-face">
    6. <span class="dot"></span>
    7. <span class="dot"></span>
    8. </div>
    9. <div class="dice third-face">
    10. <span class="dot"></span>
    11. <span class="dot"></span>
    12. <span class="dot"></span>
    13. </div>
    14. <div class="dice fourth-face">
    15. <span class="dot"></span>
    16. <span class="dot"></span>
    17. <span class="dot"></span>
    18. <span class="dot"></span>
    19. </div>
    20. <div class="fifth-face dice">
    21. <span class="dot"></span>
    22. <span class="dot"></span>
    23. <span class="dot"></span>
    24. <span class="dot"></span>
    25. <span class="dot"></span>
    26. </div>
    27. <div class="dice sixth-face">
    28. <span class="dot"></span>
    29. <span class="dot"></span>
    30. <span class="dot"></span>
    31. <span class="dot"></span>
    32. <span class="dot"></span>
    33. <span class="dot"></span>
    34. </div>
    35. </div>

    整体的 CSS 代码如下:

    1. .dice {
    2. width: 200px;
    3. height: 200px;
    4. padding: 20px;
    5. background-color: tomato;
    6. border-radius: 10%;
    7. display: grid;
    8. grid-template: repeat(3, 1fr) / repeat(3, 1fr);
    9. grid-template-areas:
    10. "a . c"
    11. "e g f"
    12. "d . b";
    13. }
    14. .dot {
    15. display: inline-block;
    16. width: 50px;
    17. height: 50px;
    18. border-radius: 50%;
    19. background-color: white;
    20. }
    21. .dot:nth-child(2) {
    22. grid-area: b;
    23. }
    24. .dot:nth-child(3) {
    25. grid-area: c;
    26. }
    27. .dot:nth-child(4) {
    28. grid-area: d;
    29. }
    30. .dot:nth-child(5) {
    31. grid-area: e;
    32. }
    33. .dot:nth-child(6) {
    34. grid-area: f;
    35. }
    36. .dot:nth-child(odd):last-child {
    37. grid-area: g;
    38. }

    3. 实现 3D 骰子

    上面我们分别使用 Flex 和 Grid 布局实现了骰子的六个面,下面来这将六个面组合成一个正方体。

    首先对六个面进行一些样式修改:

    1. .dice {
    2. width: 200px;
    3. height: 200px;
    4. padding: 20px;
    5. box-sizing: border-box;
    6. opacity: 0.7;
    7. background-color: tomato;
    8. position: absolute;
    9. }

    定义它们的父元素:

    1. .dice-box {
    2. width: 200px;
    3. height: 200px;
    4. position: relative;
    5. transform-style: preserve-3d;
    6. transform: rotateY(185deg) rotateX(150deg) rotateZ(315deg);
    7. }

    其中,transform-style: preserve-3d; 表示所有子元素在3D空间中呈现。这里的transform 的角度不重要,主要是便于后面查看。

    此时六个面的这样的:image.png看起来有点奇怪,所有面都叠加在一起。不要急,我们来一个个调整位置。

    首先将第一个面在 Z 轴移动 100px:

    1. .first-face {
    2. transform: translateZ(100px);
    3. }

    第一面就到了所有面的上方:image.png因为每个面的宽高都是 200px,所以将第六面沿 Z 轴向下调整 100px:

    1. .sixth-face {
    2. transform: translateZ(-100px);
    3. }

    第六面就到了所有面的下方:image.png下面来调整第二面,将其在X轴向后移动 100px,并沿着 Y 轴旋转 -90 度:

    1. .second-face {
    2. transform: translateX(-100px) rotateY(-90deg);
    3. }

    此时六个面是这样的:image.png下面来调整第二面的对面:第五面,将其沿 X 轴的正方向移动 100px,并沿着 Y 轴方向选择 90 度:

    1. .fifth-face {
    2. transform: translateX(100px) rotateY(90deg);
    3. }

    此时六个面是这样的:image.png下面来调整第三面,道理同上:

    1. .third-face {
    2. transform: translateY(100px) rotateX(90deg);
    3. }

    此时六个面是这样的:image.png最后来调整第五面:

    1. .fourth-face {
    2. transform: translateY(-100px) rotateX(90deg);
    3. }

    此时六个面就组成了一个完整的正方体:image.png下面来为这个骰子设置一个动画,让它转起来:

    1. @keyframes rotate {
    2. from {
    3. transform: rotateY(0) rotateX(45deg) rotateZ(45deg);
    4. }
    5. to {
    6. transform: rotateY(360deg) rotateX(45deg) rotateZ(45deg);
    7. }
    8. }
    9. .dice-box {
    10. animation: rotate 5s linear infinite;
    11. }

    最终的效果如下: Kapture 2022-08-01 at 00.11.45.gif在线体验-3D 骰子-Flex:点击查看【codepen】在线体验-3D 骰子-Grid:点击查看【codepen】

    以太坊cppgolang区别 编程

    以太坊cppgolang区别

    以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
    progolang 编程

    progolang

    Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
    golangn个发送者 编程

    golangn个发送者

    Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
    golang技能图谱 编程

    golang技能图谱

    从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
    评论:0   参与:  8