zoukankan      html  css  js  c++  java
  • 如何用纯 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
  • 相关阅读:
    题解 CF171G 【Mysterious numbers
    题解 P1157 【组合的输出】
    题解 P3955 【图书管理员】
    题解 P2036 【Perket】
    题解 CF837A 【Text Volume】
    题解 CF791A 【Bear and Big Brother】
    题解 CF747A 【Display Size】
    题解 P1332 【血色先锋队】
    题解 P2660 【zzc 种田】
    题解 P4470 【[BJWC2018]售票】
  • 原文地址:https://www.cnblogs.com/qixidi/p/10036036.html
Copyright © 2011-2022 走看看