Skip to main content
100%

My first working animation

✓ Published1🌍 Public
RRussell Watson
Last edited Feb 13, 2020
Created on Feb 5, 2020

Words fall like rain across an SVG canvas, each word shrinking from oversized, transparent text into its final position with rainbow colors. Words are randomly selected from a repeated dataset and appended every 100 milliseconds for 20 seconds. The animation uses D3 v5's `selectAll`, `data`, `enter`, `transition`, and `duration` methods, with `scaleSequential` and `interpolateRainbow` for coloring. A custom `playAnimation` function drives `setInterval` and `setTimeout`.

AI-generated description

So, I've given up on making a word-cloud, but I have managed to make it rain words!

Lots of things have come together all at once to make this work:

ES6 Modules

I've at last cracked ES6 Modules (which had been baffling me a bit in VizHub)

  • IMPORTANT!*
  • When importing modules don't forget the ./ in the import module name!
import { select } from 'd3';
import { appendRandomWord } from './random'; // './*' !
import { color } from './color'
import { words } from './data';

Data 'munging'

  • Using map to add a (random) 'fill' property to the data

Color Scale

Using…

  • scaleSequential
    • with an (unnecessarily explicit) domain of [0,1]
    • which is great for random colors
      • (Math.random delivers numbers in the range [0,1])
  • interpolateRainbow
    • which is a range of colors across the rainbow
  • a custom color function to pass the value to the scale to convert it to a color
  • and choosing the necessary property
    • .attr('fill', d => color(d.fill) )

Animation

At last!

Using…

  • .enter() - to add text objects
  • .transition() - to animate the movement
  • .duration() - to control the
  • setTimeout - (recursive) to dynamically add data to the array
  • better:
    • setInterval - to repeatedly add data to the array without recursion
  • even better:
    • setInterval + setTimeout with clearInterval - to play an animation for a fixed duration
  • the best yet:
    • a custom function to animate at a given rate for a given time:
  function playAnimation (animationFunc,rateMS,durationMS)

svg text elements

  • animating, appending text elements and defining their content
    svg.selectAll('text')
      .data(…)

    .enter()
      .append('text')
      :
      .text(d =>  d.text)
  • anchoring text centrally using the svg-attributes
      .attr('text-anchor','middle')
      .attr('dominant-baseline','middle')

Parameterisation

  • variables for many aspects of the
  • a location function to decide where the words are going to land
  • Next steps:
    • Rework the whole chart as a function

DON'Ts

It's been a real steep curve learning what you don't need from the (sometimes very old or mediorchre) examples you find (out there ... not the ones from [Curran]).

  • You don't need to wrap the .transition()-code in a .call(…)!
    • So, NOT this:
      • .call(e => e.transition() … );
  • You don't need to pass a duration parameter to the .transition() function
    • So, NOT this:
      • .call(e => e.transition(t)
MIT Licensed

Similar vizzes