Skip to content
001

11_空间转换 + 动画

01_空间转换

01_平移 + 视距

01_空间转换

空间: 是从坐标轴角度定义的 X, Y 和 Z 三条坐标轴构成了一个立体空间, Z 轴位置与视线方向相同

空间转换也叫 3D 转换

属性: transform

002

02_平移

属性

003

取值 (正负 均可)

  • 像素单位数值
  • 百分比 (参照 盒子自身尺寸 计算结果)
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    .box {
      width: 200px;
      height: 200px;
      margin: 100px auto;
      background-color: pink;
      transition: all 0.5s;
    }

    .box:hover {
      /* 1.电脑是平面, 默认无法观察 Z 轴平移效果 */
      transform: translate3d(100px, 200px, 300px);

      /* 2.3d 小括号里面必须逗号隔开三个数(否则不生效) */
      /* transform: translate3d(100px, 200px); */

      /* 3.水平移动 */
      /* transform: translateX(100px); */

      /* 4.垂直移动 */
      /* transform: translateY(-100%); */

      /* 5.视线移动 */
      /* transform: translateZ(300px); */
    }
  </style>
</head>

<body>
  <div class="box"></div>
</body>

</html>

03_视距 perspective

作用: 指定了 观察者Z = 0 平面的 距离, 为元素添加 透视效果

透视效果: 近大远小, 近实远虚

004

属性: (添加给 父级, 取值范围 800~1200)

005
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    /* 1.视距属性必须添加给 直接父级 */
    .father {
      /* 2.取值范围 800~1200 */
      perspective: 1000px;
    }

    .son {
      width: 200px;
      height: 200px;
      margin: 100px auto;
      background-color: pink;
      transition: all 0.5s;
    }

    .son:hover {
      /* 3.负值: 远小 */
      /* transform: translateZ(-300px); */

      /* 4.正值: 近大 */
      transform: translateZ(300px);
    }
  </style>
</head>

<body>
  <div class="father">
    <div class="son"></div>
  </div>
</body>

</html>

02_旋转

01_Z 轴旋转

transform: rotateZ(值);

006
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    .box {
      width: 300px;
      margin: 100px auto;
    }

    img {
      width: 300px;
      transition: all 2s;
    }

    .box img:hover {
      /* 1.正数: 顺时针旋转 */
      /* transform: rotateZ(360deg); */

      /* 2.负数: 逆时针旋转 */
      transform: rotateZ(-360deg);

    }
  </style>
</head>

<body>
  <div class="box">
    <img src="./images/hero.jpeg" alt="" />
  </div>
</body>

</html>

02_X 轴旋转

transform: rotateX(值);

007
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    .box {
      width: 300px;
      margin: 100px auto;
    }

    img {
      width: 300px;
      transition: all 2s;
    }

    .box {
      /* 透视效果: 近大远小, 近实远虚 */
      perspective: 1000px;
    }

    .box img:hover {
      /* 1.正数: 从下往上旋转  */
      /* transform: rotateX(60deg); */

      /* 2.负数: 从上往下旋转 */
      transform: rotateX(-60deg);
    }
  </style>
</head>

<body>
  <div class="box">
    <img src="./images/hero.jpeg" alt="" />
  </div>
</body>

</html>

03_Y 轴旋转

transform: rotateY(值);

008
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    .box {
      width: 300px;
      margin: 100px auto;
    }
  
    img {
      width: 300px;
      transition: all 2s;
    }
  
    .box {
      /* 透视效果: 近大远小, 近实远虚 */
      perspective: 1000px;
    }
  
    .box img:hover {
      /* 1.正数: 从左往右旋转 */
      /* transform: rotateY(60deg); */
  
      /* 2.负数: 从右往左旋转 */
      transform: rotateY(-60deg);
    }
  </style>
</head>

<body>
  <div class="box">
    <img src="./images/hero.jpeg" alt="" />
  </div>
</body>

</html>

04_左手法则

左手法则 - 根据 旋转方向 确定取值 正负

  • 左手 握住旋转轴, 拇指指向正值方向, 其他四个手指 弯曲 方向为旋转 正值 方向
009

05_拓展

  • rotate3d(x, y, z, 角度度数): 用来设置 自定义旋转轴的位置 及旋转的角度
  • x, y, z 取值为 0 ~ 1 之间的数字

03_立体呈现

01_立体呈现

作用: 设置元素的 元素是位于 3D 空间 中还是 平面

属性名: transform-style

010

属性值:

  • flat:子级处于 平面
  • preserve-3d: 子级处于 3D 空间

呈现立体图形步骤

  1. 父元素 添加 transform-style: preserve-3d;
  2. 子级 定位
  3. 调整子盒子的 位置 (位移或旋转)
011
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    .cube {
      position: relative;
      width: 200px;
      height: 200px;
      margin: 100px auto;
      /* background-color: pink; */
      transition: all 2s;

      /* 1.父元素 添加 transform-style: preserve-3d; */
      transform-style: preserve-3d;

      /* 旋转与案例效果无关, 用来看前后移动的效果 */
      /* transform: rotateY(89deg); */
    }

    .cube div {
      /* 2.子级 定位 */
      position: absolute;
      left: 0;
      top: 0;
      width: 200px;
      height: 200px;
    }

    .front {
      background-color: orange;

      /* 3.调整子盒子的 位置(位移或旋转) */
      transform: translateZ(100px);
    }

    .back {
      background-color: green;

      /* 4.调整子盒子的 位置(位移或旋转) */
      transform: translateZ(-100px);
    }

    .cube:hover {
      transform: rotateY(90deg);
    }
  </style>
</head>

<body>
  <div class="cube">
    <div class="front">前面</div>
    <div class="back">后面</div>
  </div>
</body>

</html>

04_3D 导航案例

01_3D 导航案例

012

搭建 立方体

  • 绿色是立方体的前面
  • 橙色是立方体的上面
013

添加鼠标 悬停旋转 效果

014
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    ul {
      margin: 0;
      padding: 0;
      list-style: none;
    }

    .nav {
      width: 300px;
      height: 40px;
      margin: 50px auto;
    }

    .nav ul {
      display: flex;
    }

    .nav li {
      position: relative;
      width: 100px;
      height: 40px;
      line-height: 40px;
      transition: all 0.5s;

      /* 1.搭建 立方体 */
      transform-style: preserve-3d;

      /* 为了看到橙色和绿色的移动过程, 给立方体添加旋转 */
      /* transform: rotateX(-20deg) rotateY(30deg); */
    }

    .nav li a {
      position: absolute;
      left: 0;
      top: 0;
      display: block;
      width: 100%;
      height: 100%;
      text-align: center;
      text-decoration: none;
      color: #fff;
    }

    /* 4.立方体每个面都有独立的坐标轴, 互不影响 */
    .nav li a:first-child {
      background-color: green;

      /* 3.绿色是立方体的前面 */
      transform: translateZ(20px);
    }

    .nav li a:last-child {
      background-color: orange;

      /* 2.橙色是立方体的上面 */
      transform: rotateX(90deg) translateZ(20px);
    }

    .nav li:hover {
      /* 5.添加鼠标 悬停 的 旋转 效果 */
      transform: rotateX(-90deg);
    }
  </style>
</head>

<body>
  <div class="nav">
    <ul>
      <li>
        <a href="#">首页</a>
        <a href="#">Index</a>
      </li>
      <li>
        <a href="#">登录</a>
        <a href="#">Login</a>
      </li>
      <li>
        <a href="#">注册</a>
        <a href="#">Register</a>
      </li>
    </ul>
  </div>
</body>

</html>

05_缩放

01_缩放

属性

015
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    ul {
      margin: 0;
      padding: 0;
      list-style: none;
    }

    .nav {
      width: 300px;
      height: 40px;
      margin: 50px auto;
    }

    .nav ul {
      display: flex;
    }

    .nav li {
      position: relative;
      width: 100px;
      height: 40px;
      line-height: 40px;
      transition: all 0.5s;

      /* 搭建 立方体 */
      transform-style: preserve-3d;

      /* 1.长度缩放倍数 */
      /* transform: scaleX(0.5); */

      /* 2.宽度缩放倍数 */
      /* transform: scaleY(2); */

      /* 3.视距缩放倍数 */
      /* transform: scaleZ(3); */

      /* 4.长度缩放倍数, 宽度缩放倍数, 视距缩放倍数 */
      transform: scale3d(0.5, 2, 3);

      /* 为了看到橙色和绿色的移动过程, 给立方体添加旋转 */
      /* transform: rotateX(-20deg) rotateY(30deg); */
    }

    .nav li a {
      position: absolute;
      left: 0;
      top: 0;
      display: block;
      width: 100%;
      height: 100%;
      text-align: center;
      text-decoration: none;
      color: #fff;
    }

    /* 立方体每个面都有独立的坐标轴, 互不影响 */
    .nav li a:first-child {
      background-color: green;

      /* 绿色是立方体的前面 */
      transform: translateZ(20px);
    }

    .nav li a:last-child {
      background-color: orange;

      /* 橙色是立方体的上面 */
      transform: rotateX(90deg) translateZ(20px);
    }

    .nav li:hover {
      /* 添加鼠标 悬停 的 旋转 效果 */
      transform: rotateX(-90deg);
    }
  </style>
</head>

<body>
  <div class="nav">
    <ul>
      <li>
        <a href="#">首页</a>
        <a href="#">Index</a>
      </li>
      <li>
        <a href="#">登录</a>
        <a href="#">Login</a>
      </li>
      <li>
        <a href="#">注册</a>
        <a href="#">Register</a>
      </li>
    </ul>
  </div>
</body>

</html>

02_动画

01_介绍

01_介绍

过渡: 实现 两个状态 间的变化过程

动画: 实现 多个状态 间的变化过程, 动画过程可控 (重复播放, 最终画面, 是否暂停)

016

02_定义使用

01_定义使用

017

使用动画

018
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    .box {
      width: 200px;
      height: 100px;
      background-color: pink;

      /* 2.使用动画 animation: 动画名称 动画花费时长 */
      animation: change 1s;
    }

    /* 1.定义动画一: 宽度从 200 变化到 800 */
    /* @keyframes change {
      from {
        width: 200px;
      }
  
      to {
        width: 800px;
      }
    } */

    /* 1.定义动画二: 从 200*100 变化到 300*300 变化到 800*500; 百分比: 表示的意思是动画时长的百分比 */
    @keyframes change {
      0% {
        width: 200px;
        height: 100px;
      }

      20% {
        width: 300px;
        height: 300px;
      }

      100% {
        width: 800px;
        height: 500px;
      }
    }
  </style>
</head>

<body>
  <div class="box"></div>
</body>

</html>

03_动画属性

01_动画复合属性

提示:

  • 动画名称动画时长 必须赋值
  • 取值 分先后顺序
  • 如果有 两个时间 值, 第一个 时间表示 动画时长, 第二个 时间表示 延迟时间
019
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    .box {
      width: 200px;
      height: 100px;
      background-color: pink;

      /* 1.速度曲线: linear 匀速 */
      /* animation: change 1s linear; */

      /* 2.速度曲线: steps 分步动画, 工作中, 配合精灵图实现精灵动画 */
      /* animation: change 1s steps(3); */

      /* 3.延迟时间: 如果有两个时间, 第一个是动画时长, 第二个是延迟时间 */
      /* animation: change 1s 2s; */

      /* 4.重复次数: infinite 无限循环 */
      /* animation: change 1s 3; */
      /* animation: change 1s infinite; */

      /* 5.动画方向: alternate 反向 */
      /* animation: change 1s infinite alternate; */

      /* 6.执行完毕时状态: forwards 结束状态; backwards 开始状态 (默认) */
      /* animation: change 1s forwards; */
      animation: change 1s backwards;
    }

    /* 宽度 从 200 变化到 800 */
    @keyframes change {
      from {
        width: 200px;
      }

      to {
        width: 800px;
      }
    }
  </style>
</head>

<body>
  <div class="box"></div>
</body>

</html>

02_动画拆分属性

020
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    .box {
      width: 200px;
      height: 100px;
      background-color: pink;

      /* 1.动画名称 */
      animation-name: change;
      /* 2.动画时长 */
      animation-duration: 1s;
      /* 3.重复次数: infinite 为无限循环 */
      animation-iteration-count: infinite;
    }

    .box:hover {
      /* 4.暂停动画: paused 为暂停, 通常配合 :hover 使用 */
      animation-play-state: paused;
    }

    /* 宽度从 200 变化到 800 */
    @keyframes change {
      0% {
        width: 200px;
      }

      100% {
        width: 800px;
      }
    }
  </style>
</head>

<body>
  <div class="box"></div>
</body>

</html>

04_走马灯案例

01_走马灯效果

021

无缝动画原理: 复制 开头图片结尾 位置 (图片累加宽度 = 区域宽度)

022
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    * {
      padding: 0;
      margin: 0;
    }

    li {
      list-style: none;
    }

    img {
      display: block;
      width: 200px;
    }

    .box {
      width: 600px;
      height: 112px;
      border: 5px solid #000;
      margin: 100px auto;
      overflow: hidden;
    }

    .box ul {
      display: flex;

      /* 2.使用动画: infinite 无限循环, linear 匀速 */
      animation: move 6s infinite linear;
    }

    /* 1.定义位移动画 */
    @keyframes move {
      0% {
        transform: translate(0);
      }

      100% {
        transform: translate(-1400px);
      }
    }

    /* 4.鼠标悬停暂停动画 */
    .box:hover ul {
      animation-play-state: paused;
    }
  </style>
</head>

<body>
  <div class="box">
    <ul>
      <li><img src="./images/1.jpg" alt="" /></li>
      <li><img src="./images/2.jpg" alt="" /></li>
      <li><img src="./images/3.jpg" alt="" /></li>
      <li><img src="./images/4.jpg" alt="" /></li>
      <li><img src="./images/5.jpg" alt="" /></li>
      <li><img src="./images/6.jpg" alt="" /></li>
      <li><img src="./images/7.jpg" alt="" /></li>

      <!-- 3.无缝动画原理: 复制 开头图片 到 结尾 位置 (图片累加宽度 = 区域宽度) -->
      <li><img src="./images/1.jpg" alt="" /></li>
      <li><img src="./images/2.jpg" alt="" /></li>
      <li><img src="./images/3.jpg" alt="" /></li>
    </ul>
  </div>
</body>

</html>

05_逐帧动画 + 多组动画

01_逐帧动画

023

02_逐帧动画案例

024

核心原理:

  1. steps() 逐帧动画
  2. CSS 精灵图

精灵动画制作步骤

  1. 准备显示区域
    1. 盒子尺寸与 一张精灵小图尺寸 相同
  2. 定义动画
    1. 移动背景图 (移动距离 = 精灵图宽度)
  3. 使用动画
    1. steps(N), N 与精灵小图个数相同
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    div {
      /* 1.盒子尺寸与 一张精灵小图尺寸 相同 */
      width: 140px;
      height: 140px;
      border: 1px solid #000;
      background-image: url(./images/bg.png);

      /* 3.teps(N), N 与精灵小图个数相同 */
      animation: run 1s steps(12) infinite;
    }

    /* 2.移动背景图 ( 移动距离 = 精灵图宽度 ) */
    @keyframes run {
      from {
        background-position: 0 0;
      }

      to {
        background-position: -1680px 0;
      }
    }
  </style>
</head>

<body>
  <div></div>
</body>

</html>

03_多组动画

025026
html
<!-- /code/test.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>

  <style>
    div {
      width: 140px;
      height: 140px;
      /* border: 1px solid #000; */
      background-image: url(./images/bg.png);

      animation:
        /* 3.使用动画一 */
        run 1s steps(12) infinite,

        /* 4.使用动画二 */
        move 3s forwards;
    }

    /* 5.当动画的开始状态样式 跟 盒子默认样式相同, 可以省略动画开始状态的代码 */

    /* 1.动画一 */
    @keyframes run {
      /* from {
        background-position: 0 0;
      } */

      to {
        background-position: -1680px 0;
      }
    }

    /* 2.动画二 */
    @keyframes move {
      /* 0% {
        transform: translate(0);
      } */

      100% {
        transform: translate(800px);
      }
    }
  </style>
</head>

<body>
  <div></div>
</body>

</html>

03_综合案例

01_全民出游

01_背景图

027
html
<!-- /code/index.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>全民出游季</title>
  <link rel="stylesheet" href="./css/index.css">
</head>

<body>

</body>

</html>
css
/* /code/css/index.css */

/* 1.背景图 */
html {
  /* 默认状态 HTML 和 body 的高度是 0, 所以导致 cover 缩放背景图不成功 */
  height: 100%;
}

body {
  height: 100%;
  background: url(../images/f1_1.jpg) no-repeat center 0 / cover;
  /* background-size: cover; */
}

02_云彩

028
html
<!-- /code/index.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>全民出游季</title>
  <link rel="stylesheet" href="./css/index.css">
</head>

<body>
  <!-- 1.云彩 -->
  <div class="cloud">
    <img src="./images/yun1.png" alt="">
    <img src="./images/yun2.png" alt="">
    <img src="./images/yun3.png" alt="">
  </div>
</body>

</html>
css
/* /code/css/index.css */

/* 2.云彩 */
.cloud img {
  position: absolute;
  left: 50%;
}

.cloud img:nth-child(1) {
  margin-left: -250px;
  top: 20px;
  animation: cloud 1s infinite alternate linear;
}

.cloud img:nth-child(2) {
  margin-left: 400px;
  top: 100px;
  animation: cloud 1s infinite alternate linear 0.4s;
}

.cloud img:nth-child(3) {
  margin-left: -550px;
  top: 200px;
  animation: cloud 1s infinite alternate linear 0.6s;
}

@keyframes cloud {
  100% {
    transform: translate(20px);
  }
}

03_文字

029
html
<!-- /code/index.html -->

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>全民出游季</title>
  <link rel="stylesheet" href="./css/index.css">
</head>

<body>
  <!-- 云彩 -->
  <!-- ...... -->

  <!-- 1.文字 -->
  <div class="text">
    <img src="./images/font1.png" alt="">
  </div>
</body>

</html>
css
/* /code/css/index.css */

/* 2.文字 */
.text img {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  animation: text 1s;
}

/* 默认 ==> 小 ==> 大 ==> 小 ==> 默认 */
@keyframes text {
  0% {
    transform: translate(-50%, -50%) scale(1);
  }

  20% {
    transform: translate(-50%, -50%) scale(0.1);
  }

  40% {
    transform: translate(-50%, -50%) scale(1.4);
  }

  70% {
    transform: translate(-50%, -50%) scale(0.8);
  }

  100% {
    transform: translate(-50%, -50%) scale(1);
  }
}

更新时间: