block by olearym ec27b9ac1bf0da42ed8a0d533181693b

Modular Multiplication Circle

Full Screen

Inspired by this video by Mathologer.

index.js

function main() {

	var width = 960;
	var height = 500;
	var margin = 10;
	var container = d3.select("#container");
	var svg = container.append("svg")
		.attr("width", width)
		.attr("height", height);

	var g = svg.append("g")
		.attr("transform", "translate(" + width/2 + "," + height/2 + ")");
	var mod = 0;
	var radius = (d3.min([height, width]) - (2 * margin)) / 2;
	var max = 250;

	var scale = d3.scaleLinear()
		.domain([0, max])
		.range([0, 2 * Math.PI]);

	var colorScale = d3.scaleSequential(d3.interpolateRainbow)
		.domain([0, max/10]);

	var circle = g.append("circle")
		.attr("r", radius)
		.attr("fill", "none")
		.attr("stroke", colorScale(mod));

	var lines = g.selectAll("line")
		.data(Array.apply(null, Array(max)).map(function (_, i) { return i; } ))

	lines.enter().append("line");

	var tick = 100;
	setInterval(function() {

		g.selectAll("circle").transition()
			.duration(tick)
			.attr("stroke", colorScale(mod));

		g.selectAll("line").transition()
			.duration(tick)
			.attr("x1", function(d) {
				return radius * Math.cos(scale(d));
			})
			.attr("y1", function(d) {
				return radius * Math.sin(scale(d));
			})
			.attr("x2", function(d) {
				return radius * Math.cos(scale(mod*d));
			})
			.attr("y2", function(d) {
				return radius * Math.sin(scale(mod*d));
			})
			.attr("stroke", colorScale(mod));

		if (mod < 250) {
			mod = mod + .1;
		} else {
			mod = 0;
		}

	}, tick)

}

window.onload = main;

index.html

<html>
  <head>
    <meta charset="utf-8">
    <title>Modular Multiplication Circle</title>
  </head>
  
  <body>
  	<div id="container"></div>
  </body>

  <script src="https://d3js.org/d3.v4.min.js"></script>
  <script src="index.js"></script>
</html>