animation - Transition chaining and cancellation -
i have 2 functions perform animations on lines. first function, one
executed @ beginning, in order perform operations on enter selection, , animates lines' horizontal movement (x1
, x2
). second function two
animates lines' height (only y2
,y1
stays fixed).
through user events, function one
cannot interrupted function two
, vice versa (also because animation in two
considerably longer). means that, when transition two
still running, user can trigger one
.
this gave me serious headaches, because one
somehow take values of last state of running transition of two
instead of correctly assigning data-driven value (i.e. .attr('y2', function(d){ ... });
).
http://jsfiddle.net/h39wn/6/ - please following: click on one
. see horizontal movement animated data changes. see @ end of execution, lines should ordered lowest highest. click on two
once , wait full 2 seconds until animation completed. click on one
again. desired behavior.
now click on two
, wait few ms , click on one
- see lines keep height of last state of two
's animation, though correctly ordered. (i know data not realistic , maybe bit confusing in example, still allow replicate problem).
i came solution schedule another, "empty", transition on lines in one
- according docs should cancel 1 still running in two
when one
invoked:
var 1 = function () { var svg = d3.select('svg'); vis.mobileteams = svg .selectall('.teamgroup') .data(data.values, function (d) { return d.id; }); // enter var teamenter = vis.mobileteams .enter() .append('g') .attr('class', 'teamgroup'); // enter line teamenter .append('line') .attr('class', 'teamweightedline'); // update line // height - should not animated svg .selectall('.teamgroup line') .attr('y1', paddingy) // inserted transition here cancel // 1 triggered other function var linetransition = svg .selectall('.teamgroup line') .transition() .attr('y2', function(d){ ... }); // need use transition chaining changing 'y2' // transition not // overwritten following transition // horizontal position - should animated linetransition .transition() .duration(500) // 'x1' , 'x2' values // need animated in function .attr('x1', function (d) { return function(d){ ... }); }) .attr('x2', function (d) { return function(d){ ... }); }); };
and here second function.
var 2 = function () { var svg = d3.select('svg'); // transition concerning height supposed take place svg .selectall('.teamgroup line') .transition() .ease('circle-out') .duration(2000) .attr('y2', vis.mobilecalculatescoretoheight); console.log('mobile vis updated'); };
even though fixes "interference" problem two
's transition canceled because 1 scheduled, brings problem:
var linetransition = svg .selectall('.teamgroup line') .transition() .attr('y2', function(d){ ... });
http://jsfiddle.net/96un6/8/ fiddle incorporates change. when two
interrupted one
, correct heights result in end - but:
y2
being animated in one
too! know .transition()
brings default duration of 250ms, did this:
var linetransition = svg .selectall('.teamgroup line') .transition() .duration(0) .attr('y2', function(d){ ... });
this, in turn, brings problem: y2
not set @ now, i.e. <line>
s don't have attribute:
weirdly, works when using short duration (so animation barely visible), works , browser-dependent:
var linetransition = svg .selectall('.teamgroup line') .transition() .duration(10) .attr('y2', function(d){ ... });
setting y2
in regular selection instead of transition selection not work either brings "interference" problem - y2
set when animation two
still running.
svg .selectall('.teamgroup line') .attr('y1', paddingy) .attr('y2', function(d){ ... }); var linetransition = svg .selectall('.teamgroup line') .transition();
the approach without transition chaining not work either, of course, because first transition canceled second , y2
never set.
svg .selectall('.teamgroup line') .transition() .duration(10) .attr('y2', function(d){ ... }); svg .selectall('.teamgroup line') .transition() .duration(transduration) .attr('x1', function (d) { return function(d){ ... }; }) .attr('x2', function (d) { return function(d){ ... }; });
so possible solution working me (the 1 short duration) seems quirky, there must better solution, mustn't it? feel free ask if unclear.
through mike bostock (https://github.com/mbostock/d3/issues/1877), found out can use selection.interrupt()
cancel previous transitions, i.e., running transitions.
so, quirky
var linetransition = svg .selectall('.teamgroup line') .transition() .duration(0) .attr('y2', function(d){ ... });
becomes
var linetransition = svg .selectall('.teamgroup line') .interrupt() .attr('y2', function(d){ ... });
it's easy that.
Comments
Post a Comment