用 CSS3 实现一个 Webpack 的 logo 动画

简介: 用 CSS3 实现一个 Webpack 的 logo 动画

前言

先直接展示下最终效果,想看代码的可以直接拉到最底部

4.gif

webpack 官网上的截图:

image.png

分析:webpack 这个 logo 的实现思路很简单,其实就是绘制了两个正方形,外面一个里面一个,然后让两个正方形按照不同的方向旋转即可

所以我们又可以把目标变成:如何实现一个正方形

css 中实现一个正方形,就不得不先讲一下 css3 transform

1. 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硬件加速,比如: translate3dtranslateZscale3drotate3d ...

1.1. 3D旋转

1. rotateZ 、rotateX、rotateY

  • 旋转:rotateX(deg)rotateY(deg)rotateZ(deg)
    • CSS 函数定义一个变换,它将元素围绕固定轴旋转。旋转量由指定的角度确定; 为正,旋转将为顺时针,为负,则为逆时针。
  • 值个数
    • 只有一个值,表示旋转的角度(单位 deg
  • 值类型:
    • deg:<angle> 类型,表示旋转角度(不是弧度)。
    • 正数为顺时针
    • 负数为逆时针
  • 简写:rotate3d(x, y, z, deg)
  • 注意:旋转的原点受 transform-origin 影响

image.png

2. rotate3d

  • 旋转:rotate3d(x, y, z, a)
    • CSS 函数定义一个变换,它将元素围绕固定轴旋转。旋转量由指定的角度定义; 为正,运动将为顺时针,为负,则为逆时针。
  • 值个数
    • 一个值时,表示 z 轴 旋转的角度
    • 四个值时,表示在 3D 空间之中,旋转有 x , y , z 个旋转轴和一个旋转角度。
  • 值类型:
    • x:<number> 类型,可以是 0 到 1 之间的数值,表示旋转轴 X坐标方向的矢量(用来计算形变矩阵中的值)。
    • y:<number> 类型,可以是 0 到 1 之间的数值,表示旋转轴 Y 坐标方向的矢量。
    • z:<number> 类型,可以是 0 到 1 之间的数值,表示旋转轴 Z 坐标方向的矢量。
    • a:<angle> 类型,表示旋转角度。正的角度值表示顺时针旋转,负值表示逆时针旋转。
  • 注意:旋转的原点受 transform-origin 影响

1.2. 3D透视

  • 透视:perspective
    • 定义了观察者与 z=0 平面的距离,使具有三维位置变换的元素产生透视效果(z 表示Z 轴)。
    • z>0 的三维元素比正常的大,而 z<0 时则比正常的小,大小程度由该属性的值决定。
  • 值个数
    • 只有一个值,表示观察者距离 z=0 的平面距离 和 none
  • 必须是 <none> <length> 中的一个
    • none:没有应用 perspective 样式时的默认值。
    • length:定观察者距离 z=0 平面的距离(如下图 d 的距离,单位 px)。
      ✓ 为元素及其内容应用透视变换。当值为 0 或负值时,无透视变换。
  • 透视的两种使用方式:
    1. 在父元素上定义 CSS 透视属性
    2. 如果它是子元素或单元素子元素,可以使用函数 perspective()

image.png

1.3. 3D位移

1. translateX、translateY、translateZ

  • 平移:translateX(x)translateY(y)translateZ(z)
    • 该函数表示在二、三维平面上移动元素。
  • 值个数
    • 只有一个值,设置对应轴上的位移
  • 值类型:
    • 数字:100px
    • 百分比:参照元素本身( refer to the size of bounding box )

2. translate3d

平移:translate3d(tx, ty, tz)

  • CSS 函数在 3D 空间内移动一个元素的位置。这个移动由一个三维向量来表达,分别表示他在三个方向上移动的距离。
  • 值个数
    • 三个值时,表示在 3D 空间之中, tx , ty , tz 分别表示他在三个方向上移动的距离。
  • 值类型:
    • tx:是一个 <length> 代表移动向量的横坐标。
    • ty:是一个 <length> 代表移动向量的纵坐标。
    • tz:是一个 <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.4. 3D缩放

1. scaleX、scaleY、scaleZ

  • 缩放:scaleXscaleYscaleZ
    • 函数指定了一个沿 xyz 轴调整元素缩放比例因子。
  • 值个数
    • 一个值时,设置对应轴上的缩放(无单位)
  • 值类型:
    • 数字
      ✓ 1:保持不变
      ✓ 2:放大一倍
      ✓ 0.5:缩小一半
    • 百分比:不支持百分比

2. scaleX、scaleY、scaleZ

  • 缩放:scale3d(sx, sy,sz)
    • CSS 函数定义了在 3D 空间中调整元素的缩放比例因子 。。
  • 值个数
    • 三个值时,表示在 3D 空间之中, sx, sy, sz 分别表示他在三个方向上缩放的向量。
  • 值类型:
    • sx:是一个 <number> 代表缩放向量的横坐标。
    • sy:是一个 <number> 表示缩放向量的纵坐标。
    • sz:是 <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)

1.5. 3D空间

  • 变换式:transform-style
    • 该CSS属性用于设置元素的子元素是定位在 3D 空间中还是平展在元素的2D平面中。
    • 在3D空间中同样是可以使用透视效果。
  • 值类型:
    • flat:指示元素的子元素位于元素本身的平面内。
    • preserve-3d:指示元素的子元素应位于 3D 空间中。

image.png

  • 背面可见性:backface-visibility
    • 该CSS 属性 backface-visibility 指定某个元素当背面朝向观察者时是否可见。
  • 值类型:
    • visible:背面朝向用户时可见。
    • hidden:背面朝向用户时不可见。

image.png

2. 先实现一个正方形的骰子

先将骰子的六个面绘制出来,这里我用的 grid 布局,用 flex 也可以的

body {
   
  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;
}
<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>

image.png

现在将 dice-wrapper 稍作修改:

/* 在父元素中添加 transform-style来启用3D空间 */
transform-style: preserve-3d;
transform: rotateX(-33.5deg) rotateY(45deg);

此时六个面的效果都是这样的:

image.png

接下来我们一个个调整位置

第一个面

.first-face {
  transform: rotateX(90deg) translateZ(100px);
}

image.png

第二个面

.second-face {
  transform: rotateX(-90deg) translateZ(100px);
}

image.png

第三个和第四个面

.third-face {
   
  transform: rotateY(0deg) translateZ(100px);
}
.fourth-face {
   
  transform: rotateY(-180deg) translateZ(100px);
}

image.png

最后两个面

.fifth-face {
   
  transform: rotateY(-90deg) translateZ(100px);
}
.sixth-face {
   
  transform: rotateY(90deg) translateZ(100px);
}

image.png

3. 实现 Webpack logo

有了上面实现正方形的基础,我们终于可以来实现这个 logo 啦。

3.1 实现基本框架 v1 版本

  1. css 部分
    ```css
    body {
    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;
}


2. `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>

上面两部分都很简单:

  1. cube-inner 作为里面的正方
  2. cube-outer 作为外面的正方形。
  3. 两个正方形都有 top bottom front back left right 六个面

3.2 绘制两个正方形

根据第 2 节中的知识绘制两个正方形,要注意的是两个正方形的大小控制好两倍,我这里设置的是
50px 100px

添加 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);
}

3.3 添加动画

要让两个正方形转起来,可以使用 keyframes 帧动画

添加 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,大功告成。

相关文章
|
2月前
|
机器学习/深度学习 前端开发 JavaScript
|
1月前
纯css3实现的百分比渐变进度条加载动画源码
纯css3实现的百分比渐变进度条加载动画特效源码
58 31
|
2月前
|
前端开发 搜索推荐 UED
实现 CSS 动画效果的兼容性
【10月更文挑战第16天】实现 CSS 动画效果的兼容性需要对不同浏览器的特性有深入的了解,并采取适当的策略和方法。通过不断的实践和优化,你可以在各种浏览器上创造出流畅、美观且兼容的动画效果,为用户带来更好的体验。在实际开发中,要密切关注浏览器的发展动态,及时掌握最新的兼容性技巧和解决方案,以确保你的动画设计能够在广泛的用户群体中得到良好的呈现。
116 58
|
21天前
|
Web App开发 移动开发 JavaScript
纯CSS3+SVG实现的节日庆祝五彩纸屑动画效果源码
这是一款基于纯CSS3+SVG实现的节日庆祝五彩纸屑动画效果源码。画面中左下角是一个圆锥形礼炮卡通效果,呈现出节日庆祝时礼花爆破、五彩纸屑纷飞的动画特效。整体动画效果采用纯css3+svg实现,没有引入任何外部图形或js脚本元素。建议使用支持HTML5与css3效果较好的火狐(Firefox)或谷歌(Chrome)等浏览器预览本源码。
39 6
|
1月前
|
前端开发 JavaScript UED
CSS滚动效果和视差滚动的原理、应用及其对用户体验的影响。从平滑滚动到元素跟随,再到滚动触发动画
本文探讨了CSS滚动效果和视差滚动的原理、应用及其对用户体验的影响。从平滑滚动到元素跟随,再到滚动触发动画,这些效果增强了页面的吸引力和互动性。视差滚动通过不同层次元素的差异化移动,增加了页面的深度感和沉浸感。文章还讨论了实现方法、性能优化及案例分析,旨在为设计师和开发者提供实用指导。
61 7
|
1月前
CSS3制作的聚光灯下倒影文字选装动画特效源码
CSS3聚光灯下倒影文字特效是一段基于CSS3实现的聚光灯下带倒影的文字旋转动画效果代码,具有真实的视觉感,同时文字还会在旋转过程中显示出灯光的反射效果,很有意思,欢迎对此段代码感兴趣的朋友前来下载使用。
32 6
|
1月前
|
移动开发 前端开发 JavaScript
除了 CSS3,还有哪些技术可以实现动画效果?
除了 CSS3,还有哪些技术可以实现动画效果?
60 5
|
1月前
纯css3加载loading发光变色动画代码
纯css3加载loading发光变色动画特效代码是一款基于css3 keyframes属性实现的发光变色圆点串联旋转loading加载动画
25 2
|
1月前
|
Web App开发 前端开发 iOS开发
CSS加载动画大全 126种
CSS加载动画大全是一个css Loaders加载动画特效汇总,一共包含126种加载动画效果,不同样式不同图案,简单实用,一览包含所有,会让你在等待的过程中,体验视觉盛宴,给用户不一般的加载体验,欢迎下载试试!代码适用浏览器:搜狗、360、FireFox(建议)、Chrome、Safari、Opera、傲游、世界之窗,是一款不错的的特效插件,希望大家喜欢!
29 2
|
1月前
|
JavaScript 前端开发
CSS3 动画和 JavaScript 动画的性能比较
具体的性能表现还会受到许多因素的影响,如动画的复杂程度、浏览器的性能、设备的硬件条件等。在实际应用中,需要根据具体情况选择合适的动画技术。

热门文章

最新文章