• 动画图标,如何实现页面中图标小动画,动画按钮 CSS JS


    动画图标,如何实现页面中图标小动画,动画按钮 CSS JS

    本文提到的例子的在线演示:
    https://kylebing.cn/test/scss/

    最近在看线上服务器的时候,无意间发现一个好玩的东西,看下图:

    一个是阿里云的动画

    https://www.aliyun.com/

    请添加图片描述

    一个是腾讯云的动画

    https://cloud.tencent.com/

    请添加图片描述

    还有一个是 vultr 的动画

    https://my.vultr.com/deploy/

    在这里插入图片描述

    现象

    因为我一直想实现这样的功能用于我日记应用的天气图标中,也一直没有思路,真是得来全不费工夫。
    所以我好好研究了一下它的实现方式,就只有两种,

    • 一种是通过 js
    • 一种是通过 css

    一、背景

    前两种实现方式都采用了逐帧动画的原理,底图是一张完整动画帧的拼接
    在这里插入图片描述
    在这里插入图片描述

    而 Vultr 的动画采用的是拆分部件的方式,将一个 SVG 图标拆分成了三块:阴影、中间层、上层。使用 SVG 的好处是随意缩放不会失真。

    在这里插入图片描述

    二、动画原理

    动画的实现就是变换呈现给用户的图片位置,来实现动画的展示,这也是所有视频和动画的原理。

    阿里云用的是通过 js 来变换画面位置
    请添加图片描述

    而腾讯云则用的 css 动画 animation 来实现的变换,我更喜欢 css 来实现的这种方式。更合理。效果更好。
    在这里插入图片描述

    Vultr 使用的也是 CSS 动画,不过只是简单的变换 transition

    .deploy__box 设置 :hover 响应样式,
    :hover 的时候,变换 .deploy__box 下面的 svg 下面的 .svg-illustration-shadow .svg-illustration-bottom .svg-illustration-top 相应的变换
    在这里插入图片描述
    在这里插入图片描述

    三、css 实现的动画,例子

    我最终实现的动画效果是这样的,接下来会详细解说是如何实现的:

    在这里插入图片描述
    在这里插入图片描述
    线上例子:

    https://kylebing.cn/test/scss/

    四、实现过程、原理: animation 一些特殊的设置

    关于动画的设置就不多说了,可以去百度 css animation 的使用。
    这里只说比较特殊的地方。

    1. 需要的素材

    一张逐帧动画的拼接图,比如腾讯云的 :
    在这里插入图片描述

    2. 确定变化的过程

    我们都已经知道 animation 动画是从一个状态到另一个状态的过渡,比如从 a 点到 b 点,默认情况下,这个过渡的过程是线性的,也就是均速的。
    以现在这个例子来说,就是从背景图的最上端变换到最下端,而变化的行程,就是

    图标高度 = 60px
    图标高度 x 图中的图标数量 =  60px * 16 = 960px
    
    • 1
    • 2

    也就是说,实现这个图标动画,需要图标背景从 0 0 变换到 0 -960px ,第一个数是横坐标值,第二个数是纵坐标值。

    既然这个变换过程是线性的,那它变化就是匀速的,也就会是这样:
    在这里插入图片描述

    3. 动画曲线

    那么如何改变上面这种样子呢,这就需要更深入的了解一下 css 动画中的动画曲线了。
    什么是动画曲线呢,就是在 1x1 的坐标系中,横坐标代表时间,纵坐标代表距离,表达距离与时间关系的这么一种线段,就是动画曲线。
    动画曲线有一些预置的,比如 linear easy-in-out 都代表着一种
    在这里插入图片描述
    你可以从这个网站中编辑自己需要的动画曲线:

    https://cubic-bezier.com

    上图中的动画效果就是图二的曲线。

    如果我们需要它逐帧的变换,那么它的曲线就应该是阶梯状的,像这样。

    在这里插入图片描述
    那么如何生成这种曲线呢, css 有它的方法,就是 steps(步数)
    在这里插入图片描述

    animation: icon-animation-enter 0.3s steps(16) forwards
    
    • 1

    此时的动画就不再是匀速的变换了,而是跟幻灯片似的,变换 16 次,这样也实现了动画图标背景的播放。

    4. 确定变换的次数

    比如腾讯云的背景是由 16 张图标合成的,也就是需要变换16次才算跟底片吻合。

    5. 这样就实现了例子的动画效果。

    五、完整代码

    先做图标的基础样式,比如做一个 60x60 的图标。这里我用 scss 写,为了方便定义一些变化的值,不了解的可以查看我之前写的 scss 教程,或者直接可以自己计算。

    完整的代码 html + css 代码是这样的

    <div class="container">
        <div class="header">Animation Icons - 腾讯云div>
        <div class="content">
            <div class="animation-icon lock">div>
            <div class="animation-icon money">div>
            <div class="animation-icon setup">div>
            <div class="animation-icon weixin">div>
            <div class="animation-icon cloud">div>
            <div class="animation-icon game">div>
        div>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    // 动画图标 ANIMATION ICONS
    
    $animation-duration: 0.3s; // 动画的间隔
    $icon-width: 60px;         // 图标的大小
    $frame-count: 16;          // 动画的帧率
    
    
    
    .animation-icon {
      width: $icon-width;
      height: $icon-width;
      background-position: top;
      background-size: 100% auto;
      background-repeat: no-repeat;
      @extend .animation-icon-leave; // 默认图标动画
      border: 1px solid transparent; // 这个只是为了标识鼠标悬停的位置,实际使用中删除即可
      &:hover {
        border: 1px solid #eee; // 这个只是为了标识鼠标悬停的位置,实际使用中删除即可
        @extend .animation-icon-enter // hover 时的图标动画
      }
    }
    
    // 背景图
    .lock{background-image: url(animation-icons/tencent.png);}
    .money{background-image: url(animation-icons/money.png);}
    .setup{background-image: url(animation-icons/setup.png);}
    .game{background-image: url(animation-icons/game.png);}
    .cloud{background-image: url(animation-icons/cloud.png);}
    .weixin{background-image: url(animation-icons/weixin.png);}
    
    
    // 进入动画
    .animation-icon-enter {
      -webkit-animation:icon-animation-enter $animation-duration steps($frame-count) forwards;
      animation: icon-animation-enter $animation-duration steps($frame-count) forwards
    }
    
    @-webkit-keyframes icon-animation-enter {
      0% {background-position: 0 0}
      to {background-position: 0 $icon-width * $frame-count * -1}
    }
    
    @keyframes icon-animation-enter {
      0% {background-position: 0 0}
      to {background-position: 0 $icon-width * $frame-count * -1}
    }
    
    // 离开动画
    .animation-icon-leave {
      -webkit-animation: icon-animation-leave $animation-duration steps($frame-count) forwards;
      animation: icon-animation-leave $animation-duration steps($frame-count) forwards
    }
    
    @-webkit-keyframes icon-animation-leave {
      0% {background-position: 0 $icon-width * $frame-count * -1}
      to {background-position: 0 0}
    }
    
    @keyframes icon-animation-leave {
      0% {background-position: 0 $icon-width * $frame-count * -1}
      to {background-position: 0 0}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
  • 相关阅读:
    『无为则无心』Python面向对象 — 58、类方法和静态方法
    【云原生】Docker 进阶 -- 阿里云服务器安装Docker Compose与初体验
    Appium自动化测试基础 — ADB常用命令(二)
    MySQL索引设计与选择
    python爬虫获取豆瓣前top250的标题(简单)
    谷粒商城实战笔记-34-前端基础-ES6-promise异步编排
    JAVA计算机毕业设计电影评分网站Mybatis+系统+数据库+调试部署
    Zongmu AVM车载环视 Android SDK 简介
    Redis入门(基础篇)笔记
    目标跟踪(1)SORT Windows实战+代码解析
  • 原文地址:https://blog.csdn.net/KimBing/article/details/126427977