Animating Words with d3

Updated Feb 14, 2018

d3’s built-in transitions make it a great tool to animate arbitrary elements. Here we take advantage of that to animate SVG text elements, taking a sentence and scrambling the letters:

Get started by defining the data setting up the main SVG element:

Getting started Copy
import {
  select  as d3_select,
  shuffle as d3_shuffle
from 'd3';
let data = 'Does this make any sense?'.split('').map( (d, i) => ({
  letter  : d,
  index   : i,
  pos     : i
}));
const LETTER_WIDTH = 22;
const WIDTH        = LETTER_WIDTH * data.length;
const HEIGHT       = 80;
const svg = d3_select('#letters').append('svg')
  .attr('width', WIDTH)
  .attr('height', HEIGHT)
  .append('g')
    .attr('transform''translate(0,' + (HEIGHT/2+ ')');

Next we define an update function that handles data entry and update using the standard d3 pattern:

Update Copy
function update (data) {
  const text = svg.selectAll('text').data(data, d => d.index);
  text.enter().append('text')
    .attr('fill', d => d.letter === '?' ? 'tomato' : '#000')
    .attr('x', (d, i) => LETTER_WIDTH*d.pos)
    .style('font-size''40px')
    .style('font-family''monospace')
    .text(d => d.letter)
    .merge(text)
      .transition().duration(1000)
      .attr('x', (d, i) => LETTER_WIDTH*d.pos);
}

With the update function in hand the last step is to create a loop to shuffle the letters, call update, and restore their positions:

The loop Copy
function loop () {
  update(data);
  window.setTimeout(function () {
    data = d3_shuffle(data).map( (d, i) => {
      d.pos = i;
      return d;
    });
    update(data);
    window.setTimeout(function () {
      data = data.map( (d, i) => {
        d.pos = d.index;
        return d;
      });
      loop();
    }, 2000);
  }, 2000);
}
loop();

That’s all there is to it. Maybe not the most useful application but still fun.

Comments

No comments exist. Be the first!

Leave a comment