D3中动画(transition函数)的使用
关于transition的几个基本点:
1. transition()是针对与每个DOM element的,每个DOM element的transition并不会影响其他DOM element的transition操作;
2. 对于每一个DOM element的transition每次只能执行一个,如果在一个DOM element上添加了许多transition操作,只有最后一个会起作用,前面的都会被覆盖掉。但是例外是,当这些transition是chaining的形式连接的时候,这些transition会按照先后顺序依次执行(大致形式就是:.....transition()....transition()....)。具体可以查看这个例子:http://bl.ocks.org/mbostock/3943967
3. 在对每个transition动作除了用duration()函数指定持续时间之外,也可以通过delay()函数来对transition动作加一定时间的时间延迟,2中提到的例子有相关的代码。
4. transition比较核心的一点就是,必须要有两个核心的frame:起始frame是怎么样,终止frame是什么样。这些都要在schedule一个transition动作的时候指定好。因此有些操作就没法加transition,例如,创建一个新的DOM element,因为没有起始frame.
5. 并不是所有的属性都能加transition,目前D3支持四种数据/属性的transition:
- numbers
- colors
- geometric transforms
- strings with embedded numbers (e.g.,
"96px"
) (注意,这是目前能够应用transition的几种属性)
因此,如果要多一个文本的创建加transition就是不可能的。
6. Transition 和join操作相结合的一个常用的模板:
var bar = svg.selectAll(".bar")
.data(data, function(d) { return d.key; });
bar.enter().append("rect")
.attr("class", "bar")
… // initialize entering bars
bar.transition()
… // transition entering + updating bars
bar.exit().transition()
… // transition exiting bars
.remove();
主要参考文章:working with transitions: http://bost.ocks.org/mike/transition/
以下是Mike Bostock的博客原文:
Working with Transitions
D3’s selection.transition method makes it easy to animate transitions when changing the DOM. For example, to change the text color to red instantaneously, you can select the body element and set the color style:
d3.select("body").style("color", "red");
To instead animate the change over time, derive a transition:
d3.select("body").transition().style("color", "red");
This ease-of-use comes from D3’s transition interface mirroring the selection interface: nearly everything you can do to a selection of elements, you can also do to a transition, causing the change to be animated over time rather than instantaneous.
Yet looks can be deceiving because selections and transitions are not perfectly equivalent: transitions provide only a subset of selection functionality. These nuances are due to the long-running, asynchronous nature of transitions. Before you attempt more complicated uses of transitions, it is helpful to understand the system’s underlying design.
Note: This article discusses transitions as implemented in version 3.0, which was released in December 2012. You can download D3 3.0 from d3js.org or GitHub.
#Transitions Are a Form of Animation
For more general uses, consider implementing animations withd3.timer rather than as transitions.
Transitions are a limited form of key frame animation with only two key frames: start and end. The starting key frame is typically the current state of the DOM, and the ending key frame is a set of attributes, styles and other properties you specify. Transitions are thus well-suited for transitioning to a new view without complicated code that depends on the starting view.
Look again at this example transition:
d3.select("body").transition().style("color", "red");
Although only a single attribute value is specified—the color red—a second value is implied. This starting value is computed from the DOM via getComputedStyle or getAttribute.
In some cases, the computed starting value may not be what you want. For example, it can be different than what was set previously due to browsers converting values to canonical representations, say converting the color string "red"
to "rgb(255,0,0)"
. Depending on the interpolator you use (more on that in a bit), this may cause the transition to stutter. As another example, transparent colors are reported as "rgba(0,0,0,0)"
(transparent black), which is treated as opaque black when using RGB interpolation.
One way to make the starting value more explicit is to set it in the DOM before creating the transition. This won’t fix problems related to value conversion, but it can be useful if the inherited or default value isn’t what you want.
d3.select("body")
.style("color", "green") // make the body green
.transition()
.style("color", "red"); // then transition to red
If the transition has a delay, then the starting value should be set only when the transition starts. You can do this by listening for the start event:
This is a new feature in 3.0; older versions of D3 dispatched the start event after constructing tweens.
d3.select("body").transition()
.delay(750)
.each("start", function() { d3.select(this).style("color", "green"); })
.style("color", "red");
The most explicit approach to set the starting value is to use transition.styleTween. This skips computing the starting value from the DOM by specifying the both values and an interpolator.
d3.select("body").transition()
.styleTween("color", function() { return d3.interpolate("green", "red"); });
This last variation gives a hint as to how transitions work under the hood. When you use transition.style, D3 creates a style tween for you automatically by retrieving the starting value from the DOM and constructing an interpolator to the specified ending value. If you want to override the start value or the interpolator, do this using styleTween, attrTween or tween.
#Transitions Interpolate Values over Time
Given start and end key frames, how do we get from here to there? To perform a smooth animated transition, D3 needs to know how to interpolate—or blend—from a given starting value to its corresponding ending value. The d3.interpolate method determines an appropriate interpolator by inferring a type for each pair of starting and ending values. D3 supports several common types, including:
The same interpolation subsystem is used by D3’squantitative scales. You can extend the set of built-in interpolators by adding to thed3.interpolators array. Or create a custom tween.
- numbers
- colors
- geometric transforms
- strings with embedded numbers (e.g.,
"96px"
) (注意,这是目前能够应用transition的几种属性)
The string interpolator is particularly useful: it finds numbers embedded within strings, pairing up numbers in the starting string with the corresponding number in the ending string. Those numbers are interpolated separately, and the resulting string is then reconstructed. String interpolators have myriad applications, such as interpolating path data (e.g., "M0,0L20,30"
) and CSS font specifications (e.g., "300 12px/100% Helvetica"
).
String interpolation isn’t always appropriate. If the starting and ending path data have a different number of control points, for example, it’s no longer meaningful to pair up numbers. Instead, you need to resample the path prior to interpolation (or apply more advanced shape blending algorithms). Likewise, arcs require interpolation in polar coordinates so that the angles are interpolated, rather than the positions.
If you want to implement your own interpolator, you need a function that takes a single argument tranging from 0 to 1. For t = 0, the interpolator returns the starting value; for t = 1, the interpolator returns the ending value; and for values in-between, the interpolator returns a blending value. For example, to interpolate two numbers:
When rolling your own interpolator, you may still be able to reuse some of D3’sbuilt-in interpolators.
function interpolateNumber(a, b) {
return function(t) {
return a + t * (b - a);
};
}
When interpolating to or from zero, some interpolated values may be very small. JavaScript formats small numbers in exponential notation, which unfortunately is not supported by CSS. For example, when transitioning opacity to fade in or out, the number 0.0000001
is converted to the string "1e-7"
and then ignored, giving the default value of 1
! To avoid distracting flicker, start or end the transition at 1e-6
rather than 0
; this is the smallest value not formatted in exponential notation.
Some Things Cannot Be Interpolated
When modifying the DOM, use selections for any changes that cannot be interpolated; only use transitions for animation. For example, it is impossible to interpolate the creation of an element: it either exists or it doesn’t. Furthermore, in order to schedule a transition, the element must exist and so element creation cannot be deferred to start. Selection methods related to data joins (data, enter, exit) and creating elements (append, insert) can therefore only be performed on selections.
When using transitions in conjunction with the general update pattern, first perform the data-join on selections using enter and exit. Then derive transitions on each subselection as desired.
To perform a special transition on updating nodes, derive a transition before appending to the enter selection.
(以下是一个常用的使用transition加enter(), exit()集合的一个模板)
var bar = svg.selectAll(".bar")
.data(data, function(d) { return d.key; });
bar.enter().append("rect")
.attr("class", "bar")
… // initialize entering bars
bar.transition()
… // transition entering + updating bars
bar.exit().transition()
… // transition exiting bars
.remove();
For convenience, there are a few exceptions to this rule. You can transition.remove to remove an element at the end of the transition; likewise, transition.text sets the text content at the start of the transition, without interpolating. In the future, transitions may support additional non-interpolatable operations, such as classed and html.
#The Life of a Transition
As with concurrent programming, perhaps the trickiest aspect of transitions is that they happen over time rather than instantaneously. The code does not proceed in a single straightforward path, as when the page loads, but as a complex sequence of recurring callbacks. While you can safely ignore this complexity in many cases, you must understand the rules which govern the evaluation of transitions if you want to harness their full power.
A useful mnemonic is that transitions are conceived, born,live and die. But perhaps that takes the metaphor too literally.
Transitions have a four-phase life cycle:
- The transition is scheduled.
- The transition starts.
- The transition runs.
- The transition ends.
A transition is scheduled when it is created: when you call selection.transition, you are scheduling a transition. This is also when you call attr, style, and other transition methods to define the ending key frame. Scheduling happens in your code (for example, in response to the user clicking a button), meaning that the code so far is fully synchronous. This makes it easier to debug, and easier to use ending values that depend on changing global state, such as a scale’s domain.
A transition starts based on its delay, which was specified when the transition was scheduled. If no delay was specified, then the transition starts as soon as possible, which is typically after a few milliseconds. The start event is then dispatched, and the transition initializes its tweens, which may involve retrieving starting values from the DOM and constructing interpolators. Deferring the initialization of tweens to start is necessary because starting values aren’t known until the transition starts. Therefore, if you use attrTween, styleTween and other tween methods, keep in mind that your code will be evaluated asynchronously when the transition starts!
While the transition runs, its tweens are repeatedly invoked with values of t ranging from 0 to 1. In addition to delay and duration, transitions have easing to control timing. Easing distorts time, such as for slow-in and slow-out. Some easing functions may temporarily give values of t greater than 1 or less than 0; however, the ending time is always exactly 1 so that the ending value is set exactly when the transition ends. A transition ends based on the sum of its delay and duration. When a transition ends, the tweens are invoked a final time with t = 1, and then the end event is dispatched.
#Transitions Are per-Element and Exclusive
There is no end event when all selected elements finish transitioning, although you can simulate this by counting.
Each element transitions independently. When you create a transition from a selection, think of it as a set of transitions, one per element, rather than a single mega-transition running on multiple elements. Different elements can have different delays and duration, and even different easing and tweens. Additionally, transition events are dispatched separately for each element. When you receive an end event for a given element, its transition has ended, but other transitions may still be running on other elements.
For a given element, transitions are exclusive: only one transition can be running on the element at the same time. Starting a new transition on the element stops any transition that is already running. Interrupting a transition on the element has no effect on other elements, and multiple transitions can run concurrently on different elements. While only one transition can be running simultaneously on the element, multiple transitions can be scheduled. For example, you can schedule successive transitions using transition.transition, which creates a new transition whose delay immediately follows the existing transition.
For each element, sequences of transitions only advance forward in time. Transitions are assigned a monotonically-increasing identifier (id
) when they are scheduled; each new transition id
is greater than the last. When a transition starts on the element, it can only run if the transition is newer than whatever previously ran on the same element. Thus, starting a new transition implicitly cancels any previous transitions—even if those old transitions have not yet started. This design eliminates the need to cancel transitions explicitly. An excellent illustration of this behavior is thestacked-to-grouped bar transition. This uses two chained transitions: the bars first slide right and narrow; then the bars drop to the baseline. The first transition also has a staggered delay. If you quickly toggle between stacked and grouped, notice the old transition is only interrupted when the new one starts, not when the new one is scheduled.
Similar to how data is bound to an element’s __data__
property, transitions are bound to a__transition__
property. When a transition is first scheduled on an element, this property is created; when the last scheduled transition ends, this property is likewise deleted. Inspecting this property in the console can be useful to debug which transitions are scheduled to run on which elements, as well as to inspect computed tweens and transition timing parameters. Because transitions are bound to elements, you can also reselect elements within a transition and modify tweens or timing. This is most common in conjunction with component-driven transitions, such as the axis component; use post-selection to customize the appearance of elements after invoking the component.
#Additional Reading
This tutorial covered most of the important details in the mechanics of transitions. I omitted an explanation of transition inheritance using transition.each; perhaps I’ll cover that in the future, though see #400 for an example. For more on how transitions should be used (and not just implemented), see my earlier post on object constancy and Heer & Robertson’s excellent paper,“Animated Transitions in Statistical Data Graphics”.
D3中动画(transition函数)的使用的更多相关文章
- css3中动画(transition)和过渡(animation)详析
css3中动画(transition)和过渡(animation)详析
- CSS3中动画属性transform、transition 和 animation
CSS3中和动画有关的属性有三个 transform.transition 和 animation.下面来一一说明: transform 从字面来看transform的释义为改变,使 ...
- vue中使用transition和animate.css动画效果
一.单个动画中,使用div中引用animate动画 1.下载依赖 npm install animate.css –save 2.main.js中全局引用 import animate from 'a ...
- 【转载】jQuery动画中的queue()函数
原文链接:http://www.cnblogs.com/hh54188/archive/2011/04/09/1996469.html 原文摘要:当你使用一系列的动画效果(如hide,show),这些 ...
- jQuery动画高级用法(上)——详解animation中的.queue()函数
如果你拿着一个疑问去找专业人士寻找答案,那么你的一个疑问会变成三个,因为他会用另外两个令你更加一头雾水的名词来解释你的这个疑问. 我想这是大多数,包括我在内,IT人在学习过程中碰到的最大问题.当你有一 ...
- D3.js 动画 过渡效果 (V3版本)
一 . 过渡的启动 启动过渡效果,与以下四个方法相关: d3.transition([selection],[name]) //创建一个过渡对象.但是由于每个选择集中都有transition( ...
- 大厂前端带来css3动画transition的使用和介绍全新认识动画
CSS3中可以使用transition来做最简单动画效果,transition表示到一个元素的属性值发生变化时,我们可以看到页面元素从旧的属性慢慢变化为新的属性值的过程,这种效果不是立即变化的,而是体 ...
- CSS动画-transition/animation
HTML系列: 人人都懂的HTML基础知识-HTML教程(1) HTML元素大全(1) HTML元素大全(2)-表单 CSS系列: CSS基础知识筑基 常用CSS样式属性 CSS选择器大全48式 CS ...
- 锋利的jQuery读书笔记---jQuery中动画
jQuery中的动画: 1.show和hide 2.fadeIn和fadeOut 3.slideUp和slideDown <!DOCTYPE html> <html> < ...
随机推荐
- VBA笔记(三)——常用对象
VBA实际上就是操作Excel,把Excel进行拆解,划分多层对象,由顶至下为(也可以说是层层包裹): Application:代表Excel程序本性,之后我们操作对象都在它之下,因为是唯一且至高点, ...
- shell 计算
1.整数计算 n=$((/)) echo $n 输出 2(注意必须是两个括号) exper / / 注意这里不支持括号,a%b,a/b后取余 output: 1 2.小数计算 bc <<& ...
- [Computational Advertising] 计算广告学笔记之基础概念
因为工作需要,最近一直在关注计算广告学的内容.作为一个新手,学习计算广告学还是建议先看一下刘鹏老师在师徒网的教程<计算广告学>. 有关刘鹏老师的个人介绍:刘鹏现任360商业产品首席架构师, ...
- STM32f10xxx 之 GPIO口配置
背景 配置stm32f103使其完成PWM输出的过程中,在配置GPIO口的时候,按照习惯配置GPIO口的speed为50MHZ,突然就意识到,为什么大部分例程习惯配置为50MHZ,而不是其它值,即有了 ...
- 如何改变span元素的宽度与高度
内联元素:也称为行内元素,当多个行内元素连续排列时,他们会显示在一行里面. 内联元素的特性:本身是无法设置宽度和高度属性的,但是可以通过CSS样式来控制,达到我们想要的宽度和高度. span举例1: ...
- ORACLE 中ROWNUM用法总结(转)
ORACLE 中ROWNUM用法总结! 对于 Oracle 的 rownum 问题,很多资料都说不支持>,>=,=,between...and,只能用以上符号(<.<=.!=) ...
- maven+ssm+cxf3配置例子
以下只是简单记录 ssm结合cxf3的配置 提供方配置::: pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0&quo ...
- mac php环境启动
mac 环境下,用brew安装php相关环境启动命令 说明 这里php,mysql,nginx都是用brew安装,安装目录默认,在Cellar下面 php-fpm 带配置重启 /*注意权限,加 sud ...
- Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters. Examples: Giv ...
- 新型的Hbb项目目录结构
- Hbb - ComponentPacket (底层组件包) 数据库组件 网络组件 格式化组件 - Resources (存放所有图片资源文件) - ToolClass (工具类/Helper 独立 ...