iis服务器助手广告广告
返回顶部
首页 > 资讯 > 前端开发 > JavaScript >如何利用JS实现时间轴动画效果
  • 937
分享到

如何利用JS实现时间轴动画效果

2024-04-02 19:04:59 937人浏览 独家记忆
摘要

目录CSS动画什么是时间轴动画?动画对象动画函数思考总结css动画 在前端开发中,一些简单的动效往往是使用 css3 的 @keyframes 来实现的 ,如: .div1 {

css动画

前端开发中,一些简单的动效往往是使用 css3 的 @keyframes 来实现的 ,如:

.div1 {
    width: 100px;
    height: 100px;
    background: red;
    animation: changeColor 2s;
}
@keyframes changeColor {
    0% {background: red;}
    50% {background: yellow;}
    100% {background: blue;}
}

假如设定的时间是2s,那么 这段动画的描述是这样的:在2秒内,某元素的背景色由红色变为黄色,又变为蓝色了。

假定有这样一个需求:

一个动画共持续4秒,在0-2秒内 div1 从红色变为黄色再变为蓝色,div2 在2-4秒内宽度由100px变为200px。

.div1 {
    width: 100px;
    height: 100px;
    background: red;
    animation: changeColor 2s forwards;
}
@keyframes changeColor {
    0% {background: red;}
    50% {background: yellow;}
    100% {background: blue;}            
}
.div2 {
    width: 100px;
    height: 100px;
    background: pink;
    animation: changeWidth 4s forwards;
}
@keyframes changeWidth {
    0% {width: 100px} 
    50% {width: 100px} 
    100% {width: 200px}            
}

看起来好像也还行,那么 div1 在第1秒变色, div2 在2-5秒内变形, div3 在3-7秒内变色变形,div4在4-10秒内旋转...,然后这些一起构成了需求想要的动画效果。

这样的话我们要找出整个动画的总时长,然后每个div的运动时间算出相对总时间的百分比区域,然后设定 keyframe 动画。

到这里 keyframes 貌似就有些复杂度了,我们平时一直在用 keyframes,那么 keyframes 或者说动画的本质是什么?

由于人类视觉停留的原理,这样一张张图片连续展示就看起来像动画了,翻书动画或者显示器逐帧刷新显示都是利用了这个原理。在动画创作时,除了像素、2d动画还在逐帧绘制,大多数类型的动画都已在编辑时方便将帧转换为时间进行计算。

keyframes 作为一个高度定制化的产物,只是在名称上对“帧”这个概念进行了保留,它对单个元素的动画编辑是简单方便的。
但通过示例二就可以看出,它没有对多元素组合动画进行针对性的设计,代码上 div1 和 div2 是没有逻辑关系表现的 (虽然在最终运行时会进行组合,即页面上的多数动画是维护在一个计时器里执行的。),它们没有统一的时间轴,没有父级包裹,要实现这些,需要编码者自己维护。

什么是时间轴动画?

对有过视频剪辑经验的人来说,视频剪辑的核心工具:基于时间轴的多轨视频编辑器是极为高效和方便的,它实现了对多个动画/特效片段的整合,称为时间轴动画。我们可以基于此实现一个简易的js版本来针对多元素长时间的动画需求。

如图所示,整个视频由多段小动画交错拼合而成,公用一个时间轴,由此构成了整个视频。

类比到前端,我们也可以用类似的方法,以时间轴为基准,整合多个动画片段。

我们可以有以下思路:

先创建一个obj对象作为参数,我们称作 “动画对象”,它是整个动画过程的描述。
再创建一个执行动画的函数,我们称作 ”动画函数“,它接受”动画对象“和一个回调函数(动画结束时执行)作为参数。
接下来就进入代码实现:

动画对象

我们首先看以下代码:

var anim = [ 
    { // 动画对象,可以多个
        dom: document.getElementById('a1'), // dom对象
        anim: [ // 动画数组,里面可为多个对象
            {
                style: 'height', 
// 要改变的样式名称如width,height

                from: '10rem', // 样式的起始值要和to保持一致
                to: '20rem', // 样式的目标值要和from保持一致
                start: 0, // 开始时间 毫秒
                end: 100, // 结束时间 毫秒
            },
            {
                style: 'width',
                from: '10rem',
                to: '20rem',
                start: 100,
                end: 200,
            },
            {
                style: 'transfORM',
                from: 'rotate(20deg)',
                to: 'rotate(40deg)',
                start: 0,
                end: 2000,
            }                        
        ]
    },
    {
        dom: document.getElementById('a2'),
        anim: [
            {
                style: 'background',
                from: 'rgba(0.0, 0.0, 0.0, 1)',
                to: 'rgba(255, 0, 100, 0.5)',
                start: 0,
                end: 3000,
            }
        ]
    },
];
timeLineAnim(anim, function () {
    console.log('animation finished');
});

anim 对象里清晰的描述了每个对象有几个动画,每个动画是怎么进行的。
然后 anim 对象作为一个参数传入了 timeLineAnim 中,在实际执行中它会进行如下操作:

div1在0.1秒内高度从 10rem 变为了 20rem,接着变宽,同时前2秒内还在旋转。

div2在0-3秒内颜色由rgba(0, 0, 0, 1) 变为rgba(255, 0, 100, 0.5)。

在3秒后,动画结束,控制台打出了 animation finished。

它的效果如下图所示:

动画函数

实现这个动画函数,首先简单构思下思路:1:将参数 anim 中的 from、to 的数字提取出来,便于计算。
2:开启 requestAnimationFrame,根据时间间隔和动画参数 anim 计算出当前帧的 css,并赋到对应的 dom 元素上。
3:在最后一个动画结束后,关闭requestAnimationFrame,并执行回调函数。

现在就进入编码阶段:在以上思路的基础上,我们在具体实现的过程中,通过 timeCount 来判断动画是否结束,使用 cssText 进行样式的赋值。

function timeLineAnim(arr, cb) {
    
    function initData(obj) {
        var reg = /[\d\.]+/g;
        var numArrFrom = obj.from.match(reg);
        var numArrTo = obj.to.match(reg);
        if (!numArrFrom || !numArrTo || numArrFrom.length == 0 || numArrTo.length == 0 || numArrFrom.length != numArrTo.length) {
            console.warn('数据输入错误');
        }
        for (var i = 0; i < numArrFrom.length; i++) {
            numArrFrom[i] = parseFloat(numArrFrom[i]);
            numArrTo[i] = parseFloat(numArrTo[i]);
        }
        var strArr = obj.from.split(reg);
        if (numArrFrom.length <= 0) { return; };
        animCount++;
        return {
            strArr: strArr,
            numArrFrom: numArrFrom,
            numArrTo: numArrTo,
            totalLength: strArr.length + numArrFrom.length,
            isEnd: false,
        }
    }

    function setCss(obj, timeCount) {
        var styleStr = '';
        var tempCount = animCount;
        // 将对象的多个动画,根据时间计算出样式,并合并
        for (var i = 0; i < obj.anim.length; i++) {
            var target = obj.anim[i];
            if (timeCount > target.start && !target.initData.isEnd) {
                // 根据起止时间 计算出当前动画进度
                var percent = (timeCount - target.start) / (target.end - target.start);
                if (percent >= 1) {
                    percent = 1;
                    target.initData.isEnd = true;
                    tempCount--;
                }
                styleStr += getValue(percent);
            }
        }
        obj.dom.style.cssText += ';' + styleStr;
        animCount = tempCount;
        // 这里进行单个动画每帧样式的生成,这里是匀速运动
        function getValue(percent) {
            var numFrom = target.initData.numArrFrom;
            var numTo = target.initData.numArrTo;
            var arr = [];
            for (var i = 0; i < numFrom.length; i++) {
                arr.push(numFrom[i] + (numTo[i] - numFrom[i]) * percent);
            }
            var numIndex = 0;
            var strIndex = 0;
            var turnForNum = false;
            var str = target.style + ':';
            for (var i = 0; i < target.initData.totalLength; i++) {
                if (turnForNum) {
                    str += arr[numIndex];
                    numIndex++;
                    turnForNum = false;
                }
                else {
                    str += target.initData.strArr[strIndex];
                    strIndex++;
                    turnForNum = true;
                }
            }
            return str + ';';
        }
    }

    // 主体逻辑: 初始化数据、帧动画、动画结束执行回调
    var animCount = 0;
    for (var i = 0; i < arr.length; i++) {
        for (var j = 0; j < arr[i].anim.length; j++) {
            arr[i].anim[j].initData = initData(arr[i].anim[j]);
        }
    }
    this.timer && cancelAnimationFrame(this.timer);
    var _this = this;
    (function animate(timeCount) {
        if (animCount > 0) {
            for (var i = 0; i < arr.length; i++) {
                setCss(arr[i], timeCount);
            }
            _this.timer = requestAnimationFrame(animate);
        }
        else {
            cancelAnimationFrame(_this.timer);
            cb && cb();
        }
    })();
}

伸手党可直接复制运行。至此,一个基于时间轴的简易动画函数就完成了,不到100行的代码就可以使你愉快的使用声明式的方式编辑时间轴动画。
此外,在getValue阶段,你还可以根据自己的需求搭配不同的运动曲线函数,丰富动画的功能。

由于参数是类JSON的,因此如果需要更进一步的话,你完全可以制作一个UI界面来可视化的生成动画参数,从而方便非程序员从业者使用。

思考

开头的部分讲述了市面上少部分动画如2d像素类,2d动画的制作仍然是以帧来进行的。

而无论在 keyframes 里 还是 本文给出的 timeLineAnim 函数 都是以 时间来进行设计的。

那么:如果我们改成用帧来进行计算和制作会如何呢?有什么优缺点吗?欢迎评论区讨论。

总结

到此这篇关于如何利用JS实现时间轴动画效果的文章就介绍到这了,更多相关JS时间轴动画内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: 如何利用JS实现时间轴动画效果

本文链接: https://www.lsjlt.com/news/152838.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何利用JS实现时间轴动画效果
    目录css动画什么是时间轴动画?动画对象动画函数思考总结css动画 在前端开发中,一些简单的动效往往是使用 css3 的 @keyframes 来实现的 ,如: .div1 { ...
    99+
    2022-11-13
  • JS如何实现时间轴自动播放
    这篇文章主要为大家展示了“JS如何实现时间轴自动播放”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“JS如何实现时间轴自动播放”这篇文章吧。最近实现了一个这样的效果,点击播放按钮,时间轴开始播放,...
    99+
    2023-06-20
  • js如何实现动态显示时间效果
    这篇文章给大家分享的是有关js如何实现动态显示时间效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。示例代码如下:<!DOCTYPE HTML> ...
    99+
    2022-10-19
  • js定时器怎么实现动画效果
    这篇文章将为大家详细讲解有关js定时器怎么实现动画效果,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1.向下滑动<!DOCTYPE html> &l...
    99+
    2022-10-19
  • 如何使用JS时间控制实现动态效果
    这篇文章主要介绍了如何使用JS时间控制实现动态效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。如下所示:<script> &n...
    99+
    2022-10-19
  • CSS3如何实现时间轴特效
    小编给大家分享一下CSS3如何实现时间轴特效,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!最近打开电脑就能看到极客学院什么新用户vip免费一个月,就进去看看咯,这...
    99+
    2023-06-08
  • 使用JavaScript 实现时间轴与动画效果的示例代码(前端组件化)
    目录代码整理JavaScript 中的 “帧”实现“帧”的方法1. setInterval2. setTimeout3. requestAnimationFrame实现 Timeli...
    99+
    2022-11-12
  • Android控件之使用ListView实现时间轴效果
     实现思路: 该View是通过ListView实现的,通过实体两个字段内容content和时间time来展示每个ListItem 时间轴是使用上面一条线(20dp)和...
    99+
    2022-06-06
    listview Android
  • 使用CSS3怎么实现一个时间轴效果
    这篇文章将为大家详细讲解有关使用CSS3怎么实现一个时间轴效果 ,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。什么是csscss是一种用来表现HTML或XML等文件样式的计算机语言,主要是用...
    99+
    2023-06-08
  • 怎么使用js实现动画效果
    这篇文章主要介绍“怎么使用js实现动画效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么使用js实现动画效果”文章能帮助大家解决问题。1.动画原理      &nb...
    99+
    2023-07-05
  • js如何通过Date对象实现倒计时动画效果
    小编给大家分享一下js如何通过Date对象实现倒计时动画效果,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!js通过Date对象实...
    99+
    2022-10-19
  • WPF实现动画效果(三)之时间线(TimeLine)
    WPF动画效果系列 WPF实现动画效果(一)之基本概念 WPF实现动画效果(二)之From/To/By 动画 WPF实现动画效果(三)之时间线(TimeLine) WPF实现动画效果...
    99+
    2022-11-13
  • 使用CSS3实现简单时间轴效果的案例
    这篇文章主要为大家展示了使用CSS3实现简单时间轴效果的案例,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带大家一起来研究并学习一下“使用CSS3实现简单时间轴效果的案例”这篇文章吧。css是什么意思css是一种用来表现HT...
    99+
    2023-06-06
  • jquery+swiper组件如何实现时间轴滑动年份tab切换效果
    这篇文章主要讲解了“jquery+swiper组件如何实现时间轴滑动年份tab切换效果”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“jquery+swiper组件如何实现时间轴滑动年份tab...
    99+
    2023-06-21
  • 怎么用jquery+swiper实现时间轴tab滑动切换显示效果
    这篇文章主要介绍“怎么用jquery+swiper实现时间轴tab滑动切换显示效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“怎么用jquery+swiper实现...
    99+
    2022-10-19
  • jquery+swiper组件实现时间轴滑动年份tab切换效果
    实现效果: 实现代码:需要配合swiper组件使用 Swiper基础演示地址: https://www.swiper.com.cn/demo/index.html HTML: ...
    99+
    2022-11-12
  • Android使用自定义View实现横行时间轴效果
    前言 本篇文章会说下如何使用并且要用麻烦的自定义 view 去实现时间轴效果,以及如何分析、实现自定义 view。 需要具备的知识:Paint、Canvas、自定义 view ...
    99+
    2022-06-06
    view 自定义view Android
  • JavaScript动画原理之如何使用js进行动画效果的实现
    目录前言1.动画原理2.动画函数的封装3.给不同元素添加定时器4.缓动动画原理5.给动画添加回调函数6.动画函数的使用写在最后前言 动画对于我们来说都不陌生,css里面就有很多动画,...
    99+
    2023-05-14
    js动画效果有哪些 js动画效果代码案例 javascript动画教程
  • 如何使用Jquery实现时间轴
    这篇文章将为大家详细讲解有关如何使用Jquery实现时间轴,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、纵向折叠时间轴1、js文件(jQuery.js或者jQuery...
    99+
    2022-10-19
  • 利用JavaScript实现放鞭炮动画效果
    目录前言制作思路代码实现构建鞭炮安排小兔上场点火爆炸效果添加音频前言 谈及过年,最先让人想到的就是,噼里啪啦的鞭炮声,小时候到了春节,点上一根香,把红色的鞭炮从那一排子里解出几个,放...
    99+
    2023-01-11
    JavaScript放鞭炮动画 JavaScript放鞭炮 JavaScript 动画
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作