JS实现帧动画

Posted arla

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS实现帧动画相关的知识,希望对你有一定的参考价值。

JS实现帧动画的原理

  1. 如果有多张帧图片,用一个image标签去承载图片,然后定时改变image的src属性(不推荐,相当于请求了多张图片,会发送多个http请求)
  2. 把所有动画关键帧绘制在一张图片里,把图片作为元素的backgroud-image,定时改变元素的background-position属性(推荐,只有一个http请求)

因为项目的要求,轮播图的第一张需要用n张图片实现一款动画,我这里用到的是第一种方法。。

首先思考一下,要实现动画必定要用到定时器了,既然有n张图那么一要用到for循环了。下面我要说说我在for循环和定时器上踩过的坑。
下面是html

<img src="" class="part1_pic_01_1" id="Jdove"/>

 

下面是js:


var storyboard = ["1_00000.png", "1_00001.png", "1_00002.png", "1_00003.png", "1_00004.png", "1_00005.png", "1_00006.png", "1_00007.png", "1_00008.png", "1_00009.png", "1_00010.png", "1_00011.png", "1_00012.png", "1_00013.png", "1_00014.png", "1_00015.png", "1_00016.png", "1_00017.png", "1_00018.png", "1_00019.png", "1_00020.png", "1_00021.png", "1_00022.png", "1_00023.png", "1_00024.png", "1_00025.png", "1_00026.png", "1_00027.png", "1_00028.png", "1_00029.png", "1_00030.png", "1_00031.png", "1_00032.png", "1_00033.png", "1_00034.png", "1_00035.png", "1_00036.png", "1_00037.png", "1_00038.png", "1_00039.png", "1_00040.png", "1_00041.png", "1_00042.png", "1_00043.png", "1_00044.png", "1_00045.png", "1_00046.png", "1_00047.png", "1_00048.png", "1_00049.png", "1_00050.png", "1_00051.png", "1_00052.png", "1_00053.png", "1_00054.png", "1_00055.png", "1_00056.png", "1_00057.png", "1_00058.png", "1_00059.png", "1_00060.png", "1_00061.png", "1_00062.png", "1_00063.png", "1_00064.png", "1_00065.png", "1_00066.png", "1_00067.png", "1_00068.png", "1_00069.png", "1_00070.png", "1_00071.png", "1_00072.png", "1_00073.png", "1_00074.png", "1_00075.png", "1_00076.png", "1_00077.png", "1_00078.png", "1_00079.png", "1_00080.png", "1_00081.png", "1_00082.png", "1_00083.png", "1_00084.png", "1_00085.png", "1_00086.png", "1_00087.png", "1_00088.png", "1_00089.png", "1_00090.png", "1_00091.png", "1_00092.png", "1_00093.png", "1_00094.png", "1_00095.png", "1_00096.png", "1_00097.png", "1_00098.png", "1_00099.png", "1_00100.png", "1_00101.png", "1_00102.png", "1_00103.png", "1_00104.png", "1_00105.png", "1_00106.png", "1_00107.png", "1_00108.png", "1_00109.png", "1_00110.png", "1_00111.png", "1_00112.png", "1_00113.png", "1_00114.png", "1_00115.png", "1_00116.png", "1_00117.png", "1_00118.png", "1_00119.png", "1_00120.png", "1_00121.png", "1_00122.png", "1_00123.png", "1_00124.png", "1_00125.png", "1_00126.png", "1_00127.png", "1_00128.png", "1_00129.png", "1_00130.png", "1_00131.png", "1_00132.png", "1_00133.png", "1_00134.png", "1_00135.png", "1_00136.png", "1_00137.png", "1_00138.png", "1_00139.png", "1_00140.png", "1_00141.png", "1_00142.png", "1_00143.png", "1_00144.png", "1_00145.png", "1_00146.png", "1_00147.png", "1_00148.png", "1_00149.png", "1_00150.png", "1_00151.png", "1_00152.png", "1_00153.png", "1_00154.png", "1_00155.png", "1_00156.png", "1_00157.png", "1_00158.png", "1_00159.png", "1_00160.png", "1_00161.png", "1_00162.png", "1_00163.png", "1_00164.png", "1_00165.png", "1_00166.png", "1_00167.png", "1_00168.png", "1_00169.png", "1_00170.png", "1_00171.png", "1_00172.png", "1_00173.png", "1_00174.png", "1_00175.png", "1_00176.png", "1_00177.png", "1_00178.png", "1_00179.png", "1_00180.png", "1_00181.png", "1_00182.png", "1_00183.png", "1_00184.png", "1_00185.png", "1_00186.png", "1_00187.png", "1_00188.png", "1_00189.png", "1_00190.png", "1_00191.png", "1_00192.png", "1_00193.png", "1_00194.png", "1_00195.png", "1_00196.png", "1_00197.png", "1_00198.png", "1_00199.png", "1_00200.png", "1_00201.png", "1_00202.png", "1_00203.png", "1_00204.png", "1_00205.png", "1_00206.png", "1_00207.png", "1_00208.png", "1_00209.png", "1_00210.png", "1_00211.png", "1_00212.png", "1_00213.png", "1_00214.png", "1_00215.png", "1_00216.png", "1_00217.png", "1_00218.png", "1_00219.png", "1_00220.png", "1_00221.png", "1_00222.png", "1_00223.png", "1_00224.png", "1_00225.png", "1_00226.png", "1_00227.png", "1_00228.png", "1_00229.png", "1_00230.png", "1_00231.png", "1_00232.png", "1_00233.png", "1_00234.png", "1_00235.png", "1_00236.png", "1_00237.png", "1_00238.png", "1_00239.png", "1_00240.png", "1_00241.png", "1_00242.png", "1_00243.png", "1_00244.png", "1_00245.png", "1_00246.png", "1_00247.png", "1_00248.png", "1_00249.png", "1_00250.png", "1_00251.png", "1_00252.png", "1_00253.png", "1_00254.png", "1_00255.png", "1_00256.png", "1_00257.png", "1_00258.png", "1_00259.png", "1_00260.png", "1_00261.png", "1_00262.png", "1_00263.png", "1_00264.png", "1_00265.png", "1_00266.png", "1_00267.png", "1_00268.png", "1_00269.png", "1_00270.png", "1_00271.png", "1_00272.png", "1_00273.png", "1_00274.png", "1_00275.png", "1_00276.png", "1_00277.png", "1_00278.png", "1_00279.png", "1_00280.png", "1_00281.png", "1_00282.png", "1_00283.png", "1_00284.png", "1_00285.png", "1_00286.png", "1_00287.png", "1_00288.png", "1_00289.png", "1_00290.png", "1_00291.png", "1_00292.png", "1_00293.png", "1_00294.png", "1_00295.png", "1_00296.png", "1_00297.png", "1_00298.png", "1_00299.png", "1_00300.png", "1_00301.png", "1_00302.png", "1_00303.png", "1_00304.png", "1_00305.png", "1_00306.png", "1_00307.png", "1_00308.png", "1_00309.png", "1_00310.png", "1_00311.png", "1_00312.png", "1_00313.png", "1_00314.png", "1_00315.png", "1_00316.png", "1_00317.png", "1_00318.png", "1_00319.png", "1_00320.png", "1_00321.png", "1_00322.png"]; var st;

for(var i=0;i<storyboard.length;i++){ (function(i){ var img = storyboard[i]; st = setTimeout(function(i) { $("#Jdove").attr("src","img/index/"+img); }, 350*i); })(i); }

看效果的话是没什么问题。但是在切换轮播图的时候就出现问题了。当这些帧动画没有执行完就切换到其他轮播图再切换回来到第一张的时候,就会执行两遍for循环,导致同时执行两遍帧动画,使得动画混乱。所以我们就要清除定时器。 实际上,for循环很快,上述代码类似于同时启动n个定时器,因此无法清除定时器,因此我用到了第二种方法。

function frameAnimation() {
        var storyboard = ["1_00000.png", "1_00001.png", "1_00002.png", "1_00003.png", "1_00004.png", "1_00005.png", "1_00006.png", "1_00007.png", "1_00008.png", "1_00009.png", "1_00010.png", "1_00011.png", "1_00012.png", "1_00013.png", "1_00014.png", "1_00015.png", "1_00016.png", "1_00017.png", "1_00018.png", "1_00019.png", "1_00020.png", "1_00021.png", "1_00022.png", "1_00023.png", "1_00024.png", "1_00025.png", "1_00026.png", "1_00027.png", "1_00028.png", "1_00029.png", "1_00030.png", "1_00031.png", "1_00032.png", "1_00033.png", "1_00034.png", "1_00035.png", "1_00036.png", "1_00037.png", "1_00038.png", "1_00039.png", "1_00040.png", "1_00041.png", "1_00042.png", "1_00043.png", "1_00044.png", "1_00045.png", "1_00046.png", "1_00047.png", "1_00048.png", "1_00049.png", "1_00050.png", "1_00051.png", "1_00052.png", "1_00053.png", "1_00054.png", "1_00055.png", "1_00056.png", "1_00057.png", "1_00058.png", "1_00059.png", "1_00060.png", "1_00061.png", "1_00062.png", "1_00063.png", "1_00064.png", "1_00065.png", "1_00066.png", "1_00067.png", "1_00068.png", "1_00069.png", "1_00070.png", "1_00071.png", "1_00072.png", "1_00073.png", "1_00074.png", "1_00075.png", "1_00076.png", "1_00077.png", "1_00078.png", "1_00079.png", "1_00080.png", "1_00081.png", "1_00082.png", "1_00083.png", "1_00084.png", "1_00085.png", "1_00086.png", "1_00087.png", "1_00088.png", "1_00089.png", "1_00090.png", "1_00091.png", "1_00092.png", "1_00093.png", "1_00094.png", "1_00095.png", "1_00096.png", "1_00097.png", "1_00098.png", "1_00099.png", "1_00100.png", "1_00101.png", "1_00102.png", "1_00103.png", "1_00104.png", "1_00105.png", "1_00106.png", "1_00107.png", "1_00108.png", "1_00109.png", "1_00110.png", "1_00111.png", "1_00112.png", "1_00113.png", "1_00114.png", "1_00115.png", "1_00116.png", "1_00117.png", "1_00118.png", "1_00119.png", "1_00120.png", "1_00121.png", "1_00122.png", "1_00123.png", "1_00124.png", "1_00125.png", "1_00126.png", "1_00127.png", "1_00128.png", "1_00129.png", "1_00130.png", "1_00131.png", "1_00132.png", "1_00133.png", "1_00134.png", "1_00135.png", "1_00136.png", "1_00137.png", "1_00138.png", "1_00139.png", "1_00140.png", "1_00141.png", "1_00142.png", "1_00143.png", "1_00144.png", "1_00145.png", "1_00146.png", "1_00147.png", "1_00148.png", "1_00149.png", "1_00150.png", "1_00151.png", "1_00152.png", "1_00153.png", "1_00154.png", "1_00155.png", "1_00156.png", "1_00157.png", "1_00158.png", "1_00159.png", "1_00160.png", "1_00161.png", "1_00162.png", "1_00163.png", "1_00164.png", "1_00165.png", "1_00166.png", "1_00167.png", "1_00168.png", "1_00169.png", "1_00170.png", "1_00171.png", "1_00172.png", "1_00173.png", "1_00174.png", "1_00175.png", "1_00176.png", "1_00177.png", "1_00178.png", "1_00179.png", "1_00180.png", "1_00181.png", "1_00182.png", "1_00183.png", "1_00184.png", "1_00185.png", "1_00186.png", "1_00187.png", "1_00188.png", "1_00189.png", "1_00190.png", "1_00191.png", "1_00192.png", "1_00193.png", "1_00194.png", "1_00195.png", "1_00196.png", "1_00197.png", "1_00198.png", "1_00199.png", "1_00200.png", "1_00201.png", "1_00202.png", "1_00203.png", "1_00204.png", "1_00205.png", "1_00206.png", "1_00207.png", "1_00208.png", "1_00209.png", "1_00210.png", "1_00211.png", "1_00212.png", "1_00213.png", "1_00214.png", "1_00215.png", "1_00216.png", "1_00217.png", "1_00218.png", "1_00219.png", "1_00220.png", "1_00221.png", "1_00222.png", "1_00223.png", "1_00224.png", "1_00225.png", "1_00226.png", "1_00227.png", "1_00228.png", "1_00229.png", "1_00230.png", "1_00231.png", "1_00232.png", "1_00233.png", "1_00234.png", "1_00235.png", "1_00236.png", "1_00237.png", "1_00238.png", "1_00239.png", "1_00240.png", "1_00241.png", "1_00242.png", "1_00243.png", "1_00244.png", "1_00245.png", "1_00246.png", "1_00247.png", "1_00248.png", "1_00249.png", "1_00250.png", "1_00251.png", "1_00252.png", "1_00253.png", "1_00254.png", "1_00255.png", "1_00256.png", "1_00257.png", "1_00258.png", "1_00259.png", "1_00260.png", "1_00261.png", "1_00262.png", "1_00263.png", "1_00264.png", "1_00265.png", "1_00266.png", "1_00267.png", "1_00268.png", "1_00269.png", "1_00270.png", "1_00271.png", "1_00272.png", "1_00273.png", "1_00274.png", "1_00275.png", "1_00276.png", "1_00277.png", "1_00278.png", "1_00279.png", "1_00280.png", "1_00281.png", "1_00282.png", "1_00283.png", "1_00284.png", "1_00285.png", "1_00286.png", "1_00287.png", "1_00288.png", "1_00289.png", "1_00290.png", "1_00291.png", "1_00292.png", "1_00293.png", "1_00294.png", "1_00295.png", "1_00296.png", "1_00297.png", "1_00298.png", "1_00299.png", "1_00300.png", "1_00301.png", "1_00302.png", "1_00303.png", "1_00304.png", "1_00305.png", "1_00306.png", "1_00307.png", "1_00308.png", "1_00309.png", "1_00310.png", "1_00311.png", "1_00312.png", "1_00313.png", "1_00314.png", "1_00315.png", "1_00316.png", "1_00317.png", "1_00318.png", "1_00319.png", "1_00320.png", "1_00321.png", "1_00322.png"];

        var index = 0;

        function run() {
            $("#Jdove").attr("src", "img/zyl/" + storyboard[index]);
            index++;
            oTimer = setTimeout(run, 30);
            if(index >= storyboard.length) {
                index = storyboard.lengt - 1;
          //清除定时器 clearTimeout(oTimer); return false; } } run(); }

通过递归调用的方法实现循环调用。

  1. 递归是一种思想:类似于我们的计数器,开闭原则。
  2. 递归的实质就是函数自己调用自己。
  3. 递归注意点:递归必须有跳出条件,否则是死循环。

所以在调用定时器之前,加入一段清除定时器的代码就可以了。

clearTimeout(oTimer);

 






以上是关于JS实现帧动画的主要内容,如果未能解决你的问题,请参考以下文章

逐帧动画 两种实现方式 css和js

帧动画插件

使用vue学习three.js之创建动画-变形动画-使用MorphAnimMesh制作奔跑的小马动画

一起Talk Android吧(第四百八十五回:逐帧动画的代码实现方法)

window.requestAnimationFrame与Tween.js配合使用实现动画缓动效果

js动画与css3动画的区别