先直接展示下最终效果,想看代码的可以直接拉到最底部
webpack 官网上的截图:
分析:webpack
这个 logo
的实现思路很简单,其实就是绘制了两个正方形,外面一个里面一个,然后让两个正方形按照不同的方向旋转即可
所以我们又可以把目标变成:如何实现一个正方形。
css
中实现一个正方形,就不得不先讲一下 css3 transform
了
CSS3 Transform
属性不但允许你进行 2D
的旋转,缩放或平移指定的元素,还支持 3D
变换元素。
常见的函数 transform function
有:
translate3d(tx, ty, tz)
✓ translateX(tx)
、translateY(ty)
、translateZ(tz)
scale3d(sx, sy, sz)
✓ scaleX(sy)
、scaleY(sy)
、scaleZ(sz)
、rotate3d(x, y, z, a)
✓ rotateX(x)
、rotateY(y)
、rotateZ(z)
◼ 通过上面的几个函数,我们可以改变某个元素的 3D
形变。
◼ 3D
形变函数会创建一个合成层来启用GPU硬件加速,比如: translate3d
、translateZ
、 scale3d
、 rotate3d
...
1. rotateZ 、rotateX、rotateY
rotateX(deg)
、rotateY(deg)
、rotateZ(deg)
CSS
函数定义一个变换,它将元素围绕固定轴旋转。旋转量由指定的角度确定; 为正,旋转将为顺时针,为负,则为逆时针。deg
)<angle>
类型,表示旋转角度(不是弧度)。rotate3d(x, y, z, deg)
transform-origin
影响2. rotate3d
rotate3d(x, y, z, a)
CSS
函数定义一个变换,它将元素围绕固定轴旋转。旋转量由指定的角度定义; 为正,运动将为顺时针,为负,则为逆时针。z
轴 旋转的角度3D
空间之中,旋转有 x
, y
, z
个旋转轴和一个旋转角度。<number>
类型,可以是 0 到 1 之间的数值,表示旋转轴 X
坐标方向的矢量(用来计算形变矩阵中的值)。<number>
类型,可以是 0 到 1 之间的数值,表示旋转轴 Y
坐标方向的矢量。<number>
类型,可以是 0 到 1 之间的数值,表示旋转轴 Z
坐标方向的矢量。<angle>
类型,表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转。transform-origin
影响perspective
z=0
平面的距离,使具有三维位置变换的元素产生透视效果(z
表示Z
轴)。z>0
的三维元素比正常的大,而 z<0
时则比正常的小,大小程度由该属性的值决定。z=0
的平面距离 和 none
<none>
<length>
中的一个
perspective
样式时的默认值。z=0
平面的距离(如下图 d
的距离,单位 px
)。
✓ 为元素及其内容应用透视变换。当值为 0
或负值时,无透视变换。CSS
透视属性perspective()
1. translateX、translateY、translateZ
translateX(x)
、translateY(y)
、translateZ(z)
100px
2. translate3d
平移:translate3d(tx, ty, tz)
CSS
函数在 3D
空间内移动一个元素的位置。这个移动由一个三维向量来表达,分别表示他在三个方向上移动的距离。3D
空间之中, tx
, ty
, tz
分别表示他在三个方向上移动的距离。<length>
代表移动向量的横坐标。<length>
代表移动向量的纵坐标。<length>
代表移动向量的 z
坐标。它不能是 <percentage>
值;那样的移动是没有意义的。translateX(tx)
等同于 translate(tx, 0)
或者 translate3d(tx, 0, 0)
。translateY(ty)
等同于 translate(0, ty)
或者 translate3d(0, ty, 0)
。translateZ(zx)
等同于 translate3d(0, 0, tz)
。1. scaleX、scaleY、scaleZ
scaleX
、scaleY
、scaleZ
x
、y
、z
轴调整元素缩放比例因子。2. scaleX、scaleY、scaleZ
scale3d(sx, sy,sz)
CSS
函数定义了在 3D
空间中调整元素的缩放比例因子 。。3D
空间之中, sx
, sy
, sz
分别表示他在三个方向上缩放的向量。<number>
代表缩放向量的横坐标。<number>
表示缩放向量的纵坐标。<number>
表示缩放向量的 z
分量的 a
(再讲到 3D
正方体再演示)。scaleX(sx)
等价于 scale(sx, 1)
或 scale3d(sx, 1, 1)
。scaleY(sy)
等价于 scale(1, sy)
或 scale3d(1, sy, 1)
。scaleZ(sz)
等价于 scale3d(1, 1, sz)
。先将骰子的六个面绘制出来,这里我用的 grid
布局,用 flex
也可以的
cssbody {
margin: 0;
width: 100vw;
height: 100vh;
position: relative;
}
.dice-wrapper {
position: relative;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 200px;
height: 200px;
display: flex;
justify-content: space-around;
align-items: center;
}
.dice-face {
background-color: #fff;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 2px solid #000;
border-radius: 10%;
display: grid;
place-items: center;
grid-template: repeat(3, 1fr) / repeat(3, 1fr);
grid-template-areas:
"a . c"
"e g f"
"d . b";
}
.dot {
display: inline-block;
width: 50%;
height: 50%;
border-radius: 50%;
background-color: #000;
}
.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;
}
html<div class="dice-wrapper">
<div class="dice-face first-face">
<span class="dot"></span>
</div>
<div class="dice-face second-face">
<span class="dot"></span>
<span class="dot"></span>
</div>
<div class="dice-face third-face">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
<div class="dice-face fourth-face">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
<div class="fifth-face dice-face">
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
<span class="dot"></span>
</div>
<div class="dice-face 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>
现在将 dice-wrapper
稍作修改:
/* 在父元素中添加 transform-style来启用3D空间 */ transform-style: preserve-3d; transform: rotateX(-33.5deg) rotateY(45deg);
此时六个面的效果都是这样的:
接下来我们一个个调整位置
第一个面
CSS.first-face {
transform: rotateX(90deg) translateZ(100px);
}
第二个面
CSS.second-face {
transform: rotateX(-90deg) translateZ(100px);
}
**第三个和第四个面 **
css.third-face {
transform: rotateY(0deg) translateZ(100px);
}
.fourth-face {
transform: rotateY(-180deg) translateZ(100px);
}
最后两个面
css.fifth-face {
transform: rotateY(-90deg) translateZ(100px);
}
.sixth-face {
transform: rotateY(90deg) translateZ(100px);
}
有了上面实现正方形的基础,我们终于可以来实现这个 logo
啦。
css
部分cssbody {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
background-color: #2b3a42;
display: flex;
justify-content: center;
align-items: center;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
.webpack-logo {
width: 100%;
height: 200px;
/* border: 1px solid red; */
position: relative;
}
html
部分html<div class="webpack-logo">
<!-- cube-inner -->
<ul class="cube-inner">
<li class="top"></li>
<li class="bottom"></li>
<li class="front"></li>
<li class="back"></li>
<li class="left"></li>
<li class="right"></li>
</ul>
<!-- cube-outer -->
<ul class="cube-outer">
<li class="top"></li>
<li class="bottom"></li>
<li class="front"></li>
<li class="back"></li>
<li class="left"></li>
<li class="right"></li>
</ul>
</div>
上面两部分都很简单:
cube-inner
作为里面的正方cube-outer
作为外面的正方形。top
bottom
front
back
left
right
六个面根据第 2 节中的知识绘制两个正方形,要注意的是两个正方形的大小控制好两倍,我这里设置的是
50px
100px
添加 css
css.cube-inner {
position: absolute;
left: 50%;
top: 50%;
/* 关键,不要用 transform */
margin: -25px 0px 0px -25px;
width: 50px;
height: 50px;
/* background-color: red; */
/* 启用3D空间 */
transform-style: preserve-3d;
transform: rotateX(-33.5deg) rotateY(45deg);
/* 帧动画 */
animation: innerLoop 4s ease-in-out infinite;
}
.cube-inner li {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: #175d96;
border: 1px solid white;
}
.cube-inner .top {
transform: rotateX(90deg) translateZ(25px);
}
.cube-inner .bottom {
transform: rotateX(-90deg) translateZ(25px);
}
.cube-inner .front {
transform: rotateX(0deg) translateZ(25px);
}
.cube-inner .back {
transform: rotateX(-180deg) translateZ(25px);
}
.cube-inner .left {
transform: rotateY(-90deg) translateZ(25px);
}
.cube-inner .right {
transform: rotateY(90deg) translateZ(25px);
}
/* cube outer */
.cube-outer {
position: absolute;
left: 50%;
top: 50%;
/* 关键,不要用 transform */
margin: -50px 0px 0px -50px;
width: 100px;
height: 100px;
/* 启用3D空间 */
transform-style: preserve-3d;
transform: rotateX(-33.5deg) rotateY(45deg);
/* 帧动画 */
animation: outerLoop 4s ease-in-out infinite;
}
.cube-outer li {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(141, 214, 249, 0.5);
border: 1px solid white;
}
.cube-outer .top {
transform: rotateX(90deg) translateZ(50px);
}
.cube-outer .bottom {
transform: rotateX(-90deg) translateZ(50px);
}
.cube-outer .front {
transform: rotateX(0deg) translateZ(50px);
}
.cube-outer .back {
transform: rotateX(-180deg) translateZ(50px);
}
.cube-outer .left {
transform: rotateY(-90deg) translateZ(50px);
}
.cube-outer .right {
transform: rotateY(90deg) translateZ(50px);
}
要让两个正方形转起来,可以使用 keyframes
帧动画
添加 css
css@keyframes outerLoop {
0% {
transform: rotateX(-33.5deg) rotateY(45deg);
}
50%,
100% {
transform: rotateX(-33.5deg) rotateY(405deg);
}
}
@keyframes innerLoop {
0% {
transform: rotateX(-33.5deg) rotateY(45deg);
}
50%,
100% {
transform: rotateX(-33.5deg) rotateY(-315deg);
}
}
OK,大功告成。
本文作者:叶继伟
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!