ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

cytoscape.js 动画反向播放:reverse() 方法原理与实战指南

cytoscape.js 动画反向播放:reverse() 方法原理与实战指南 数据可视化【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址https://gitcode.com/gh_mirrors/cy/cytoscape.js点击查看免费下载导读reverse()是 cytoscape.js 动画对象Animation的核心方法之一用于将正在执行或已经完成的动画瞬间反转方向让节点样式、位置、缩放或视图平移沿着原路径倒带回去。在交互式图可视化场景中它常用于实现展开/收起、放大/还原、高亮/取消高亮这类可往返切换的动效让同一段动画代码同时承载正向与反向两种表现。读完本文你将掌握reverse()的完整 API 用法、链式调用模式以及它在 src/animation.mjs 中进度取反 起终点互换的底层实现原理并学会与play()、rewind()、progress()等方法组合出健壮的往返动画。一、reverse()是什么核心作用与典型场景reverse()是每个通过eles.animation()或cy.animation()创建的Animation对象上的方法。它的作用非常直观把当前动画的方向反转——原本从起点到终点的动画调用后变成从当前进度向起点回放原本已经播放到终点的动画调用后会回到起点继续播放。典型应用场景包括开关型 UI 动效节点被选中时高亮放大取消选中时反向回到原始大小与颜色视图往返核心视图cy级动画先放大平移聚焦到某个区域再反向还原循环演示一组动画反复正放、倒放形成呼吸效果。官方文档给出了该方法的精炼示例见 reverse.md下面我们将从这段示例出发逐层展开。二、官方示例一次完整的正放 → 倒放流程原文档中的示例完整展示了一个动画从创建、播放、等待完成、再到反转重新播放的闭环流程var jAni cy.$(#j).animation({ style: { background-color: red, width: 75 }, duration: 1000 }); jAni .play() // start .promise(completed).then(function(){ // on next completed jAni .reverse() // switch animation direction .rewind() // optional but makes intent clear .play() // start again ; }) ;这段代码的执行顺序可以拆解为cy.$(#j)选中 id 为j的节点animation()创建一个时长为 1000ms 的动画目标是把background-color变为red、width变为75.play()开始正向播放.promise(completed)返回一个 Promise在动画完成事件触发时 resolve此处使用了.then()而非.promise(completed)文档中的promise(completed)语义二者等价详见下文 promise 一节完成回调中依次调用.reverse()把动画方向反转——此时进度已到 1反转后进度变为 0即起点与终点互换.rewind()将进度显式拨回 0让意图更明确源码中rewind()等价于progress(0)见 src/animation.mjs.play()重新播放此时动画从red/75变回原来的背景色与宽度。三个方法均返回动画对象自身this因此可以像示例中一样链式书写。三、源码级原理剖析reverse()到底做了什么reverse()的实现位于 src/animation.mjs其核心逻辑可以概括为一个取反 两组互换reverse: function(){ let _p this._private; let wasPlaying _p.playing; if( wasPlaying ){ this.pause(); // 1. 若正在播放先暂停 } _p.progress 1 - _p.progress; // 2. 进度取反 _p.started false; // 3. 标记为未启动交给动画循环重新驱动 let swap function( a, b ){ /* 交换 _p[a] 与 _p[b] */ }; swap( zoom, startZoom ); // 4a. 核心视图缩放起点/终点互换 swap( pan, startPan ); // 4b. 核心视图平移起点/终点互换 swap( position, startPosition ); // 4c. 元素位置起点/终点互换 // 4d. 样式起点/终点互换 if( _p.style ){ for( let i 0; i _p.style.length; i ){ let prop _p.style[ i ]; let name prop.name; let startStyleProp _p.startStyle[ name ]; _p.startStyle[ name ] prop; _p.style[ i ] startStyleProp; } } if( wasPlaying ){ this.play(); // 5. 若原状态在播放恢复播放 } return this; // 6. 返回自身支持链式调用 }3.1 进度取反progress 1 - progress动画的当前进度存储于内部私有字段_p.progress取值 01。反转即把进度映射为它的互补值播到 30% 时反转则从 70% 处继续倒放已播完1则回到 0。随后_p.started false告诉动画循环这是一个尚未启动的动画让循环按新进度重新插值计算。3.2 起终点互换position / pan / zoom这是reverse()的精妙之处。一个动画对象在创建时就固定了起点与终点两套数据见 src/animation.mjs元素动画记录startPosition创建时的位置与目标position核心cy级动画记录startPan、startZoom创建时的视图平移与缩放与目标pan、zoom。调用reverse()时代码通过swap()把二者互换于是终点变成了起点。正因为起终点被物理交换反转后的动画在后续播放时才能严格沿着原来的路径走回去而不是基于当前值重新插值。3.3 样式起终点互换startStyle与style样式属性的处理方式与位置一致。动画创建时getAnimationStartStyle()实现于 src/style/get-for-ele.mjs会为动画涉及的每个属性抓取元素当前计算样式作为起点存入_p.startStyle目标值则存在_p.style。reverse()遍历_p.style中每个属性把_p.style[i]与_p.startStyle[name]一一互换从而完成样式层的起终点交换。// 简化示意等价于 // 原 _p.style { width: 75, background-color: red } // 原 _p.startStyle { width: 原值, background-color: 原色 } // 互换后两者对调动画目标即变为还原。这正是官方示例中width从 75 能变回去的底层原因。3.4 播放状态保持与链式返回reverse()开头记录wasPlaying反转过程中先pause()避免动画循环在状态切换的半途中插值处理完毕后再按原状态恢复play()——若动画本就在播放反转后立即继续方向已反向若动画原本静止反转后保持静止等待你手动.play()。最后return this使reverse().rewind().play()这类链式调用得以成立。四、与reverse()配合的动画控制方法族理解reverse()离不开它的搭档方法它们共同定义在 src/animation.mjs 的Animation.prototype上。以下方法均返回动画对象自身可自由链式组合方法作用源码要点play()开始播放若进度已是 1 则自动回卷到 0autorewindsrc/animation.mjspause()暂停播放保留当前进度src/animation.mjsstop()停止并从动画队列移除便于清理与 GCsrc/animation.mjsrewind()进度拨回 0等价progress(0)src/animation.mjsfastforward()进度拨到 1等价progress(1)src/animation.mjsprogress(p)获取/设置进度播放中设置会自动暂停再恢复src/animation.mjstime(t)基于毫秒时间设置/读取进度progress t / durationsrc/animation.mjscompleted()判断进度是否为 1src/animation.mjspromise(type)返回 Promisetype取frame或completed默认src/animation.mjsapply()将动画直接应用到当前进度暂停态跳帧src/animation.mjs几点值得注意的细节play()的自动回卷播放完成后进度为 1再次play()会先把进度归 0。因此官方示例中reverse()后再rewind()更多是显式表达意图即使省略reverse()本身已将进度从 1 取反为 0promise(completed)回调在动画完成时触发对应_p.completes数组用于编排先放完、再反转的时序这正是官方示例的核心用法若需要每帧回调可传framestop()与内存如 stop.md 所述ani.stop()会把动画标记为stopped并从队列移除使动画帧计算更快已停止的动画可复用但未停止的动画会随其目标元素或核心实例一起驻留内存难以被垃圾回收。大量动画场景下记得清理。五、测试验证reverse()的行为契约仓库测试 test/collection-style.mjs 用两个用例锁定了reverse()的语义用例一ani.reverse()L1079-L1098var ani n1.style({ width: 100 }).animation({ style: { width: 200 }, duration: 100 }); return ani.play().promise().then(function(){ expect( ani.progress() ).to.equal(1); expect( parseFloat(n1.style().width) ).to.equal(200); // 正向完成width 200 ani.reverse(); return ani.play().promise(); }).then(function(){ expect( ani.progress() ).to.equal(1); expect( parseFloat(n1.style().width) ).to.equal(100); // 反向完成width 100 });该用例验证了动画从100播到200后reverse()再play()能精确回到100——证明起终点交换后动画严格沿原路径倒放。用例二ani.reverse() does not affect second animationL1100-L1136var a1 n1.animation({ style: { width: 100, height: 100 }, duration: 100 }); var a2 n1.animation({ position: { x: 1000, y: 1000 }, duration: 50 }); a2.play(); return a1.play().promise().then(function(){ return a1.reverse().play().promise(); }).then(function(){ expect( n1.position() ).to.deep.equal( p2 ); // a2 的位置动画不受 a1 反转影响 });该用例验证了reverse()的作用域隔离一个动画的反转只影响自身同元素上其他独立动画的进度与结果不受牵连节点最终位置仍由a2决定。六、实战建议与注意事项综合文档、源码与测试使用reverse()时有几点实践建议明确动画起点reverse()依赖创建动画时快照的起点数据startPosition/startPan/startZoom/startStyle。若在动画创建后手动修改了元素的位置或样式反转后的起点仍是创建时的快照值而非当前值配合promise(completed)编排时序需要播完再倒放时优先用 Promise 回调如官方示例或apply()精准跳帧避免在播放中途reverse()造成视觉突兀长动画场景及时stop()若动画不再需要如元素被移除或视图已切换调用ani.stop()让动画退出队列减少每帧检查量并允许回收内存链式调用自然流畅reverse()、rewind()、play()、progress()均返回动画对象可安全链式书写rewind()非必需但能提升代码可读性核心视图与元素通用reverse()对cy.animation({ pan, zoom })与eles.animation({ position, style })均生效两类起终点都已在源码中做了对应的 swap 处理。结语reverse()用极简的 API 背后承载了精巧的设计通过进度取反 起终点互换位置、视图、样式三层同时交换让一段动画天然具备往返播放能力。理解 src/animation.mjs 的实现再对照 test/collection-style.mjs 的契约用例你就能在交互式图应用中自如地设计高亮、聚焦、展开与还原等往返动效。相关的完整方法族文档可进一步查阅 play.md、pause.md、stop.md、progress.md 与 apply.md。赞分享数据可视化【免费下载链接】cytoscape.jsGraph theory (network) library for visualisation and analysis项目地址https://gitcode.com/gh_mirrors/cy/cytoscape.js点击查看免费下载相关推荐如何使用CSS实现动画反向播放效果从基础到高级技巧全解析如何使用CSS实现动画反向播放效果从基础到高级技巧全解析 CSS动画是现代网页设计中不可或缺的元素而掌握动画反向播放技术能为用户体验带来质的飞跃。在You前端示例工程CSS动画方向终极指南正向、反向、交替播放的完整解析CSS动画方向终极指南正向、反向、交替播放的完整解析 想要让你的网页动画更加生动有趣吗CSS动画方向控制正是实现这一目标的关键技术无论你是想创建弹跳的小球前端示例工程Cytoscape.js 元素动画完全指南eles.animate() 的 API 用法与底层实现原理Cytoscape.js 元素动画完全指南eles.animate 的 API 用法与底层实现原理 本文聚焦 Cytoscape.js 图库中 元素集合co数据可视化上一篇dapper-dot-net代码生成工具T4模板自动生成数据访问层下一篇dia版本发布流程确保稳定的模型更新创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表