2.旋转的骰子(1)

1.动画——旋转的骰子

我们想用纯html CSS 做一个旋转的筛子,骰子要有立体感,每个面上要有圆点,表示点数,并且骰子可以原地旋转。

2.分析需求——庖丁解牛

a.立方体的每个面上有点数

立方体面上不同数量和排布的圆点,可以使用CSS来完成,让原点有内凹的立体感。至于排布,我们可以使用先进的flex实现。

b.骰子个立方体

这个筛子必须是一个货真价实的立方体才行,只有这样才能在旋转中才能没有破绽。而立方提有6个面,我们需要用六个正方形,辗转腾挪后拼接起来。立方体边缘要有一定的圆弧,而不是90度的棱角。

c.旋转是个大麻烦

立方体自身需要旋转,以便让立方体倾斜一定角度,同时要求保持倾斜的立方体围绕几何中心进行旋转,这需要对坐标轴和旋转有比较透彻的理解。

3.六个面——先来解决平面问题

在合成立方体之前,先解决平面的问题,复杂问题,先从简单的地方着手。我们先来制作6个面,这无非就是6<div>标签。每个面上的点,使用相应数量的<span>标签(或者任意其他标签)即可代替。使用css让点呈现内凹样式,使用flex对点进行布局。

a.六个面的逻辑划分

html的制作的原则就是要简单明了,清晰易懂!

 b.面的基本样式

 c.布局点点——flex排兵布阵

点的基本样式

 1个点——舍我其谁

2个点——平分秋色

 3个点——三分天下

 4个点——纵情四海

 5个点——五子登科

 6个点——六韬三略

 最终的效果:

4.立方体——我想起泰国的四面佛

立方体有6个面,前后左右上下,我们需要做六个正方形,然后通过transform属性的旋转和平移函数,来让它们处于正确的方位和方向,拼接成一个立方体。而且我们需要将元素的2D平面几何中心,作为立方体的几何中心。如图,这样的话,前后面前后移动,上下面围绕X轴旋转,上线移动,左右面围绕Y轴旋转,左右平移,就大功告成了

 a.首先需要将所有的面重合于相同区域,再进行旋转和移动

b.凡是子元素有3D显示效果的,父元素都需要设置透视3D,否则是看不到效果的

c.前后面移动立方体边长的1/2,同时注意,后面的面要反转180度(因为面有正反,正面要朝外)

 d.上下面围绕X轴旋转90度(注意旋转角度相反,因为面要朝外),同时沿上下平移立方体边长一半

e.左右面围绕Y轴旋转90度(注意旋转角度相反,因为面要朝外),同时朝左右移动立方体边长一半

f.我们可以旋转立方体,以便验证移动的正确性,可以选择性的隐藏显示其他面,或者修改面的颜色,方便查看。

g.立方体的面设为白色,我们发现,每个面之间是有空隙的,因为我们原先想要做成圆角的边缘,这样透过空袭就可以看到立方体内部,或者页面背景,非常的糟糕,我们需要完全遮挡空袭,并且让立方体更有立体感。

我们可以在立方体的中心增加一个上图所示的遮挡面片,遮挡面片位于立方体内部,这样无论如何都不会从缝隙看到背景了!

h. 制作遮挡面片

 i.通过上一步骤,我们发现视线很难穿透立方体的空隙,但是立方体的内部仍然可以看到,还需要一个遮挡。我们需要在6个面的每个面下方(在立方体内部),再提供一层遮挡,并且颜色设当加深,从而有一定立体感。图中深色的那层面片,当然,内层的面片会适当增大,否则也是无法遮挡的。这层遮挡位于作为面片子元素出现会比较好,这样,面片旋转时候,子元素也跟着旋转了。这让我们想到了伪元素。

 5.立方体旋转动画

立方体本身,我们可以通过设置.cube的样式来进行旋转,如图。但是,如果我们想要让立方体保持这个姿势,水平旋转,或者垂直旋转,单纯修改立方体本身的属性,就有点困难。

  

 加入水平“支架”,垂直“支架”,再把立方体放上去,然后旋转外面的支架即可。这个原理类似于在外面套了一层壳,类似于陀螺仪的结构。

增加水平,垂直“支架”

设置水平,垂直旋转帧动画

 设置水平垂直旋转动画

 设置尺寸与正方体边长相等,否则旋转轴会偏离正方体

设置3D透视属性,否则无法看到立体透视效果

 6.更多思考

a.如果想按照某个倾斜的轴旋转,如何操作实现

b.如果在立方体表面添加更多的面,每个面,实现不同的颜色,能否有更好的立体效果

c.如何添加鼠标的操作,滑动鼠标,可以转动立方体

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8"/>
		<title>Rotate Dice</title>
		<link rel="stylesheet" type="text/css" href="./styles.css"/>
	</head>
	<body>
		<div class="dice">
			<div class="vertical">
        <div class="horizontal">
          <div class="cube">
            <div class="face front one">
              <span class="dot"></span>
            </div>
            <div class="face back two">
              <span class="dot"></span>
              <span class="dot"></span>
            </div>
            <div class="face up three">
              <span class="dot"></span>
              <span class="dot"></span>
              <span class="dot"></span>
            </div>
            <div class="face down four">
              <div class="dot-row">
                <span class="dot"></span>
                <span class="dot"></span>
              </div>
              <div class="dot-row">
                <span class="dot"></span>
                <span class="dot"></span>
              </div>
            </div>
            <div class="face left five">
              <div class="dot-row">
                <span class="dot"></span>
                <span class="dot"></span>
              </div>
              <div class="dot-row">
                <span class="dot"></span>
              </div>
              <div class="dot-row">
                <span class="dot"></span>
                <span class="dot"></span>
              </div>
            </div>
            <div class="face right six">
              <div class="dot-row">
                <span class="dot"></span>
                <span class="dot"></span>
                <span class="dot"></span>
              </div>
              <div class="dot-row">
                <span class="dot"></span>
                <span class="dot"></span>
                <span class="dot"></span>
              </div>
            </div>
            <div class="axis-face x"></div>
            <div class="axis-face y"></div>
            <div class="axis-face z"></div>
          </div>
				</div>
			</div>
		</div>
		
	</body>
</html>

html
{
	background-color: black;
	font-size:100px;
	padding: 1em;
}

/*骰子动画*/
.vertical{
	animation: rotateX 5s infinite linear;
}
.horizontal{
	animation: rotateY 5s infinite linear;
}
.cube{
	transform: rotateX(-45deg) rotateY(45deg);
}
@keyframes rotateY {
	from{transform:rotateY(0);}
	to{transform:rotateY(360deg);}
}
@keyframes rotateX {
	from{transform:rotateX(0);}
	to{transform:rotateX(360deg);}
}
/*面的样式*/
.dice,.vertical,.horizontal,.cube,.face{
	transform-style:preserve-3d;
}
.dice,.vertical,.horizontal,.cube,.face,.face::after,.axis-face{
	width:1em;
	height: 1em;
}
.dice{
	margin: auto;
}
.cube{
  position: relative;
}
.face,.face::after,.axis-face{
	position: absolute;
  top:0;
  left: 0;
}
.face{
	box-sizing: border-box;
  padding: .15em;
  background-color: white;
  border-radius: 40%;
  box-shadow: 0 0 .2em #ccc inset;
}
.face::after{
  content:"";
  display: block;
  border-radius: .2em;
  transform: translateZ(-.1px);
  background-color: #e0e0e0;
}
.axis-face{
  background:#e0e0e0;
}

/*点的样式*/
.dot{
  width:.2em;
  height: .2em;
  display: inline-block;
  background: #444;
  border-radius: 50%;
  box-shadow: inset .05em .05em .1em black;
}

/* 面的方位*/
.face.front{
  transform: translateZ(.5em);
}
.face.back{
  transform: translateZ(-.5em) rotateY(180deg);
}
.face.up{
  transform: translateY(-50%) rotateX(90deg);
}
.face.down{
  transform: translateY(50%) rotateX(-90deg);
}
.face.left{
  transform: translateX(-50%) rotateY(-90deg);
}
.face.right{
  transform: translateX(50%) rotateY(90deg);
}
.axis-face.x{
  transform:rotateY(90deg);
}
.axis-face.y{
  transform:rotateX(90deg);
}
.axis-face.z{
}

/* 点的排列布局*/
.face,.dot-row{
  display: flex;
}
.face.one{
  align-items: center;
  justify-content: center;
}
.face.two{
  justify-content: space-around;
}
.face.two .dot:nth-child(2){
  align-self: flex-end;
}
.face.three{
  justify-content: space-around;
}
.face.three .dot:nth-child(2){
  align-self:center;
}
.face.three .dot:nth-child(3){
  align-self: flex-end;
}
.face.four{
  flex-direction: column;
  justify-content: space-between;
}
.face.four .dot-row{
  justify-content: space-between;
}
.face.five{
  flex-direction: column;
  justify-content: space-between;
}
.face.five .dot-row{
  justify-content: space-between;
}
.face.five .dot-row:nth-child(2){
  justify-content:center;
}
.face.six{
  flex-direction: column;
  justify-content: space-around;
}
.face.six .dot-row{
  justify-content: space-between;
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值