美文网首页前端开发笔记让前端飞前端开发那些事
CSS动画相关(打字动画、逐帧动画、环形路径平移)

CSS动画相关(打字动画、逐帧动画、环形路径平移)

作者: Bouc | 来源:发表于2018-11-28 22:36 被阅读66次

    一、 逐帧动画

      很多时候,我们需要一个很难只通过CSS属性来实现的动画,比如一个复杂的进度提示框,在这样场景下基于图片的逐帧动画才是王道。
      看到动画,你可能会想:[直接用GIF不就得了嘛,搞这么复杂的CSS干嘛]。不用GIF肯定是GIF有短板。呐,短板如下:

    • GIF颜色被限制在256色
    • 不能实现半透明效果
    • 无法在CSS层修改动画的参数,例如持续时间、循环次数等,GIF动画一旦生成这些参数就固定在文件内部,若想修改只能用PS等软件重新生成,可移植性虽好,但调试过程简直就是灾难
    解决方案
    假设我们将动画中的所有帧都合并到一张PNG图片中了, 兔斯基揉脸.png

    将其设置为background,通过改变background-position的值就可以显示出每一帧图片。

    代码

        <style>
            @keyframes loader {
                0% {
                    background-position: 0px 0%;
                }
                100%{
                    background-position: 0px -400%;
                }
            }
            div{
                width: 32px;
                height: 35px;
                background-image: url(http://www.web-tinker.com/share/兔斯基揉脸.png);
                animation: loader .4s steps(4) infinite;
            }
        </style>
    
        <body>
            <div></div>
        </body>
    

    注意点!
    animation中的steps()属性较为少见,与贝赛尔曲线不同的是steps()会根据你指定的步进数,把整个动画切分为多帧,而且整个动画会在帧与帧之间硬切,不会有任何插值处理

    效果

    动画

    二、 打字动画

    打字动画即让字符逐个显现,模拟出一种打字的效果,用等宽字体可以营造出一种终端命令行的感觉。
    CSS解决的思路是:让容器的宽度成为动画的主体,但仅适用于单行文本

    代码

    <style>
            @keyframes typing {
                from {
                    width: 0;
                }
            }
    
            @keyframes caret {
                50% {
                    border-color: currentColor;
                }
            }
    
            h1 {
                width: 15ch;
                overflow: hidden;
                white-space: nowrap;
                border-right: .05em solid;
                animation: typing 4s steps(15), caret 1s steps(1) infinite;
            }
        </style>
    
    <body>
        <h1 id="text">Ciger is a handsome boy</h1>
        <script>
            let text = document.getElementById('text');
            let len = text.textContent.length;
            text.style.width = len + 'ch';
            text.style.animationTimingFunction = `steps(${len}),steps(1)`;
          </script>
     </body>
    

    这里用h1标签包裹文字,设置一个默认宽度15ch,ch表示数字“0”的宽度,对于等宽字体来说,我们用ch单位来表达这个标题的长度,实际上就是字符的个数。这样写死宽度是不合理的,万一字符变多了还得改,于是设置标题宽度这我们得用到一点JS。

    <script>
            let text = document.getElementById('text');
            let len = text.textContent.length;
            text.style.width = len + 'ch';
            text.style.animationTimingFunction = `steps(${len}),steps(1)`;
    </script>
    

    这段JS获取了文本内容的长度,因我们单位用了ch,字符长度即宽度,然后设置其style

    画龙点睛的一步就是给他加上一个闪烁的光标,这里用了右边框来模拟光标效果,颜色为currentColor,这个属性的意思是“当前的标签所继承的文字颜色”,这样边框颜色就会自动与文字颜色保持一致。

    上两张效果图

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

    不知道大家有没有见过一些网站的404页面,在浩瀚的宇宙中心有一个环形轨道,一个个星球绕着这个轨道运转,而自身的角度不发生变化。
    类似的例子还有很多,下面是一个简化版本。用CSS让一副头像图片沿着环形路径动起来。

    代码

      <style>
            body {
                display: flex;
                align-items: center;
                justify-content: center;
                height: 100vh;
            }
    
            .round {
                width: 200px;
                height: 200px;
                border-radius: 100%;
                background: #6959CD;
                padding: 20px;
            }
    
            .move {
                width: 30px;
                height: 30px;
                margin: 0px auto;
                border-radius: 50%;
                animation: spin 5.5s infinite linear;
                transform-origin: 50% 100px;
            }
    
            .move>img {
                display: block;
                width: inherit;
                height: inherit;
                border-radius: 50%;
                animation: inherit;
                animation-direction: reverse;
            }
    
            @keyframes spin {
                to {
                    transform: rotate(1turn);
                }
            }
    </style>
    
    <div class="round">
        
            <div class="move">
                <img src="imgs/01.jpg" />
            </div>
    
            <div class="move" style="animation-delay: .5s;margin-top: -30px;">
                <img src="imgs/02.jpg" />
            </div>
          
    </div>
    

    关键点是 transform-origin 以及 animation-direction: reverse
    我们只设置了一个animation:spin,让其旋转一周。注意最外层的div,是一个圆形,直径是其宽/高度300px,所以半径为150px。
    若直接给图片添加
    animation:spin 3s infinite linear; transform-origin:50% 150px;
    这样不仅让头像沿着环形路径旋转,头像自身也会旋转,这不是我们要的效果。

    所以animation-direction发挥作用了,给头像加上,让它往相反的方向转回去,这样就抵消了,相当于没有旋转。

    效果

    沿着环形轨迹旋转

    相关文章

      网友评论

      本文标题:CSS动画相关(打字动画、逐帧动画、环形路径平移)

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