Based on:
Last active
November 12, 2017 16:22
-
-
Save nukadelic/6fab5f37e0ef5bd3b367d60da8b7e360 to your computer and use it in GitHub Desktop.
d3 - Transition Easing v4 (24.Oct.2017)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gist name ? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
license: mit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html><head><meta charset="utf-8"><script src="https://d3js.org/d3.v4.min.js"></script><link rel="stylesheet" type="text/css" href="style.css"></head><body></body><script> | |
// //|\ /\ //|\ /\ //|\ | |
// | |
// Data | |
// | |
// \\|/ \/ \\|/ \/ \\|/ | |
var data = ["easeLinear","easeQuadIn","easeCubicIn","easePolyIn","easeSinIn","easeExpIn","easeCircleIn","easeBounceIn","easeBackIn","easeElasticIn","easeQuadOut","easeCubicOut","easePolyOut","easeSinOut","easeExpOut","easeCircleOut","easeBounceOut","easeBackOut","easeElasticOut","easeQuadInOut","easeCubicInOut","easePolyInOut","easeSinInOut","easeExpInOut","easeCircleInOut","easeBounceInOut","easeBackInOut","easeElasticInOut"]; | |
// //|\ /\ //|\ /\ //|\ | |
// | |
// Variables | |
// | |
// \\|/ \/ \\|/ \/ \\|/ | |
var val_w = 600; | |
var val_h = 500; | |
var val_row = val_h / data.length; | |
var val_padding = val_row * 0.2; | |
var val_radius = val_row * 0.3; | |
var val_anim = 1700;// animation duration , animation delay = 25% of duration | |
var val_x1 = 140; // left padding ot avoid collision with text | |
var val_x2 = val_x1 + ( val_w - val_x1 ) * 0.7; // max easing x pos ( keep's overshooting easings within the screen boudns ) | |
// //|\ /\ //|\ /\ //|\ | |
// | |
// D3 - canvas | |
// | |
// \\|/ \/ \\|/ \/ \\|/ | |
var svg = d3.select('body').append('svg') | |
.attr('width', val_w) | |
.attr('height', val_h); | |
// //|\ /\ //|\ /\ //|\ | |
// | |
// D3 - attribute functions | |
// | |
// \\|/ \/ \\|/ \/ \\|/ | |
function f_getY(d,i) | |
{ | |
return 2 * ( i + 0.5 ) * ( val_radius + val_padding ); | |
} | |
var colors = d3.scaleOrdinal(d3.schemeCategory20c ).domain([0,8]) | |
function f_getColor(d, i) | |
{ | |
// linearEase is white, rest is calculated as groups of 9's | |
return i===0 ? '#fff' : colors( ((i-2)%9) ); | |
} | |
// //|\ /\ //|\ /\ //|\ | |
// | |
// D3 - elemnts creation | |
// | |
// \\|/ \/ \\|/ \/ \\|/ | |
var selection_rows = svg | |
.selectAll('g') | |
.data( data ) | |
.enter() | |
.append('g') | |
.attr('transform', (d,i)=> 'translate(0,' + f_getY(d,i) + ')' ); | |
var selection_rects = | |
selection_rows.append('rect') | |
.attr('width', val_w) | |
.attr('height', (val_radius+val_padding)*2+1) | |
.attr('y',-val_radius-val_padding); | |
var selection_lines = | |
selection_rows.append('line') | |
.attr('x1', val_x1) | |
.attr('x2', val_x2); | |
var selection_texts = | |
selection_rows.append("text") | |
.attr('fill',f_getColor ) | |
.attr("dy", ".35em") | |
.text((d)=>d); | |
var selection_circles = | |
selection_rows.append('circle') | |
.attr('fill',f_getColor ) | |
.attr('cx', val_x1) | |
.attr('r', val_radius); | |
// //|\ /\ //|\ /\ //|\ | |
// | |
// Highlight on mouse move | |
// | |
// \\|/ \/ \\|/ \/ \\|/ | |
selection_rows.on('mouseover', function() | |
{ | |
// ALL: dim, zoom-out, reset radius | |
selection_rows | |
.classed('dim', true) | |
.classed('focus', false) | |
.select('circle') | |
.attr('r', val_radius); | |
// Highlight, zoom in & enlarge radius for any row under mouse | |
var current = d3.select( this ) | |
.classed('dim', false) | |
.classed('focus', true) | |
.select('circle') | |
.attr('r', val_row * .5); | |
// Get current selection index | |
var index = data.indexOf( d3.select( this ).datum() ); | |
// Linear has no In,Out easing combinations | |
if( index === 0 ) return; | |
// Highlight, zoom in & enlarge easings of the same group | |
selection_rows | |
.filter(function(d,i){ | |
if( i === 0 ) return false; | |
return (i - index) % 9 === 0; | |
}) | |
.classed('dim', false) | |
.classed('focus', true) | |
.select('circle') | |
.attr('r', val_row * .5); | |
}); | |
svg.on('mouseout', ()=> { | |
d3.selectAll('g') | |
.classed('dim', false) | |
.classed('focus', false) | |
.select('circle') | |
.attr('r', val_radius); | |
}); | |
// //|\ /\ //|\ /\ //|\ | |
// | |
// Transition | |
// | |
// \\|/ \/ \\|/ \/ \\|/ | |
var _count = 0; | |
function animate( value ) | |
{ | |
//console.log( value ); // log's each element datum ( display all transitions ) | |
if( value === 'init' || ++_count === data.length ) | |
{ | |
_count = 0; | |
// Attempt: #4 ... solved ? | |
d3.selectAll('circle') | |
.each(function(d, i) { | |
d3.select(this) | |
.transition() | |
.ease((t)=>d3[d](t)) | |
.duration(val_anim) | |
.attr('cx', val_x2) | |
.delay(val_anim*0.25) | |
.transition() | |
.ease((t)=>d3[d](t)) | |
.duration(val_anim) | |
.attr('cx', val_x1) | |
.delay(val_anim*0.25) | |
.on("end", animate); | |
}); // each | |
} | |
} | |
// //|\ /\ //|\ /\ //|\ | |
// | |
// Start the animation | |
// | |
// \\|/ \/ \\|/ \/ \\|/ | |
animate('init'); | |
/* | |
// --------------------------------- | |
// Attempt: #1 - doesn't work | |
function loop() | |
{ | |
selection_circles | |
.transition() | |
.call((s)=>{ | |
console.log( selection ); // error! | |
s.ease(d3[s.selection().datum()]); | |
}) | |
.duration(1000) | |
.attr('cx', val_w - val_radius) | |
.transition() | |
.duration(1000) | |
.attr('cx', val_radius) | |
.on("end", loop); | |
} | |
loop(); | |
// --------------------------------- | |
// Attempt: #2 - work's but each transition is calling the same function on end resulting in unececerry executions | |
function loop() | |
{ | |
selection_circles.each(function(d, i) { | |
d3.select(this) | |
.transition() | |
.ease((t)=>d3[d](t)) | |
.duration(1000) | |
.attr('cx', val_w - val_radius) | |
.transition() | |
.ease((t)=>d3[d](t)) | |
.duration(1000) | |
.attr('cx', val_radius) | |
.on("end", loop); | |
}); | |
} | |
loop(); | |
// --------------------------------- | |
// Attempt: #3 - Also works but something tells me this is not how d3 should be handeling selections. | |
function animate(singleNode) | |
{ | |
var d = singleNode.datum(); | |
singleNode | |
.transition() | |
.ease((t)=>d3[d](t)) | |
.duration(1000) | |
.attr('cx', val_w - val_radius) | |
.transition() | |
.ease((t)=>d3[d](t)) | |
.duration(1000) | |
.attr('cx', val_radius) | |
.on("end", endAnimation); | |
} | |
var _count = 0; | |
function endAnimation( ease ) | |
{ | |
if( ++_count === data.length ) | |
{ | |
_count = 0; | |
loop(); | |
} | |
} | |
function loop() | |
{ | |
selection_circles.each(function(d, i) { | |
d3.select(this).call(animate); | |
}); | |
} | |
loop(); | |
*/ | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
html, body { | |
padding: 0; | |
margin: 0; | |
width: 100%; | |
height: 100%; | |
} | |
body { | |
background-color: #2a2129; | |
display: flex; | |
align-items: center; | |
justify-content: center; | |
} | |
svg * { stroke-width: 0; } | |
svg rect { opacity: 0; } | |
svg line { stroke-width: 1px;stroke:#333; } | |
svg circle { stroke-width: 0; } | |
svg text { font-size: 18px; } | |
svg g.dim { opacity: 0.2; } | |
svg g.dim line { stroke-width: 0; } | |
svg g.focus line { stroke: #666; } | |
svg g.focus rect { opacity: 0.05;fill:white; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment