zoukankan      html  css  js  c++  java
  • 前端实现动画

    通常在前端中,实现动画的方案主要有6种:

    • CSS3 transition;
    • CSS3 animation;
    • javascript直接实现;
    • .jQuery的animate()API;
    • requestAnimationFrame;
    • SVG(可伸缩矢量图形);
    • Canvas动画;

    首先,我们来搭一个基本结构框架:

    <style>
      div {
        position: relative;
        background: #999;
        width: 50px;
        height: 50px;
      }
     
        .animat{
     
        }
     
    </style>
     
    <body>
      <div class="animat"></div>
    </body>

    CSS3 transition

    transition是过度动画。但是transition只能在某个标签元素样式或状态改变时进行平滑的动画效果过渡,而不是马上改变。

     transition是渐变的意思,就是某个属性 从一个值逐渐变成另一个值,比如width:从50px,到200px

     基本表达式 transition: transition-property  transition-duration transition-timing-function transition-delay

    • transition-property :需要做缓动的属性,默认值为all,就表示所有可以缓动的属性都做缓动动画
    • transition-duration : 整个缓动动画的持续时间,比如1s 就是1秒
    • transition-timing-function : 缓动动画的呈现速度方式,默认值为ease,即 先慢再快再慢,还有linear(匀速)等其他方式
    • transition-delay : 延迟执行动画时间

    示例

    .animat{
               transition:width 2s;
               -moz-transition:width 2s; /* Firefox 4 */
               -webkit-transition:width 2s; /* Safari and Chrome */
               -o-transition:width 2s; /* Opera */
           }
    
           .animat:hover{
            width:300px;
        }

    完整代码:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style type="text/css">
            div
            {
                width:100px;
                height:100px;
                background:red;
                position:absolute;
    }
    
            }
            .animat{
               transition:width 2s;
               -moz-transition:width 2s; /* Firefox 4 */
               -webkit-transition:width 2s; /* Safari and Chrome */
               -o-transition:width 2s; /* Opera */
           }
    
           .animat:hover{
            width:300px;
        }
    </style>
    </head>
    <body>
       <div class='animat'></div>
    </body>
    </html>

    这个动画呈现效果是:当鼠标移动到div上的时候,执行width 改变动画。

    很多其他的一些属性也可以,比如left,opacity 等等,这里不做赘述。

    CSS3 animation

    语法:

    animation: name duration timing-function delay iteration-count direction;

    name:keyframe的名称,也就是定义了关键帧的动画的名称,这个名称用来区别不同的动画。
    duration:完成动画所需要的时间(2s 或者 2000ms)
    timing-function:完成动画的速度曲线
    delay:动画开始之前的延迟
    iteration-count:动画播放次数
    direction:是否轮流反向播放动画(normal:正常顺序播放,alternate下一次反向播放)如果把动画设置为只播放一次,则该属性没有效果。

    使用animation属性制作动画可以更加灵活的设置动画帧,通过不同keyframe(动画帧)的设置,实现很多优雅的效果,keyframe中的百分数是动画完成总时间的比例。
    animation是设置总的动画效果,而keyframe中设置上相应的动画名字,然后在keyframe中设置具体的动画效果。当然由于是css3的属性,仍然需要注意它的兼容性,加上必须的前缀。

    keyframes

    包含两部分,第一个是使用animation属性,第二部分是:用@keyframes定义动画

    示例

      .animat{
              animation: testAni 2s infinite alternate;
          }
          /*infinite表示动画一直循环播放*/
          /*alternate表示动画下一次反向播放*/
    
          @keyframes testAni {
            0% {
                width:100px;
            }
            
            30% {
             width:200px;
         } 
         
         100% {
              width: 500px;
        }
    }   

    0% 表示最开始,30%,表示整个动画时间的30%,  100% 表示结束, 

    中括号里面就是需要呈现动画的属性。

    注:动画优化:1)因为动画改变的太频繁,所以我们最好用position:absolute或fixed的方式把元素脱离文档流,避免频繁重绘;

                    2) 如果是定位属性:比如left,top等等,可以用transform:translate()的方式来替代,这样性能更好.

    注:transition适合于一次性的呈现动画,animation适合多次 或者需要控制中间过程的动画.

    javascript 直接实现动画

    其主要思想是通过setInterval或setTimeout方法的回调函数来持续调用改变某个元素的CSS样式以达到元素样式变化的效果。

    示例

    <body>
        <div id="animat"></div>
        <script>
            let elem = document.getElementById('animat');
            let left = 1;
            //获取某个元素的宽度:obj.offsetWidth;
            console.log(elem.offsetWidth); 
            let timer = setInterval(function(){
                let elemWidth=elem.offsetWidth;
                if(elemWidth<500){
                     //设置某个元素的宽度:obj.style.width;
                     elem.style.width=elemWidth+left+'px';
                     left ++; 
                 }else 
                 {
                    clearInterval(timer); 
                } },16); 
         </script> 
    </body>

    Jquery的animate()方法就是这种方式实现的。

    存在的问题

    javascript 实现动画通常会导致页面频繁性重排重绘,消耗性能,一般应该在桌面端浏览器。在移动端上使用会有明显的卡顿。

    Jquery的animate()

    jQuery animate() 方法用于创建自定义动画。

    语法:

    $(selector).animate({params},speed,callback);

    示例

    <!DOCTYPE html>
    <html>
    <head>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.js"></script>
    
    <script> 
    $(document).ready(function(){
      $("button").click(function(){
        var div=$("div");
        div.animate({height:'300px',opacity:'0.4'},"slow");
        div.animate({'300px',opacity:'0.8'},"slow");
        div.animate({height:'100px',opacity:'0.4'},"slow");
        div.animate({'100px',opacity:'0.8'},"slow");
      });
    });
    </script> 
    </head>
     
    <body>
    
    <button>开始动画</button>
    <div style="background:#98bf21;height:100px;100px;position:absolute;">
    </div>
    
    </body>
    </html>

    requestAnimationFrame

    requestAnimationFrame是另一种Web API,原理与setTimeout和setInterval类似,都是通过javascript持续循环的方法调用来触发动画动作。但是requestAnimationFrame是浏览器针对动画专门优化形成的APi,在性能上比另两者要好。

    通常,我们将执行动画的每一步传到requestAnimationFrame中,在每次执行完后进行异步回调来连续触发动画效果。

    示例

    <!DOCTYPE html>
    <html>
    <head>
        <title></title>
        <style type="text/css">
            * {
                margin:0;
                padding:0;
            }
            div {
                width: 100px;
                height: 100px;
                background: red;
            }
        </style>
    </head>
    <body>
        <div id="animat"></div>
        <script type="text/javascript">
        window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame ||
        window.msRequestAnimationFrame;
    
        let elem = document.getElementById("animat");
        let left = 0;
        //自动执行持续性回调
        requestAnimationFrame(step);
        //持续该改变元素位置
        function step() {
             let elemWidth=elem.offsetWidth;
                if(elemWidth<500){
                     //设置某个元素的宽度:obj.style.width;
                     elem.style.width=elemWidth+left+'px';
                     left ++; 
                     requestAnimationFrame(step);
                 }
        }
        </script>
    </body>
    </html>

    我们注意到,requestAnimationFrame只是将回调的方法传入到自身的参数中执行,而不是通过setInterval调用。

    什么是SVG? 

    SVG 指可伸缩矢量图形 (Scalable Vector Graphics)

    SVG 用来定义用于网络的基于矢量的图形
    SVG 使用 XML 格式定义图形
    SVG 图像在放大或改变尺寸的情况下其图形质量不会有所损失
    SVG 是万维网联盟的标准

    SVG 与诸如 DOM 和 XSL 之类的 W3C 标准是一个整体
    (SVG是HTML下的一个分支)

    Canvas动画

    canvas作为H5新增元素,是借助Web API来实现动画的。

    示例

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
        *{
            margin:0;
            padding:0;
        }
        </style>
    </head>
    <body>
        <canvas id="canvas" width="700" height="550"></canvas>
         <script type="text/javascript">
            let canvas = document.getElementById("canvas");
            //getContext()获取元素的绘制对象
            let ctx = canvas.getContext("2d");
            let width = 100;
            let timer = setInterval(function(){
                //clearRect不断清空画布并在新的位置上使用fillStyle绘制新矩形内容实现页面动画效果。
                ctx.clearRect(0,0,700,550);
                ctx.beginPath();
                ctx.fillStyle = red;
                ctx.fillRect(0,0,width,200);
                ctx.stroke();
                if(width>700){
                    clearInterval(timer);
                }
                width += 5;
            },16);
        </script>
    </body>
    </html>

    总结

    复杂的动画是通过一个个简单的动画组合实现的。基于兼容性问题,通常在项目中,一般在

        • 桌面端浏览器推荐使用javascript直接实现动画或SVG方式;
        • 移动端可以考虑使用CSS3 transition、CSS3 
          animation、Canvas或requestAnimationFrame方式**。
  • 相关阅读:
    面试题11:旋转数组的最小数字(C++)
    2019.9.20学习内容及随堂笔记
    2019.9.19学习内容及小结
    2019.9.18(day39)学习内容及小结
    2019.9.17学习内容及随堂笔记
    2019.9.16学习内容及随堂笔记
    2019.9.12(day36)学习内容及笔记
    2019.9.11学习内容及随堂笔记
    2019.9.10学习内容及随堂笔记
    2019.9.9学习内容及随堂笔记
  • 原文地址:https://www.cnblogs.com/sunmarvell/p/9376933.html
Copyright © 2011-2022 走看看