block by kenpenn 911d741a436e8c1ed1d25dbf846fb966

viz for viSFest 2017

Full Screen

Created for d3 viSFest unconf 2017

generates elliptical paths, moves ‘stars’ along those paths with path.getPointAtLength();

function for elliptical paths adapted from this stackverflow question

Created using blockbuilder

index.html

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>unconf 2017 viz</title>
  <style>
    body {margin:0;}
    svg { background: #000; }
  </style>
</head>
<body>
<svg width="960px" height="960px" viewBox="0 0 960 960" version="1.1" xmlns="//www.w3.org/2000/svg" xmlns:xlink="//www.w3.org/1999/xlink">
  <defs>
    <path class="star" d="M32,64 C32,46.326888 46.326888,32 64,32 C46.326888,32 32,17.673112 32,0 C32,17.673112 17.673112,32 0,32 C17.673112,32 32,46.326888 32,64 Z"></path>
  </defs>
  <style>
    .star {
      fill: #fff;
      stroke: none;
    }
    .color-orbit {
      fill: none;
      stroke-width: 8px;
    }
    .star-orbit {
      fill: none;
      stroke: none;
    }
  </style>
  <g id="orbital-grp"></g>
  <g id="stars-grp"></g>
</svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.1.1/d3.min.js"></script>
<script>
  var svg = d3.select('svg');
  var svgDims = svg.node().getBoundingClientRect();
  var ctrX = svgDims.width * 0.5;
  var ctrY = svgDims.height * 0.5;
  var orbitRx = (svgDims.width - 128) * 0.5;
  var orbitalGrp = d3.select('#orbital-grp');
  var starDef = document.querySelector('svg defs .star');
  var starDims = starDef.getBoundingClientRect();
  var starsGrp = d3.select('#stars-grp');
  var colors = ['hsl(0, 100%, 50%)','hsl(28, 100%, 50%)','hsl(60, 100%, 50%)','hsl(90, 100%, 50%)','hsl(120, 100%, 50%)','hsl(216, 100%, 50%)','hsl(252, 100%, 50%)','hsl(272, 100%, 50%)','hsl(288, 100%, 50%)','hsl(314, 100%, 50%)'];
  var clx = 0;
  var cLen = colors.length;

  function ellipticalPath (cx, cy, rx, ry) {
    return 'M' + (cx - rx) + ',' + cy
        + ' a' + rx + ',' + ry
        + ' 0 1,0 ' + (rx * 2) + ',0'
        + ' a' + rx + ',' + ry
        + ' 0 1,0 -' + (rx * 2) + ',0 Z'
  }

  function setOrbitTransform (idx) {
    return 'translate(' + ctrX + ', ' + ctrY + ')'
        + ' rotate(' + (idx * 18) + ') ' // 10 colors, 180 / 10
        + ' translate( -' + ctrX + ', -' + ctrY + ' )';
  }

  function cycle () {
    var orbits = orbitalGrp.selectAll('.color-orbit');
    orbits.each(function () {
      var orbit = d3.select(this);
      var nextColor = orbit.datum().color - 1 < 0 ?  cLen - 1 : orbit.datum().color - 1;
      orbit
        .attr('stroke', colors[nextColor])
        .datum({'color': nextColor});
    });

    var starGrps = d3.selectAll('.star-grp');

    starGrps.each(function () {
      var starGrp = d3.select(this);
      var starOrbit = starGrp.select('.star-orbit');
      var len = starOrbit.node().getTotalLength();
      var stars = starGrp.selectAll('.star')
      stars.each(function () {
        var star = d3.select(this);
        var step = star.datum().step + 1 < 10 ? star.datum().step + 1 : 0;
        var pt = starOrbit.node().getPointAtLength(step * len * .1)
        star
          .attr('transform', 'translate(' + (pt.x - 32) + ',' + (pt.y - 32) + ')')
          .datum({ 'step': step});
      });
    });

    setTimeout(cycle, 100);
  }

  function draw () {
    var colorOrbit, starGrp, starOrbit, star0, star1, len, cp5, pt0, pt1;

    for (clx; clx < cLen; clx += 1) {

      colorOrbit = orbitalGrp.append('path')
        .attr('id', 'orbit-' + clx)
        .attr('class', 'color-orbit')
        .attr('stroke', colors[clx])
        .attr('d', ellipticalPath(ctrX, ctrY, orbitRx, 192))
        .datum({'color': clx});

      starGrp = starsGrp.append('g')
        .attr('class', 'star-grp');

      starOrbit = starGrp.append('path')
        .attr('id', 'star-orbit-' + clx)
        .attr('class', 'star-orbit')
        .attr('d', ellipticalPath(ctrX, ctrY, orbitRx, 192));

      cp5 = clx + 5 < 10 ? clx + 5 : clx + 5 - 10;
      len = starOrbit.node().getTotalLength();

      pt0 = starOrbit.node().getPointAtLength(len * clx * .1)
      pt1 = starOrbit.node().getPointAtLength(len * cp5 * .1)

      star0 = d3.select(starGrp.node().appendChild(starDef.cloneNode(true)))
        .attr('id', 'star-' + clx + '-0' )
        .attr('transform', 'translate(' + (pt0.x - 32) + ',' + (pt0.y - 32) + ')')
        .datum({ 'step': clx});

      star1 = d3.select(starGrp.node().appendChild(starDef.cloneNode(true)))
        .attr('id', 'star-' + clx + '-1')
        .attr('transform', 'translate(' + (pt1.x - 32) + ',' + (pt1.y - 32) + ')')
        .datum({ 'step': cp5});

      colorOrbit.attr('transform', setOrbitTransform(clx))
      starGrp.attr('transform', setOrbitTransform(clx))
    }
  }

  draw();

  setTimeout(cycle, 100);


</script>
</body>
</html>