JSFiddle - React, Tailwind, and code Playground

by Óscar Gómez Alcañiz

HTML

<button>
  Move!
</button>

<div class="container">
  <h1>
    #Circles
  </h1>
</div>

SCSS

body,
html {
  display: table;
  width: 100%;
  height: 100%;
  background: black;
  font-family: sans-serif;
}

.container {
  display: table-cell;
  text-align: center;
  vertical-align: middle;
  color: white;
  width: 100%;
  height: 100%;
}

h1 {}

button {
  position: relative;
  border: none;
  border-radius: .25em;
  font-size: 12pt;
  background: #990000;
  border-bottom-width: .25em;
  border-bottom-style: solid;
  border-bottom-color: #600;
  color: white;
  text-shadow: 0 .12em .12em #660000;
  padding: .5em;
  cursor: pointer;
  top: 0;
  transition: .06s;
  &:hover {
    top: .25em;
    border-bottom-width: 0;
  }
}

.circle {
  position: absolute;
  border-radius: 50%;
  text-align: center;
  text-shadow: -1px -1px 1px rgba(0, 0, 0, .4);
  vertical-align: middle;
  display: table-cell;
  color: white;
}

Babel + JSX

const MAX_N_THINGS = 10,
  MAX_V = 80;

function randomizeThings(n) {
  let things = [];

  for (let i = 0; i < n; i++) {
    things.push({
      x: Math.round(Math.random() * document.body.clientWidth),
      y: Math.round(Math.random() * document.body.clientHeight),
      v: Math.round(Math.random() * MAX_V)
    });
  }

  return things;
}

function draw() {
  let things = randomizeThings(Math.round(Math.random() * MAX_N_THINGS)),
    color = d3.scale.linear().domain([0, 100]).range([0x0000, 0xFFFF]),
    red = d3.scale.linear().domain([0, 100]).range([0x00, 0xFF]),

    circles = d3.select('body')
    .selectAll('.circle')
    .data(things, (thing, t) => t);

  // Enter
  circles.enter()
    .append('div', 'button')
    .classed('circle', true)
    .style({
      top: 0,
      left: 0,
      width: 0,
      height: 0,
      opacity: 0,
      'font-size': '0em',
      'line-height': 0
    }).text('');

  // Update
  circles
    .transition().duration(2000)
    .style({
      top: d => d.y + 'px',
      left: d => d.x + 'px',
      width: d => d.v + 'px',
      height: d => d.v + 'px',
      //'font-size': d => (d.v / 30) + 'em',
      'line-height': d => d.v + 'px',
      background: d => {
        let c = '#' + red(d.v).toString(16).split('.').shift() + color(100 - d.v).toString(16).split('.').shift();
        return c;
      },
      opacity: d => Math.random()
    }).text(d => d.v);

  // Exit
  circles.exit()
    .transition().duration(2000)
    .style({
      opacity: 0,
      top: document.body.clientHeight,
      left: document.body.clientWidth,
      width: document.body.clientWidth * 2,
      height: document.body.clientHeight * 2,
      'font-size': d => {
        console.debug(d.v), '0em'
      },
      'line-height': 0
    });
}

d3.select('button').on('click', draw);

draw();