关键帧动画

关键帧动画在CSS3中其实是非常常用的,我们的页面如果全都是直来直去的,就会非常生硬。在老式的页面设计中,我们通常用JQuery实现一些简单的动画,但是其效果远远不能和CSS3动画相比,而且性能也非常差。CSS3中,我们可以通过指定关键帧的方式,定义更复杂的补间动画效果(当然,浏览器毕竟不是游戏引擎,这里所指的动画主要是UI设计这个层面的)。

加载中特效

这里我们直接做一个比较有趣的例子,它是一个页面的「加载中」提示,可能稍显复杂,但其实并不难。

加载中外部的圆框会逐渐扩大,并逐渐透明至消失,而中间的Loading字样则在不停的抖动,体现出页面加载不出来,自己也很着急的样子,引起使用者的共鸣。

注:这个动画录制的帧数太低,实际上非常流畅。

<div class="app">
    <div class="loading"></div>
    <div class="loading-txt">
        <span>Loading</span>
    </div>
</div>
@font-face {
    font-family: "Roboto-Regular";
    src: url("Roboto-Regular.ttf");
}

html {
    height: 100%;
}

body {
    background-image: radial-gradient(#75c9ff, #5aa4ff);
}

.loading {
    /*屏幕居中*/
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    /*画一个白色的圆圈*/
    width: 10rem;
    height: 10rem;
    border: 1rem solid #ffffff;
    border-radius: 50%;
    /*动画效果*/
    animation: 0.7s loading-anim infinite;
}
@keyframes loading-anim {
    0% {
        width: 8rem;
        height: 8rem;
    }
    100% {
        width: 12rem;
        height: 12rem;
        opacity: 0;
    }
}
.loading-txt {
    /*屏幕居中*/
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
    width: 10rem;
    height: 10rem;
    /*使用Flex布局使内部文字居中*/
    display:flex;
    align-items:center;
    justify-content:center;
    /*字体颜色*/
    color: #ffffff;
    font-family: Roboto-Regular, sans-serif;
    font-size: 1.6rem;
    text-shadow: 2px 2px 10px #ffffff;
    /*动画效果*/
    animation: 0.1s loading-txt-anim infinite;
}
@keyframes loading-txt-anim {
    0% {
        transform: translateX(1px);
    }
    50% {
        transform: translateX(-1px);
    }
    100% {
        transform: translateX(1px);
    }
}

这里我们就不用在意太多细节了,主要看@keyframes这个写法。该标签定义了一个关键帧动画,在其他CSS定义内,通过animation属性进行引用。

animation: 动画执行时间 | 关键帧动画名 | 播放属性,infinite表示循环,默认不循环

关键帧的定义其实非常简单,就是通过0%50%等定义一个动画周期内,各个关键帧的属性,浏览器会帮我们自动补间。

动画执行完成保持状态

上面代码中,我们动画的执行是infinite的,如果不是循环动画,你会发现动画执行完成后,页面上的元素又恢复为了初始状态。如果想保持动画执行完成时的状态,可以添加如下CSS属性:

animation-fill-mode: forwards;

动画的回调函数

我们的代码逻辑,有时候在时序上必须依赖动画效果执行完成的回调函数。用CSS实现动画时,可以使用transitionendanimationend这两个事件来监听渐变动画或是关键帧动画的执行完成状态。

<button id="anim-btn">Anim</button>
<button id="reset-btn">Reset</button>
<div class="test-block"></div>
.test-block {
    width: 100px;
    height: 100px;
    background-color: #ff0000;
}

.test-block-anim {
    animation: 1s transform-animation;
    animation-fill-mode: forwards;
}

@keyframes transform-animation {
    0% {
        transform: translateX(0);
    }
    100% {
        transform: translateX(100px);
    }
}
window.onload = function () {
    var btn = document.querySelector('#anim-btn');
    var reset = document.querySelector('#reset-btn');
    var block = document.querySelector('.test-block');

    btn.onclick = function () {
        block.classList.add('test-block-anim');
    };

    reset.onclick = function () {
        block.classList.remove('test-block-anim');
    };

    var callback = function () {
        console.log('动画执行完成了');
    };

    block.addEventListener('animationend', callback);
};

注意:这里千万不要用setTimeout()等方式来实现,用延时来保证回调时序是非常不靠谱的做法。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap