animate.css源码分析--bounce(弹跳效果)

本文深入分析了animate.css中bounce动画的实现原理,包括关键的CSS属性如`animation-duration`、`animation-fill-mode`和`transform-origin`等,并通过时间轴梳理了动画过程。文章还探讨了使用ease-out和ease-in替换贝塞尔曲线来实现4次弹跳的可能性,并设计了一个新的弹跳动画方案。最后提供了animate.css的下载链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

     animate.css是一个不错CSS3预设动画库,是很好的CSS3动画学习资源,下面来剖析下bounce效果的实现原理,在此基础上实现自己的CSS动画。

     先从animate.css把bounce效果单独移出来,暂不考虑针对不同的浏览器的支持,测试浏览器为chrome,看一下效果。

<!DOCTYPE html>
<html>
<head>
    <title>bounce-source</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1, minimal-ui" />
    <style type="text/css">
        html {
            font: 100%/1.5 "Roboto", Verdana, sans-serif;
            color: #3d464d;
            background-color: #fff;
            -webkit-font-smoothing: antialiased;
            width: 100%;
            overflow: hidden-x;
            text-align: center;
        }
        .font-style{
            color: #f35626;
            background-image: -webkit-linear-gradient(92deg,#f35626,#feab3a);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            -webkit-animation: hue 10s infinite linear;
        }
        h1{
            margin-bottom: 1.5rem;
            font-size: 6rem;
            font-weight: 100;
            line-height: 1;
            letter-spacing: -.05em;
        }
        @-webkit-keyframes hue {
          from {
            -webkit-filter: hue-rotate(0deg);
          }

          to {
            -webkit-filter: hue-rotate(-360deg);
          }
        }
    </style>
    <style type="text/css">
        .animated {
          animation-duration: 1s;
          animation-fill-mode: both;
        }

        .animated.infinite {
          animation-iteration-count: infinite;
        }
        .bounce {
          animation-name: bounce;
          transform-origin: center bottom;
        }

        @keyframes bounce {
          from, 20%, 53%, 80%, to {
            animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
            transform: translate3d(0,0,0);
          }

          40%, 43% {
            animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
            transform: translate3d(0, -30px, 0);
          }

          70% {
            animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
            transform: translate3d(0, -15px, 0);
          }

          90% {
            transform: translate3d(0,-4px,0);
          }
        }
    </style>
</head>
<body>
    <header>
      <div>
       <span style="display: block;" class="bounce animated infinite"><h1 class="font-style">bounce</h1></span>
      </div>
    </header>
</body>
</html>

看下一些公共的属性

  1. animation-duration: 1s 指定动画延迟1S执行,整个动画过程为1S,可以根据实际情况调整;
  2. animation-fill-mode: both 指定动画填充模式为前后填充,bounce的动画等待和动画结束状态分别保持keyframes的第一帧和最后一帧状态;
  3. transform-origin: center bottom 指定动画执行的基点为中间下方,动画对象的弹跳基点,大概理解为重心在对象的中下位置;
  4. animation-iteration-count: infinite 指定动画执行次数,可以根据实际情况调整。

基本属性定义完成后,看下动画执行的具体过程

        @keyframes bounce {
          from, 20%, 53%, 80%, to {
            animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
            transform: translate3d(0,0,0);
          }

          40%, 43% {
            animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
            transform: translate3d(0, -30px, 0);
          }

          70% {
            animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
            transform: translate3d(0, -15px, 0);
          }

          90% {
            transform: translate3d(0,-4px,0);
          }
        }

看起来不够直观,先按时间轴整理下

        @keyframes bounce {
          0%, 20%{
            animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
            transform: translate3d(0,0,0);
          }

          40%, 43% {
            animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
            transform: translate3d(0, -30px, 0);
          }

          53%{
            animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
            transform: translate3d(0,0,0);
          }

          70% {
            animation-timing-function: cubic-bezier(0.755, 0.050, 0.855, 0.060);
            transform: translate3d(0, -15px, 0);
          }

          80%{
            animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
            transform: translate3d(0,0,0);
          }

          90% {
            transform: translate3d(0,-4px,0);
          }

          100% {
            animation-timing-function: cubic-bezier(0.215, 0.610, 0.355, 1.000);
            transform: translate3d(0,0,0);
          }

        }

这样看起来清晰多了,大体的过程可以用下图表示
bounce过程图

  • 0%- 53% 完成了第一次弹跳,高度为30px
  • 53%-80% 完成了第二次弹跳,高度为15px
  • 80%-100% 完成了第三次弹跳,高度为4px
  • 弹跳时间比例大概为5:3:2,高度比例大概为8:4:1
  • 弹跳上升阶段速度先快后慢,下降阶段速度先慢后快

上升
                  上升阶段速度贝塞尔曲线

下降
                  下降阶段速度贝塞尔曲线

关于 贝塞尔曲线可以看下另一篇CSS3 三次贝塞尔曲线(cubic-bezier)

思考

    能否用ease-out与ease-in分别代替上升与下降的过程,完成4次弹跳过程。

设计

  • 弹跳时间比例大概为9:5:3:2,高度比例大概为14:8:4:1,动画持续时间为1.5S
  • 0%- 47% 完成第一次弹跳,高度为42px
  • 47%-73% 完成第二次弹跳,高度为24px
  • 73%-89% 完成第三次弹跳,高度为12px
  • 89%-100% 完成第四次弹跳,高度为3px
        @keyframes bounce {
          0%, 15%, 47%, 73%,89%,100% {
            animation-timing-function: ease-out;
            transform: translate3d(0,0,0);
          }

          30%, 32% {
            animation-timing-function: ease-in;
            transform: translate3d(0, -42px, 0);
          }

          60% {
            animation-timing-function: ease-in;
            transform: translate3d(0, -24px, 0);
          }

          82% {
            animation-timing-function: ease-in;
            transform: translate3d(0, -12px, 0);
          }

          94% {
            animation-timing-function: ease-in;
            transform: translate3d(0,-3px,0);
          }
        }
<!DOCTYPE html>
<html>
<head>
    <title>bounce-demo</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="initial-scale=1, minimal-ui" />
    <style type="text/css">
        html {
            font: 100%/1.5 "Roboto", Verdana, sans-serif;
            color: #3d464d;
            background-color: #fff;
            -webkit-font-smoothing: antialiased;
            width: 100%;
            overflow: hidden-x;
            text-align: center;
        }
        .font-style{
            color: #f35626;
            background-image: -webkit-linear-gradient(92deg,#f35626,#feab3a);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            -webkit-animation: hue 10s infinite linear;
        }
        h1{
            margin-bottom: 1.5rem;
            font-size: 6rem;
            font-weight: 100;
            line-height: 1;
            letter-spacing: -.05em;
        }
        @-webkit-keyframes hue {
          from {
            -webkit-filter: hue-rotate(0deg);
          }

          to {
            -webkit-filter: hue-rotate(-360deg);
          }
        }
    </style>
    <style type="text/css">
        .animated {
          animation-duration: 1.5s;
          animation-fill-mode: both;
        }

        .animated.infinite {
          animation-iteration-count: infinite;
        }
        .bounce {
          animation-name: bounce;
          transform-origin: center bottom;
        }

        @keyframes bounce {
          0%, 15%, 47%, 73%,89%,100% {
            animation-timing-function: ease-out;
            transform: translate3d(0,0,0);
          }

          30%, 32% {
            animation-timing-function: ease-in;
            transform: translate3d(0, -42px, 0);
          }

          60% {
            animation-timing-function: ease-in;
            transform: translate3d(0, -24px, 0);
          }

          82% {
            animation-timing-function: ease-in;
            transform: translate3d(0, -12px, 0);
          }

          94% {
            animation-timing-function: ease-in;
            transform: translate3d(0,-3px,0);
          }
        }
    </style>
</head>
<body>
    <header>
      <div>
       <span style="display: block;" class="bounce animated infinite"><h1 class="font-style">bounce</h1></span>
      </div>
    </header>
</body>
</html>

附:animate.css动画库下载地址:https://daneden.github.io/animate.css/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值