Interesting ideas, both get the job done, but there's a d3-specific way to do this: a custom tween function.
Fiddle here: http://jsfiddle.net/QbysN/3/
Code:
function transition() {
d3.select('text').transition()
.duration(5000)
.ease("linear")
.tween("text", function () {
var newText = data[i];
var textLength = newText.length;
return function (t) {
this.textContent = newText.substr(0,
Math.round( t * textLength) );
};
});
i = (i + 1) % data.length;
}
The outer function that you pass to .tween()
is called a tween factory because it creates the tween function for each element. It is executed once per element (and would normally use the data and index of the element as parameters), at the start of the transition. It runs any set-up calculations and then returns the tween function that will be used during the transition.
The returned tween function is also called an interpolator because it calculates intermediary values. In this case it is:
function (t) {
this.textContent = newText.substr(0, Math.round( t * textLength) );
};
This function will get called at every "tick" of the transition, and passed a value between 0 and 1 representing how far through the transition the result is supposed to be. (The rate at which 0 changes to 1 will vary according to the easing parameter, I've used linear easing for a steady rate of type.)
When you are specifying custom tween functions for attributes or styles, the tween function would return the value to be used for that attribute or style at that point in the transition. For the generic transition.tween()
, return values are not used, your function has to actually make the change itself -- which I do by directly setting the textContent
property of the element. I set it to a substring of the target text, where the number of characters in the substring is determined by the t
parameter (which is always between 0 and 1) and the length of the text, so that the entire text gets typed out in the length of the transition.
P.S. You can have fun with the easing function, too. The "bounce" ease makes it look like the typist is unsure about what they are writing: