CSS3 动画专题

0x01 过渡 transition

  • 过渡(transition)是应用于特定元素的 CSS 属性,在指定时间内平滑过渡到目标样式

(1)必要属性

  • 使用 transition-property 指定需要过渡的 CSS 属性
    • 可以列入一个或多个 CSS 属性
    • 也可以使用 all 值,表示所有变化的 CSS 属性都需要过渡
    • 仅可以用于过渡的值是可以用数字表示的属性,浏览器会计算并插入中间值实现过渡
  • 使用 transition-duration 指定过渡需要的持续时间
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    button {
      width: 200px;
      height: 100px;
      font-size: 20px;
      border: none;
      color: white;
      background-color: red;
      cursor: pointer;

      transition-property: background-color;
      transition-duration: 1s;
    }

    button:hover {
      background-color: purple;
    }
  </style>
</head>

<body>
  <button>Button</button>
</body>

</html>

(2)其他属性

  • 使用 transition-timing-function 指定过渡的时序函数(指过渡的变化方式)
    • ease:慢入、快变、慢出(默认)
    • linear:匀速
    • ease-in:缓慢开始,结束前加快
    • ease-out:快速开始,结束前减慢
    • ease-in-out:与 ease 类似
  • 使用 transition-delay 指定过渡的延迟时间
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    button {
      width: 200px;
      height: 100px;
      font-size: 20px;
      border: none;
      color: white;
      background-color: red;
      cursor: pointer;

      transition-property: background-color;
      transition-duration: 1s;

      transition-timing-function: ease-in;
      transition-delay: 0.5s;
    }

    button:hover {
      background-color: purple;
    }
  </style>
</head>

<body>
  <button>Button</button>
</body>

</html>

(3)缩写属性

transition: property duration timing-function delay[, property duration timing-function delay];

0x02 变换 transform

  • 变换(transform)是指改变元素的尺寸、形状以及位置
  • 变换提供了 4 种函数来控制元素的显示方式:scaletranslaterotateskew
  • transform-origin:设定变换原点
    • 默认取值包括 topleftrightbottomcenter 以及 top lefttop rightbottom rightbottom left
    • 也可以通过百分比、数值分别设定在 \(x\)\(y\) 轴构成的坐标

(1)scale

  • 通过放缩元素的宽高,改变元素的尺寸
  • scaleX():改变元素宽度,大于 \(1\) 表示放大倍数,\(0-1\) 之间表示缩小倍率(下同)
  • scaleY():改变元素高度
  • scale():一个值表示同时改变元素的宽高,两个值表示同时分别改变元素的宽度与高度
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    div {
      width: 300px;
      height: 200px;
      display: block;
      margin: auto;
      background-color: #ff7777;
      transition: transform 1s linear;
    }

    div:hover {
      transform: scale(1.5, 0.5);
    }
  </style>
</head>

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

</html>

(2)translate

  • 通过平移的方式,改变元素的位置

  • 二维变换

    • translateX():沿 \(x\) 轴方向移动,正值向右、负值向左
    • translateY():沿 \(y\) 轴方向移动,正值向下、负值向上
    • translate(x, y):同时沿 \(x\)\(y\) 轴移动,第一个参数是 \(x\) 轴方向移动,第二个参数是 \(y\) 轴方向移动
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8">
      <style>
        div {
          width: 300px;
          height: 200px;
          display: block;
          margin: auto;
          background-color: #ff7777;
          transition: transform 1s linear;
        }
    
        div:hover {
          transform: translate(-100px, 100px);
        }
      </style>
    </head>
    
    <body>
      <div></div>
    </body>
    
    </html>
    
  • 三维变换

    • translateZ():沿 \(z\) 轴方向移动,正值向外、负值向内
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8">
      <style>
        body {
          perspective: 1000px;	// 设定人眼与屏幕的距离为 1000px(即人眼在 z 轴 1000px 处)
        }
    
        div {
          width: 300px;
          height: 200px;
          display: block;
          margin: auto;
          background-color: #ff7777;
          transform-origin: bottom left;
          transition: transform 1s linear;
        }
    
        div:hover {
          transform: translateZ(300px);	// 效果看起来是放大(即近大远小)大于到人眼的距离时会消失
        }
      </style>
    </head>
    
    <body>
      <div></div>
    </body>
    
    </html>
    

(3)rotate

  • 通过旋转,改变元素的角度

  • 二维变换

    • rotate():默认以元素中心为中心,旋转指定角度(deg)、指定梯度(grad)或旋转圈数(turn),正值顺时针、负值逆时针
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8">
      <style>
        div {
          width: 300px;
          height: 200px;
          display: block;
          margin: auto;
          background-color: #ff7777;
          transition: transform 1s linear;
        }
    
        div:hover {
          transform: rotate(1turn);
        }
      </style>
    </head>
    
    <body>
      <div></div>
    </body>
    
    </html>
    
  • 三维变换

    • rotateX():沿 \(x\) 轴旋转,正负值旋转方向不同(下同)
    • rotateY():沿 \(y\) 轴旋转
    • rotateZ():沿 \(z\) 轴旋转
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8">
      <style>
        body {
          perspective: 1000px;
        }
    
        div {
          width: 300px;
          height: 200px;
          display: block;
          margin: auto;
          background-color: #ff7777;
          transition: transform 1s linear;
        }
    
        div:hover {
          transform: rotateX(30deg);
        }
      </style>
    </head>
    
    <body>
      <div></div>
    </body>
    
    </html>
    

(4)skew

  • 通过根据 \(x\) 轴或 \(y\)倾斜,改变元素的形状
  • skewX():在 \(x\) 轴方向上倾斜指定角度,正负值方向不同(下同)
  • skewX():在 \(y\) 轴方向上倾斜指定角度
  • skew(x, y):同时分别改变元素在 \(x\)\(y\) 轴上的倾斜
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    body {
      perspective: 1000px;
    }

    div {
      width: 300px;
      height: 200px;
      display: block;
      margin: auto;
      background-color: #ff7777;
      transition: transform 1s linear;
    }

    div:hover {
      transform: skewX(30deg);
    }
  </style>
</head>

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

</html>

(5)案例

a. 旋入

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    body {
      height: 100vh;
      display: flex;
    }

    a {
      text-decoration: none;
      margin: auto;
      border: 3px solid black;
      padding: 30px 80px;
      font-size: 30px;
      font-weight: bolder;
      position: relative;
      overflow: hidden;
    }

    a::before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      width: 105%;
      height: 100%;
      background-color: #ff7777;
      z-index: -1;
      transition: transform 0.5s ease-out;
      transform-origin: bottom left;
      transform: rotate(-90deg);
    }

    a:hover::before {
      transform: rotate(0deg);
    }
  </style>
</head>

<body>
  <a>Hover me</a>
</body>

</html>

b. 滑入

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    body {
      height: 100vh;
      display: flex;
    }

    a {
      text-decoration: none;
      margin: auto;
      border: 3px solid black;
      padding: 30px 80px;
      font-size: 30px;
      font-weight: bolder;
      color: #ff7777;
      position: relative;
      overflow: hidden;
      transition: all 1s ease-out;
    }

    a::before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: #ff7777;
      z-index: -1;
      transition: all 0.5s ease-out;
      transform: translateX(-100%);
    }

    a:hover {
      color: white;
    }

    a:hover::before {
      transform: translateX(0);
    }
  </style>
</head>

<body>
  <a>Hover me</a>
</body>

</html>
  • 带入文字

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8">
      <style>
        body {
          height: 100vh;
          display: flex;
        }
    
        a {
          text-decoration: none;
          margin: auto;
          border: 3px solid black;
          padding: 30px 80px;
          font-size: 30px;
          font-weight: bolder;
          color: #ff7777;
          position: relative;
          overflow: hidden;
        }
    
        a::before {
          content: "YEAH!";
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          background-color: #ff7777;
          color: white;
          transition: all 0.5s ease-out;
          transform: translateY(-100%);
    
          display: flex;
          align-items: center;
          justify-content: center;
        }
    
        a:hover::before {
          transform: translateY(0);
        }
      </style>
    </head>
    
    <body>
      <a>Hover me</a>
    </body>
    
    </html>
    
  • 伪闪光滑入

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8">
      <style>
        body {
          height: 100vh;
          background-color: #333;
          display: flex;
        }
    
        a {
          text-decoration: none;
          margin: auto;
          border: 3px solid black;
          padding: 30px 80px;
          font-size: 30px;
          font-weight: bolder;
          color: #ff7777;
          position: relative;
          overflow: hidden;
          transition: all 0.5s ease-out;
        }
    
        a::before {
          content: "";
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 50%;
          background-color: white;
          z-index: -1;
          transition: all 0.5s ease-out;
          transform: translateX(-100%) rotate(45deg);
        }
    
        a:hover {
          background-color: #ff7777;
          color: white;
        }
    
        a:hover::before {
          transform: translateX(100%) rotate(45deg);
        }
      </style>
    </head>
    
    <body>
      <a>Hover me</a>
    </body>
    
    </html>
    

c. 十字扩展(三维变换)

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    body {
      height: 100vh;
      display: flex;
    }

    a {
      text-decoration: none;
      margin: auto;
      border: 3px solid black;
      padding: 30px 80px;
      font-size: 30px;
      font-weight: bolder;
      color: #ff7777;
      position: relative;
      overflow: hidden;
      transition: all 1s ease-out;
    }

    a::before,
    a::after {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: #ff7777;
      z-index: -1;
      transition: all 0.5s ease-out;
    }

    a::before {
      transform: rotateX(90deg);
    }

    a::after {
      transform: rotateY(90deg);
    }

    a:hover {
      color: white;
    }

    a:hover::before {
      transform: rotateX(0);
    }

    a:hover::after {
      transform: rotateY(0);
    }
  </style>
</head>

<body>
  <a>Hover me</a>
</body>

</html>
  • 文字放大退出

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8">
      <style>
        body {
          height: 100vh;
          display: flex;
        }
    
        a {
          perspective: 500px;
          text-decoration: none;
          margin: auto;
          border: 3px solid black;
          padding: 30px 80px;
          font-size: 30px;
          font-weight: bolder;
          color: #ff7777;
          position: relative;
          overflow: hidden;
          transition: all 0.5s ease-out;
        }
    
        a::before {
          content: "Hover me";
          font-size: 30px;
          font-weight: bolder;
          color: white;
          position: absolute;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          background-color: #ff7777;
          z-index: -1;
          transition: all 0.5s ease-out;
          transform: translateZ(800px);
          display: flex;
          align-items: center;
          justify-content: center;
        }
    
        a:hover {
          color: white;
        }
    
        a:hover::before {
          transform: translateZ(0);
        }
      </style>
    </head>
    
    <body>
      <a>Hover me</a>
    </body>
    
    </html>
    
  • 切牌

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8">
      <style>
        body {
          height: 100vh;
          display: flex;
        }
    
        a {
          text-decoration: none;
          margin: auto;
          border: 3px solid black;
          padding: 30px 80px;
          font-size: 30px;
          font-weight: bolder;
          color: transparent;
          position: relative;
          overflow: hidden;
        }
    
        a::before,
        a::after {
          content: "Hover me";
          font-size: 30px;
          font-weight: bolder;
          color: white;
          position: absolute;
          top: 0;
          width: 100%;
          height: 100%;
          background-color: #ff7777;
          transition: all 0.5s ease-out;
          display: flex;
          align-items: center;
          justify-content: center;
        }
    
        a::before {
          left: 0;
        }
    
        a::after {
          left: -100%;
        }
    
        a::before {
          transform: rotateY(0deg) scale(1);
        }
    
        a::after {
          transform: rotateY(360deg) scale(0);
        }
    
        a:hover::before {
          left: 100%;
          transform: rotateY(360deg) scale(0);
          opacity: 0;
        }
    
        a:hover::after {
          left: 0;
          transform: rotateY(0) scale(1);
          opacity: 1;
        }
      </style>
    </head>
    
    <body>
      <a>Hover me</a>
    </body>
    
    </html>
    

d. 点入后放大

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    body {
      height: 100vh;
      display: flex;
    }

    a {
      text-decoration: none;
      margin: auto;
      padding: 30px;
      font-size: 30px;
      font-weight: bolder;
      color: #ff7777;
      position: relative;
      overflow: hidden;
      transition: all 0.5s ease-out 0.5s;
    }

    a::before,
    a::after {
      content: "";
      position: absolute;
      top: 50%;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      transform: translateY(-50%);
      background-color: transparent;
      z-index: -1;
      transition: all 0.5s ease-out;
    }

    a::before {
      left: 0;
      box-shadow: -100px 0 0 #ff7777;
    }

    a::after {
      right: 0;
      box-shadow: 100px 0 0 #ff7777;
    }

    a:hover {
      color: white;
      background-color: #ff7777;
    }

    a:hover::before {
      left: 50%;
      background-color: #ff7777;
      box-shadow: -30px 0 0 #ff7777;
      transform: translateX(-50%) translateY(-50%);
    }

    a:hover::after {
      right: 50%;
      background-color: #ff7777;
      box-shadow: 30px 0 0 #ff7777;
      transform: translateX(50%) translateY(-50%);
    }
  </style>
</head>

<body>
  <a>Hover me</a>
</body>

</html>

f. 取景框

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    body {
      height: 100vh;
      display: flex;
    }

    a {
      text-decoration: none;
      margin: auto;
      padding: 30px;
      font-size: 30px;
      font-weight: bolder;
      color: #ff7777;
      position: relative;
      transition: all 0.5s ease-out 0.5s;
    }

    a::before,
    a::after {
      content: "";
      position: absolute;
      width: 30px;
      height: 30px;
      background-color: transparent;
      z-index: -1;
      transition: all 0.5s ease-out;
    }

    a::before {
      top: -5px;
      left: -5px;
      border-top: 3px solid #ff7777;
      border-left: 3px solid #ff7777;
    }

    a::after {
      right: -5px;
      bottom: -5px;
      border-right: 3px solid #ff7777;
      border-bottom: 3px solid #ff7777;
    }

    a:hover {
      color: white;
      background-color: #ff7777;
    }

    a:hover::before,
    a:hover::after {
      width: 100%;
      height: 100%;
    }
  </style>
</head>

<body>
  <a>Hover me</a>
</body>

</html>

0x03 动画与关键帧 animation & keyframes

(1)基本使用

  • 使用步骤:
    1. 定义 CSS 动画规则(即关键帧)
    2. 将该动画添加到需要动画的元素上
  • @keyframes identifier:定义关键帧
  • animation-name:通过名称使用相应的动画
  • animation-duration:动画持续时间
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    div {
      width: 100px;
      height: 100px;
      display: block;
      background-color: #ff7777;
    }

    div:hover {
      animation-name: moving;
      animation-duration: 3s;
    }

    @keyframes moving {
      0% {
        transform: translate(0);
      }

      30% {
        transform: translate(150px);
      }

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

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

</html>

(2)其他属性

  • animation-fill-mode:填充模式,设置 CSS 动画在执行之前和之后如何将样式应用于其目标(详解
    • noneforwardbackwardboth
  • animation-iteration-count:迭代次数,设置 CSS 动画重复执行次数
    • 取值 infinite 表示无限重复
  • animation-timing-function:时序函数,与 transition-timing-function 类似
  • animation-direction:动画方向
    • reverse:逆向
    • alternate:交替
    • alternate-reverse:逆向交替
  • animation-delay:延时

(3)缩写属性

animation: name duration ...args

  • ...args 表示其他属性,没有规定顺序

(4)案例:牛顿摆

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <style>
    body {
      height: 100vh;
      background-color: #333;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    div {
      display: flex;
      border-top: 10px solid white;
    }

    span {
      display: block;
      width: 3px;
      height: 300px;
      background-color: white;
      margin: 0 30px;
      position: relative;
      transform-origin: top;
    }

    span::before {
      content: '';
      position: absolute;
      left: 0;
      bottom: 0;
      width: 60px;
      aspect-ratio: 1;
      border-radius: 50%;
      background-color: white;
      transform: translateX(-50%);
    }

    span:first-child {
      animation: left 2s ease-in infinite;
    }

    span:last-child {
      animation: right 2s ease-in infinite;
    }

    @keyframes left {
      0% { transform: rotate(0deg); }
      25% { transform: rotate(60deg); }
      50% { transform: rotate(0deg); }
      100% { transform: rotate(0deg); }
    }

    @keyframes right {
      0% { transform: rotate(0deg); }
      50% { transform: rotate(0deg); }
      75% { transform: rotate(-60deg); }
      100% { transform: rotate(0deg); }
    }
  </style>
</head>

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

</html>

-End-

posted @ 2024-07-23 16:07  SRIGT  阅读(17)  评论(0编辑  收藏  举报