Skip to content

Instantly share code, notes, and snippets.

@kenpenn
Last active July 18, 2017 18:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenpenn/911d741a436e8c1ed1d25dbf846fb966 to your computer and use it in GitHub Desktop.
Save kenpenn/911d741a436e8c1ed1d25dbf846fb966 to your computer and use it in GitHub Desktop.
viz for viSFest 2017
license: gpl-3.0
height: 960

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

<!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="http://www.w3.org/2000/svg" xmlns:xlink="http://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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment