加入收藏 | 设为首页 | 会员中心 | 我要投稿 聊城站长网 (https://www.0635zz.com/)- 智能语音交互、行业智能、AI应用、云计算、5G!
当前位置: 首页 > 综合聚焦 > 编程要点 > 语言 > 正文

用CSS实现骰子效果的方法与代码是什么

发布时间:2023-06-24 15:28:41 所属栏目:语言 来源:
导读:这篇文章主要讲解了“用CSS实现骰子效果的方法和代码是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“用CSS实现骰子效果的方法和代码是什么
这篇文章主要讲解了“用CSS实现骰子效果的方法和代码是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“用CSS实现骰子效果的方法和代码是什么”吧!
 
在前端面试中,经常会问到如何使用 CSS实现骰子/麻将布局。今天我们就来用CSS 创建一个 3D 骰子,通过本文可以学到;
 
使用transform来实现3D形状;
 
给 3D 骰子实现旋转动画;
 
使用 Flex 布局来实现骰子布局;
 
使用 Grid 布局来实现骰子布局。
 
1. 使用 Flex 布局实现六个面
 
首先,来定义骰子六个面的 HTML 结构:
 
<div class="dice-box">
 
  <div class="dice first-face">
 
    <span class="dot"></span>
 
  </div>
 
  <div class="dice second-face">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
  <div class="dice third-face">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
  <div class="dice fourth-face">
 
    <div class="column">
 
      <span class="dot"></span>
 
      <span class="dot"></span>
 
    </div>
 
    <div class="column">
 
      <span class="dot"></span>
 
      <span class="dot"></span>
 
    </div>
 
  </div>
 
  <div class="fifth-face dice">
 
    <div class="column">
 
      <span class="dot"></span>
 
      <span class="dot"></span>
 
    </div>
 
    <div class="column">
 
      <span class="dot"></span>
 
    </div>
 
    <div class="column">
 
      <span class="dot"></span>
 
      <span class="dot"></span>
 
    </div>
 
  </div>
 
  <div class="dice sixth-face">
 
    <div class="column">
 
      <span class="dot"></span>
 
      <span class="dot"></span>
 
      <span class="dot"></span>
 
    </div>
 
    <div class="column">
 
      <span class="dot"></span>
 
      <span class="dot"></span>
 
      <span class="dot"></span>
 
    </div>
 
  </div>
 
</div>
 
下面来实现每个面和每个点的的基本样式:
 
.dice {
 
  width: 200px;  
 
  height: 200px;  
 
  padding: 20px;  
 
  background-color: tomato;
 
  border-radius: 10%;
 
}
 
.dot {
 
   display: inline-block;
 
   width: 50px;
 
   height: 50px;
 
   border-radius: 50%;
 
   background-color: white;
 
}

(1)一个点
 
HTML 结构如下:
 
<div class="dice first-face">
 
  <span class="dot"></span>
 
</div>
 
实现第一个面,只需要让它水平和垂直方向都居中即可:
 
justify-content:center:使点与主轴(水平)的中心对齐。
 
align-items:center:使点与交叉轴(垂直)的中心对齐。
 
代码实现如下:
 
.first-face {
 
  display: flex;
 
  justify-content: center;
 
  align-items: center;
 
}
 
现在第一面是这样的:
 
(2)两个点
 
HTML 结构如下:
 
<div class="dice second-face">
 
  <span class="dot"></span>
 
  <span class="dot"></span>
 
</div>
 
首先来将第二个面的父元素设置为flex布局,并添加以下属性:
 
justify-content: space-between:将子元素放置在 flex 容器的开头和结尾。
 
.second-face {
 
   display: flex;
 
   justify-content : space-between;
 
}
 
这时,第一个点在正确的位置:左上角。而第二个点需要在右下角。因此,下面来使用 align-self 属性单独调整第二个点的位置:
 
align-self: flex-end:将项目对齐到 Flex 容器的末尾。
 
.second-face .dot:nth-of-type(2) {
 
 align-self: flex-end;
 
}
 
(3)三个点
 
HTML 结构如下:
 
<div class="dice third-face">
 
  <span class="dot"></span>
 
  <span class="dot"></span>
 
  <span class="dot"></span>
 
</div>
 
可以通过在第二面放置另一个中心点来实现第三面。
 
align-self: flex-end:将项目对齐到 Flex 容器的末尾。
 
align-self: center:将项目对齐到 Flex 容器的中间。
 
.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;
 
}

 
如果想要第一个点在右上角,第三个点在左下角,可以将第一个点的 align-self 更改为 flex-end,第二个点不变,第三个点无需设置,默认在最左侧:
 
.third-face {
 
 display: flex;
 
  justify-content : space-between;
 
}
 
.third-face .dot:nth-of-type(1) {
 
 align-self :flex-end;
 
}
 
.third-face .dot:nth-of-type(2) {
 
 align-self :center;
 
}
 
现在第三面是这样的:

(4)四个点
 
HTML 结构如下:
 
<div class="dice fourth-face">
 
  <div class="column">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
  <div class="column">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
</div>
 
在四个点的面中,可以将其分为两行,每行包含两列。一行将在 flex-start ,另一行将在 flex-end 。并添加 justify-content: space-between 以便将其放置在骰子的左侧和右侧。
 
.fourth-face {
 
 display: flex;
 
 justify-content: space-between
 
}
 
接下来需要对两列点分别进行布局:
 
将列设置为flex布局;
 
将flex-direction​设置为column,以便将点放置在垂直方向上
 
将justify-content​设置为space-between,它将使第一个点在顶部,第二个点在底部。
 
.fourth-face .column {
 
 display: flex;
 
  flex-direction: column;
 
  justify-content: space-between;
 
}
 
(5)五个点
 
HTML 结构如下:
 
<div class="fifth-face dice">
 
  <div class="column">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
  <div class="column">
 
    <span class="dot"></span>
 
  </div>
 
  <div class="column">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
</div>
 
第五面和第四面的差异在于多了中间的那个点。所以,可以基于第四面,来在中间增加一列,样式如下:
 
.fifth-face {
 
 display: flex;
 
 justify-content: space-between
 
}
 
.fifth-face .column {
 
 display: flex;
 
  flex-direction: column;
 
  justify-content: space-between;
 
}
 
还需要对中间的点进行调整,可以设置 justify-content 为 center 让它垂直居中:
 
.fifth-face .column:nth-of-type(2) {
 
 justify-content: center;
 
}
 
现在第五面是这样的:
 
 
 
(6)六个点
 
HTML 结构如下:
 
<div class="dice sixth-face">
 
  <div class="column">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
  <div class="column">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
</div>
 
第六个面的布局和第四个几乎完全一样,只不过每一列多了一个元素,布局实现如下:
 
.sixth-face {
 
 display: flex;
 
 justify-content: space-between
 
}

.sixth-face .column {
 
 display: flex;
 
  flex-direction: column;
 
  justify-content: space-between;
 
}
 
2. 使用 Grid 布局实现六个面
 
骰子每个面其实可以想象成一个 3 x 3 的网格,其中每个单元格代表一个点的位置:
 
+---+---+---+
 
| a | b | c |
 
+---+---+---+
 
| d | e | f |
 
+---+---+---+
 
| g | h | i |
 
+---+---+---+
 
要创建一个 3 x 3 的网格,只需要设置一个容器元素,并且设置三个大小相同的行和列:
 
.dice {
 
    display: grid;
 
    grid-template-rows: 1fr 1fr 1fr;
 
    grid-template-columns: 1fr 1fr 1fr;
 
}
 
这里的 fr 单位允许将行或列的大小设置为网格容器可用空间的一部分,这上面的例子中,我们需要三分之一的可用空间,所以设置了 1fr 三次。
 
我们还可以使用 repeat(3, 1fr) 将 1fr 重复 3 次,来代替 1fr 1fr 1fr。还可以使用定义行/列的grid-template速记属性将上述代码进行简化:
 
.dice {
 
    display: grid;
 
    grid-template: repeat(3, 1fr) / repeat(3, 1fr);
 
}
 
每个面所需要定义的 HTML 就像是这样:
 
<div class="dice">
 
  <span class="dot"></span>
 
  <span class="dot"></span>
 
  <span class="dot"></span>
 
  <span class="dot"></span>
 
</div>
 
所有的点将自动放置在每个单元格中,从左到右:
 
现在我们需要为每个骰子值定位点数。开始时我们提到,可以将每个面分成 3 x 3 的表格,但是这些表格并不是每一个都是我们需要的,分析骰子的六个面,可以发现,我们只需要以下七个位置的点:
 
+---+---+---+
 
| a |   | c |
 
+---+---+---+
 
| e | g | f |
 
+---+---+---+
 
| d |   | b |
 
+---+---+---+
 
我们可以使用grid-template-areas属性将此布局转换为 CSS:
 
.dice {
 
  display: grid;
 
  grid-template-areas:
 
    "a . c"
 
    "e g f"
 
    "d . b";
 
}
 
因此,我们可以不使用传统的单位来调整行和列的大小,而只需使用名称来引用每个单元格。其语法本身提供了网格结构的可视化,名称由网格项的网格区域属性定义。中间列中的点表示一个空单元格。
 
下面来使用grid-area属性为网格项命名,然后,网格模板可以通过其名称引用该项目,以将其放置在网格中的特定区域中。:nth-child()伪选择器允许单独定位每个点。
 
.dot:nth-child(2) {
 
    grid-area: b;
 
}
 
.dot:nth-child(3) {
 
    grid-area: c;
 
}
 
.dot:nth-child(4) {
 
    grid-area: d;
 
}
 
.dot:nth-child(5) {
 
    grid-area: e;
 
}
 
.dot:nth-child(6) {
 
    grid-area: f;
 
}
 
可以看到,1、3、5的布局仍然是不正确的,只需要重新定位每个骰子的最后一个点即可:
 
.dot:nth-child(odd):last-child {
 
    grid-area: g;
 
}
 
这时所有点的位置都正确了:

对于上面的 CSS,对应的 HTML分别是父级为一个div标签,该面有几个点,子级就有几个span标签。代码如下:
 
<div class="dice-box">
 
  <div class="dice first-face">
 
    <span class="dot"></span>
 
  </div>
 
  <div class="dice second-face">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
  <div class="dice third-face">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
  <div class="dice fourth-face">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
  <div class="fifth-face dice">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
  <div class="dice sixth-face">
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
    <span class="dot"></span>
 
  </div>
 
</div>
 
整体的 CSS 代码如下:
 
.dice {
 
  width: 200px;  
 
  height: 200px;  
 
  padding: 20px;  
 
  background-color: tomato;
 
  border-radius: 10%;
 
  display: grid;
 
  grid-template: repeat(3, 1fr) / repeat(3, 1fr);
 
  grid-template-areas:
 
    "a . c"
 
    "e g f"
 
    "d . b";
 
}
 
.dot {
 
  display: inline-block;
 
  width: 50px;
 
  height: 50px;
 
  border-radius: 50%;
 
  background-color: white;
 
}
 
.dot:nth-child(2) {
 
  grid-area: b;
 
}
 
.dot:nth-child(3) {
 
  grid-area: c;
 
}
 
.dot:nth-child(4) {
 
  grid-area: d;
 
}
 
.dot:nth-child(5) {
 
  grid-area: e;
 
}
 
.dot:nth-child(6) {
 
  grid-area: f;
 
}
 
.dot:nth-child(odd):last-child {
 
  grid-area: g;
 
}
 
​3. 实现 3D 骰子
 
上面我们分别使用 Flex 和 Grid 布局实现了骰子的六个面,下面来这将六个面组合成一个正方体。
 
首先对六个面进行一些样式修改:
 
.dice {
 
  width: 200px;  
 
  height: 200px;  
 
  padding: 20px;
 
  box-sizing: border-box;
 
  opacity: 0.7;
 
  background-color: tomato;
 
  position: absolute;
 
}
 
定义它们的父元素:
 
.dice-box {
 
  width: 200px;
 
  height: 200px;
 
  position: relative;
 
  transform-style: preserve-3d;
 
  transform: rotateY(185deg) rotateX(150deg) rotateZ(315deg);
 
}
 
其中,transform-style: preserve-3d;表示所有子元素在3D空间中呈现。这里的transform 的角度不重要,主要是便于后面查看。
 
看起来有点奇怪,所有面都叠加在一起。不要急,我们来一个个调整位置。
 
首先将第一个面在 Z 轴移动 100px:
 
.first-face {
 
  transform: translateZ(100px);
 
}
 
第一面就到了所有面的上方:
 
因为每个面的宽高都是 200px,所以将第六面沿 Z 轴向下调整 100px:
 
.sixth-face {
 
  transform: translateZ(-100px);
 
}
 
第六面就到了所有面的下方:
 
 
 
下面来调整第二面,将其在X轴向后移动 100px,并沿着 Y 轴旋转 -90 度:
 
.second-face {
 
  transform: translateX(-100px) rotateY(-90deg);
 
}
 
此时六个面是这样的:

下面来调整第二面的对面:第五面,将其沿 X 轴的正方向移动 100px,并沿着 Y 轴方向选择 90 度:
 
.fifth-face {
 
  transform: translateX(100px) rotateY(90deg);
 
}
 
下面来调整第三面,道理同上:
 
.third-face {
 
  transform: translateY(100px) rotateX(90deg);
 
}
  
最后来调整第五面:
 
.fourth-face {
 
  transform: translateY(-100px) rotateX(90deg);
 
}
 
此时六个面就组成了一个完整的正方体:

下面来为这个骰子设置一个动画,让它转起来:
 
@keyframes rotate {
 
  from {
 
    transform: rotateY(0) rotateX(45deg) rotateZ(45deg);
 
  }
 
  to {
 
    transform: rotateY(360deg) rotateX(45deg) rotateZ(45deg);
 
  }
 
}
 
.dice-box {
 
  animation: rotate 5s linear infinite;
 
}
在线体验:
 
3D 骰子-Flex:https://codepen.io/cugergz/pen/jOzYGyV
 
3D 骰子-Grid:https://codepen.io/cugergz/pen/GROMgEe
 
 

(编辑:聊城站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!