共计 2112 个字符,预计需要花费 6 分钟才能阅读完成。
引子
继 Learn D3: Shapes 第六篇,只是英文翻译,可批改代码的局部用动态图片代替了,想要实时交互请浏览原文。
- 原文:Learn D3: Animation
- 版本:Published Mar 24, 2020
- Origin
- My GitHub
注释
与在纸上绘制的图形不同,计算机图形不用是动态的;就像弗兰肯斯坦的怪物一样,他们能够通过动画活过来!✨
下面的折线图逐渐显示。这个可有可无的成果,应该审慎应用,因为它会引起留神,但它至多强化了 x 代表工夫,并给一个本来干燥的图表带来了一丝悬念。
这里的代码相似于咱们后面看到的轴渲染:咱们抉择一个 SVG 门路元素,调用一个函数(reveal)来利用转换,最初将该元素嵌入 HTML 模板文本中。
在咱们进入技术细节之前,让咱们退一步,更全面地思考一下动画。
动画不是单个图形,而是随工夫变动的一 系列 图形。该序列能够示意为返回给定工夫 t 的图形的单元(或函数)。为简略起见,咱们通常应用惯例工夫,其中 t=0 是动画的开始,t=1 是完结。
咱们的单元实践上能够返回给定工夫 t 的 任何 图形,但工夫 t 的图形通常与工夫 t+ϵ 的图形类似。帧与帧之间的这种相似性有助于观众追随观看(在下面,仅 stroke-dasharray
属性设置动画;图形的其余部分放弃不变。)因而,间断动画通常由离散关键帧定义,两头帧由插值或补格生成。
来看看 stroke-dasharray
属性。它是两个逗号分隔的数字:第一个是虚线(dash)的长度,第二个是虚线之间的间隙长度。如果虚线长度为零,则该线将不可见;如果虚线的长度与直线一样长,那么直线将不会中断。通过调整虚线长度并使间隙至多与直线一样长,这样咱们能够管制画多少直线。咱们只须要两个关键帧:零虚线长度和线虚线长度。
为了辅助动画(以及其它用处),D3 提供了插值器。其中最通用的是 d3.interpolate,它承受数字、色彩、数字字符串,甚至数组和对象。给定 start 和 value 值,d3.interpolate 返回一个函数,这个函数取一个 0 ≤ t ≤ 1 的工夫并返回相应的两头值。
定义转换时,能够显式指定插值器(如上所述,应用 transition.attrTween)或让 D3 抉择(应用 transition.attr 或 transition.style)。显式指定容许应用更高级的插值办法,例如缩放、gamma 校对的 RGB 混合,甚至形态混合。
然而,动画不仅仅是插值:它也是计时。咱们须要每秒重画 60 次,并依据实时和动画的冀望开始工夫和持续时间计算标准化工夫 t。
到目前为止,咱们曾经看到了两种计时办法。
第一种依赖于 D3 的变换,创立初始图形,而后开始变换以批改它(插入 stroke-dasharray
数组)。
第二种依赖于 Observable 的数据流,每当援用的 t 发生变化时从新创立图形,并依赖一个 scrubber 进行计时。这比前一种办法效率低,因为图形是在每一帧从头开始创立的,但更容易编写。
Observable 还有另一个管制动画的弱小工具:生成器。当生成器单元生成一个值时,其执行将暂停,直到下一个动画帧为止,每秒最多执行 60 次。生成的值能够像整数一样简略,也能够是增量更新的 SVG 元素!
鉴于 Observable 中提供了各种无关动画的办法,该应用哪种呢?这要看状况了!
如果图形足够简略,你能够从头开始从新创立每个帧,或者如果实际上你不须要动画转换,则以申明形式编写图形。换句话说,什么也不做!得益于 Observable 的数据流,“动态”图形能够在不更改代码的状况下作出响应、交互或动画。
另一方面,对于性能须要高效增量更新的更简单的动静图形,应用转换或生成器。
你还能够将各种办法联合起来。下图最后是动态的,但给定 x 域一个转换的 chart.update 办法;当单选值更改时,另一个单元将调用此办法。(此代码应用 d3 选择器而不是 HTML 模板文本编写,但图形构造与后面的示例雷同,因而请尝试通过比拟推断代码的含意。)
通过提供一个或多个更新办法,图表能够有选择地为特定值更改的转换设置动画。如果有任何其它变动,图表将回到被动反馈状态,并从头开始从新绘制。
(如果你想晓得:你能够在独自的单元中定义更新,而不是将其作为办法裸露。然而,不倡议这样做,因为编辑更新代码不会从头开始从新绘制图表,这可能会导致不确定性的行为。😱 通过在图表单元中定义更新,它能够拜访在更新过程中继续存在的局部变量。)
这个示例演示了 D3 轴的另一个不便性能:通过切换到 transition.call 而不是 selection.call,x 轴中的更改当初是动静的而不是刹时的,并与转换门路同步!
下面的动画只波及一个元素:图表的线条。如果你想要设置多个元素的动画,该怎么办?如果元素集随着工夫的推移而变动,新元素进入旧元素退出,该怎么办?读上来!
Next
附录
如果你对设计无效的动画感兴趣,我强烈建议浏览 Heer 和 Robertson 2007 年的论文 Animated Transitions in Statistical Data Graphics。
附
依据源码,去除了平台依赖,提取了次要代码,有以下示例:
- 示例 1
- 示例 2
- 示例 3
- 示例 4
参考资料
- Learn D3: Animation