美文网首页让前端飞个人收藏
css 中随机、打字等动画的实现

css 中随机、打字等动画的实现

作者: 贵在随心 | 来源:发表于2019-03-22 15:36 被阅读2次

    背景知识:css 动画规范
    @keyframes
    animation-name
    animation-duration
    animation-timing-function
    animation-delay
    animation-iteration-count
    animation-direction
    animation-play-state
    animation-fill-mode

    各属性的定义及用法:

    @keyframes: 用来指定CSS动画一次循环中,可以用百分比表示多个时间节点处的CSS属性变化,关键字 from 等于 0%,to 等于 100%。

    animation-name:指定@keyframes的名字,CSS加载时会应用该名字的@keyframes规则来实现动画。

    animation-duration:动画持续时间,默认是0表示无动画,单位可以设s秒或ms毫秒。

    animation-timing-function:动画播放方式,默认值ease,可以设linear,ease,ease-in,ease-out,ease-in-out,cubic-bezier(n,n,n,n),steps。

    animation-delay:延迟开始动画的时间,默认值是0,表示不延迟,立即播放动画。单位是s秒或ms毫秒。允许设负时间,意思是让动画动作从该时间点开始启动,之前的动画不显示。例如 -3s 使动画马上开始,但前 3 秒的动画被跳过。

    animation-iteration-count:动画循环播放的次数,默认值为1,即放完一遍后不循环播放。除数字外也可以设关键字 infinite 表示无限循环播放。

    animation-direction:动画播放的方向,可设normal,alternate,alternate-reverse。默认值是 normal 表示正常播放动画。alternate 表示轮转正反向播放动画,即动画会在奇数次(1,3,5…)正常播放,而在偶数次(2,4,6…)反向播放。alternate-reverse 正好反过来,奇数次反向播动画,偶数次正向播动画。

    animation-play-state:动画的状态,可设running,paused。默认值 running 表示正在播放动画,paused 表示暂停动画。

    animation-fill-mode:动画的时间外属性,可设 none,forwards,backwards,both。默认值 none 表示动画播完后,恢复到初始状态。forwards 当动画播完后,保持 @keyframes 里最后一帧的属性backwards 表示开始播动画时,应用 @keyframes 里第一帧的属性要看出效果,通常要设 animation-delay 延迟时间。both 表示 forwards 和 backforwards 都应用。

    接下来看看几个比较实用的动画实现吧:

    一、随机动画

    随机动画

    代码示例:

    <p class="loading">Loading…</p>
    
    @keyframes spin { to { transform: rotate(1turn); } }
    @keyframes radius { 50% { border-radius: 50%; } }
    @keyframes color { 33% { color: orange; } 66% { color: deeppink; } }
    @keyframes width { 50% { border-width: .3em; } }
    
    .loading:before {
        content: '';
        display: block;
        width: 4em;
        height: 4em;
        margin: 0 auto 1em;
        border: 1.5em solid;
        color: yellowgreen;
        box-sizing: border-box;
        animation: 1s spin, .7s radius, 1.1s color, 1.3s width;
        animation-timing-function: ease;
        animation-iteration-count: infinite;
    }
    
    .loading {
        margin: auto;
    }
    

    二、逐帧动画

    需要利用合成好的背景图,如下:


    loader 逐帧动画

    代码示例:

    <div class="loader">loading...</div>
    
    @keyframes loader {
        to {
            background-position: -800px 0;
        }
    }
    .loader {
        width: 100px;
        height: 100px;
        margin: auto;
        background: url("img/loader.png");
        /*隐藏文字*/
        overflow: hidden;
        text-indent: 999px;
        /*这里需要借助css3的控制时间的属性steps 阶跃函数,还有一个控制时间的属性的函数是贝塞尔曲线*/
        animation: 1s loader infinite steps(8);
    }
    

    这里用到了 steps 阶跃函数。
    语法:steps(n, start/end)
    第一个参数 n 是一个正整数,表示阶跃次数,
    第二个参数start或end,表示阶跃点,
    start 表示一开始就先进行阶跃,end 表示每阶段完成后再进行阶跃,
    默认值为 end。
    阶跃时间函数如下:

    阶跃start-end 阶跃时间曲线

    注意点:
    阶跃函数 steps 指的是 @keyframes 中各环节之间的时间变换函数,
    它并不是指整个 @keyframes 动画阶跃几次,
    如果需要每个环节到下一个环节只阶跃一次,可设置为 steps(1, start/end)。

    三、闪烁效果

    闪烁效果

    代码示例:

    <p class="blink1">最普通的闪烁效果:需要借助 steps() 阶跃函数,而且必须把关键帧设置在中间</p>
    <p class="blink2">平滑的闪烁效果:让关键帧设置在中间50%的位置</p>
    <p class="blink3">更加逼真的闪烁效果:需要把循环的次数翻倍且要交替出现,循环的时间设置为上面的一半</p>
    
    @keyframes blink-smooth1 {
        50% {
            color: transparent;
        }
    }
    
    @keyframes blink-smooth2 {
        to {
            color: transparent;
        }
    }
    
    p {
        padding: 1em;
        background: gold;
    }
    
    .blink1 {
        animation: 2s blink-smooth1 3 steps(1);
    }
    
    .blink2 {
        animation: 2s blink-smooth1 3;
    }
    
    .blink3 {
        animation: 1s blink-smooth2 6 alternate;
    }
    

    四、缓动效果

    缓动效果

    代码示例:

    <div class="ball">三次贝塞尔曲线</div>
    
    @keyframes bounce {
        60%, 80%, to {
            -webkit-transform: translateY(400px);
                -moz-transform: translateY(400px);
                -ms-transform: translateY(400px);
                    -o-transform: translateY(400px);
                    transform: translateY(400px);
        animation-timing-function: ease;
        }
        70% {-webkit-transform: translateY(300px);
            -moz-transform: translateY(300px);
            -ms-transform: translateY(300px);
                -o-transform: translateY(300px);
                transform: translateY(300px);}
        90% {
            -webkit-transform: translateY(360px);
                -moz-transform: translateY(360px);
                -ms-transform: translateY(360px);
                    -o-transform: translateY(360px);
                    transform: translateY(360px);
        }
    }
    .ball {
        width: 0;
        height: 0;
        padding: 2.5em;
        margin: auto;
        border-radius: 50%;
        /*at 50% 50% 是指圆心的位置*/
        background: radial-gradient(at 30% 30%, #fdd, red);
        animation: bounce 3s cubic-bezier(.215, .61, .355, 1) forwards;
    }
    body {
        min-height: 100vh;
        background: linear-gradient(skyblue, white 450px, yellowgreen 0);
    }
    

    这个效果是通过另一个阶跃函数:cubic-bezier 函数。
    主要是借用三次贝塞尔曲线来实现的。

    语法:cubic-bezier(x1, y1, x2, y2)
    (x1, y1) 表示第一个控制锚点的坐标,而 (x2, y2) 是第二个。
    曲线片断的两个端点分别固定在 (0,0) 和 (1,1),前者是整个过渡的起点(时间进度为零,动画进度为零),后者是终点(时间进度为 100%,动画进度为 100%)。
    固定曲线的两个端点并不是唯一的限制。两个控制锚点的 x 值都被限制在 [0, 1] 区间内(即我们无法把手柄在水平方向上移出这个图形范围)。这个限制并不是随便加上的。

    之前如 ease、linear、ease-in、ease-out、ease-in-out 这五个已有的效果都是 cubic-bezier 实现的,具体值如下:

    ease: cubic-bezier(0.25, 0.1, 0.25, 1.0)
    linear: cubic-bezier(0.0, 0.0, 1.0, 1.0)
    ease-in: cubic-bezier(0.42, 0, 1.0, 1.0)
    ease-out: cubic-bezier(0, 0, 0.58, 1.0)
    ease-in-out: cubic-bezier(0.42, 0, 0.58, 1.0)
    
    贝塞尔曲线

    这个动画并没有使用上面五个已有的动画,需要在 cubic-bezier 上调试出更加平滑的参数,如例子中的 cubic-bezier(.215, .61, .355, 1) 就是通过此网站调试的。

    五、状态平滑的动画

    状态平滑的动画

    代码示例:

    <div class="state-animation"></div>
    
    @keyframes state {
        to {
            background-position: 100% 100%;
        }
    }
    .state-animation { 
        width: 250px;
        height: 250px;
        background: url("img/timg.jpg");
        background-size: auto 100%;
        animation: state 10s linear infinite alternate;
        /*这里需要动画的animate-play-state属性*/
        animation-play-state: paused;
    }
    .state-animation:hover, .state-animation:focus {
        /*通过动画的播放状态来实现动画的平滑度*/
        animation-play-state: running;
    }
    

    六、打字动画

    打字动画

    代码示例:

    <h1>CSS is awesome!</h1>
    @keyframes typing {
        from {
            width: 0;
        }
    }
    
    @keyframes caret {
        50% {
            border-color: transparent;
        }
    }
    
    h1 {
        width: 15ch;
        overflow: hidden;
        white-space: nowrap;
        border-right: .05em solid;
        animation: typing 8s steps(15), caret 1s steps(1) infinite;
        font: bold 200% Consolas, Monaco, monospace;
    }
    

    这里引入了一个新的 css 单位 ch,它是以 0 的宽度为参考的,在等宽字体中,所有的字体与 0 的宽度是一样的;如果要加上闪烁的光标,需要借助右边框来实现。
    因单行的字符数量不定,css 维护不便,为了更易于维护,需要借助 javascript 来实现,如下代码:

    function $$(selector, context) {
        context = context || document;
        let elements = context.querySelectorAll(selector);
        return Array.prototype.slice.call(elements);
    }
    $$("h1").forEach(function(h1) {
        let len = h1.textContent.length, s = h1.style;
    
        s.width = len + "ch";
        s.animationTimingFunction = "steps(" + len + "),steps(1)";
    });  
    

    七、沿环形路径平移的动画

    环形动画

    代码示例:

    <div class="circular2">
        <img src="img/me.jpg" height="960" width="1280" alt="" />
    </div>
    
    /*为同一个元素指定多个变形原点*/
    @keyframes spin2 {
        from {
            transform: translateY(150px) translateY(-50%)
                        rotate(0turn)
                        translateY(-150px) translateY(50%)
                        rotate(1turn);
        }
        to {
            transform: translateY(150px) translateY(-50%)
                        rotate(1turn)
                        translateY(-150px) translateY(50%)
                        rotate(0turn);
        }
    }
    
    .circular2 {
        margin: 50px auto;
        width: 300px;
        height: 300px;
        background: gold;
        border-radius: 50%;
    }
    
    .circular2 img {
        display: block;
        margin: 20px auto;
        width: 50px;
        height: 50px;
        border-radius: 50%;
    }    
    

    更多动画效果可以参看 animate.css 库,这里有很多动画,可以参看源码。

    相关文章

      网友评论

        本文标题:css 中随机、打字等动画的实现

        本文链接:https://www.haomeiwen.com/subject/kkpzmqtx.html