• 如何用纯 CSS 创作一个小球上台阶的动画


    效果预览

    在线演示

    按下右侧的“点击预览”按钮可以在当前页面预览,点击链接可以全屏预览。

    https://codepen.io/comehope/pen/PBGJwL

    可交互视频

    此视频是可以交互的,你可以随时暂停视频,编辑视频中的代码。

    请用 chrome, safari, edge 打开观看。

    https://scrimba.com/p/pEgDAM/cDMyyHv

    源代码下载

    本地下载

    每日前端实战系列的全部源代码请从 github 下载:

    https://github.com/comehope/front-end-daily-challenges

    代码解读

    定义 dom,容器中包含 5 个元素,代表 5 个台阶:

    <div class="loader">
        <span></span>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>
    

    居中显示:

    body {
        margin: 0;
        height: 100vh;
        display: flex;
        align-items: center;
        justify-content: center;
        background-color: black;
    }
    

    定义容器尺寸:

    .loader {
         7em;
        height: 5em;
        font-size: 40px;
    }
    

    画出 5 个台阶:

    .loader {
        display: flex;
        justify-content: space-between;
        align-items: flex-end;
    }
    
    .loader span {
         1em;
        height: 1em;
        background-color: white;
    }
    

    用变量让 5 个台阶从低到高排序:

    .loader span {
        height: calc(var(--n) * 1em);
    }
    
    .loader span:nth-child(1) {
        --n: 1;
    }
    
    .loader span:nth-child(2) {
        --n: 2;
    }
    
    .loader span:nth-child(3) {
        --n: 3;
    }
    
    .loader span:nth-child(4) {
        --n: 4;
    }
    
    .loader span:nth-child(5) {
        --n: 5;
    }
    

    为台阶增加转换排序方向的动画效果:

    .loader span {
        animation: sort 5s infinite;
    }
    
    @keyframes sort {
        0%, 40%, 100% {
            height: calc(var(--n) * 1em);
        }
    
        50%, 90% {
            height: calc(5em - (var(--n) - 1) * 1em);
        }
    }
    

    下面做小球的动画,用了障眼法,使 2 个同色小球的交替运动看起来就像 1 个小球在做往复运动。

    用伪元素画出 2 个小球:

    .loader::before,
    .loader::after {
        content: '';
        position: absolute;
         1em;
        height: 1em;
        background-color: white;
        border-radius: 50%;
        bottom: 1em;
    }
    
    .loader::before {
        left: 0;
    }
    
    .loader::after {
        left: 6em;
    }
    

    增加让小球向上运动的动画效果:

    .loader::before,
    .loader::after {
        animation: climbing 5s infinite;
        visibility: hidden;
    }
    
    .loader::after {
        animation-delay: 2.5s;
    }
    
    @keyframes climbing {
        0% {
            bottom: 1em;
            visibility: visible;
        }
    
        10% {
            bottom: 2em;
        }
    
        20% {
            bottom: 3em;
        }
    
        30% {
            bottom: 4em;
        }
    
        40% {
            bottom: 5em;
        }
    
        50% {
            bottom: 1em;
        }
    
        50%, 100% {
            visibility: hidden;
        }
    }
    

    在向上运动的同时向两侧运动,形成上台阶的动画效果:

    .loader::before {
        --direction: 1;
    }
    
    .loader::after {
        --direction: -1;
    }
    
    @keyframes climbing {
        0% {
            bottom: 1em;
            left: calc(3em - 2 * 1.5em * var(--direction));
            visibility: visible;
        }
    
        10% {
            bottom: 2em;
            left: calc(3em - 1 * 1.5em * var(--direction));
        }
    
        20% {
            bottom: 3em;
            left: calc(3em - 0 * 1.5em * var(--direction));
        }
    
        30% {
            bottom: 4em;
            left: calc(3em + 1 * 1.5em * var(--direction));
        }
    
        40% {
            bottom: 5em;
            left: calc(3em + 2 * 1.5em * var(--direction));
        }
    
        50% {
            bottom: 1em;
            left: calc(3em + 2 * 1.5em * var(--direction));
        }
    
        50%, 100% {
            visibility: hidden;
        }
    }
    

    最后,为上台阶的动作增加拟人效果:

    @keyframes climbing {
        0% {
            bottom: 1em;
            left: calc(3em - 2 * 1.5em * var(--direction));
            visibility: visible;
        }
    
        7% {
            bottom: calc(2em + 0.3em);
        }
    
        10% {
            bottom: 2em;
            left: calc(3em - 1 * 1.5em * var(--direction));
        }
    
        17% {
            bottom: calc(3em + 0.3em);
        }
    
        20% {
            bottom: 3em;
            left: calc(3em - 0 * 1.5em * var(--direction));
        }
    
        27% {
            bottom: calc(4em + 0.3em);
        }
    
        30% {
            bottom: 4em;
            left: calc(3em + 1 * 1.5em * var(--direction));
        }
    
        37% {
            bottom: calc(5em + 0.3em);
        }
    
        40% {
            bottom: 5em;
            left: calc(3em + 2 * 1.5em * var(--direction));
        }
    
        50% {
            bottom: 1em;
            left: calc(3em + 2 * 1.5em * var(--direction));
        }
    
        50%, 100% {
            visibility: hidden;
        }
    }
    

    大功告成!

    原文地址:https://segmentfault.com/a/1190000015686159
  • 相关阅读:
    鬼斧神工---计算机的开机启动过程
    微服务之日志落盘设计
    微服务架构设计
    一条SQL语句执行得很慢的原因有哪些?
    996:只要能活着就好,不管活得多么糟糕
    事务隔离性与隔离级别
    数据库悲观锁与乐观锁
    解决百度网盘(百度云)分享链接不存在失效、分享的文件已经被取消的问题
    宁撞金钟一下,不打破鼓三千,IT人要有志气,要进就进大的好的公司
    1430:家庭作业
  • 原文地址:https://www.cnblogs.com/qixidi/p/10036036.html
Copyright © 2020-2023  润新知