Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active July 8, 2019 00:08
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 HarryStevens/14346a5a472066401c6b6e7ab7a9f89b to your computer and use it in GitHub Desktop.
Save HarryStevens/14346a5a472066401c6b6e7ab7a9f89b to your computer and use it in GitHub Desktop.
Math and Boxes II
license: gpl-3.0

Use the sliders to adjust the number of boxes and the speed of rotation. Drag the "Rotation speed" slider all the way to the left to disable rotation.

Inspired by this YouTube video.

For the rainbow version, see this block.

<html>
<head>
<style>
body {
margin: 0;
font-family: "Helvetica Neue", sans-serif;
}
.box {
stroke: #fff;
fill: #3a403d;
}
.label-wrapper {
top: 10px;
position: absolute;
width: 20%;
}
.label-wrapper.rotation-speed {
left: 20%;
}
.label {
width: 100%;
margin-left: 5%;
text-shadow: -3px -3px 1px rgba(255, 255, 255, 0.4), -3px -2px 1px rgba(255, 255, 255, 0.4), -3px -1px 1px rgba(255, 255, 255, 0.4), -3px 0px 1px rgba(255, 255, 255, 0.4), -3px 1px 1px rgba(255, 255, 255, 0.4), -3px 2px 1px rgba(255, 255, 255, 0.4), -3px 3px 1px rgba(255, 255, 255, 0.4), -2px -3px 1px rgba(255, 255, 255, 0.4), -2px -2px 1px rgba(255, 255, 255, 0.4), -2px -1px 1px rgba(255, 255, 255, 0.4), -2px 0px 1px rgba(255, 255, 255, 0.4), -2px 1px 1px rgba(255, 255, 255, 0.4), -2px 2px 1px rgba(255, 255, 255, 0.4), -2px 3px 1px rgba(255, 255, 255, 0.4), -1px -3px 1px rgba(255, 255, 255, 0.4), -1px -2px 1px rgba(255, 255, 255, 0.4), -1px -1px 1px rgba(255, 255, 255, 0.4), -1px 0px 1px rgba(255, 255, 255, 0.4), -1px 1px 1px rgba(255, 255, 255, 0.4), -1px 2px 1px rgba(255, 255, 255, 0.4), -1px 3px 1px rgba(255, 255, 255, 0.4), 0px -3px 1px rgba(255, 255, 255, 0.4), 0px -2px 1px rgba(255, 255, 255, 0.4), 0px -1px 1px rgba(255, 255, 255, 0.4), 0px 1px 1px rgba(255, 255, 255, 0.4), 0px 2px 1px rgba(255, 255, 255, 0.4), 0px 3px 1px rgba(255, 255, 255, 0.4), 1px -3px 1px rgba(255, 255, 255, 0.4), 1px -2px 1px rgba(255, 255, 255, 0.4), 1px -1px 1px rgba(255, 255, 255, 0.4), 1px 0px 1px rgba(255, 255, 255, 0.4), 1px 1px 1px rgba(255, 255, 255, 0.4), 1px 2px 1px rgba(255, 255, 255, 0.4), 1px 3px 1px rgba(255, 255, 255, 0.4), 2px -3px 1px rgba(255, 255, 255, 0.4), 2px -2px 1px rgba(255, 255, 255, 0.4), 2px -1px 1px rgba(255, 255, 255, 0.4), 2px 0px 1px rgba(255, 255, 255, 0.4), 2px 1px 1px rgba(255, 255, 255, 0.4), 2px 2px 1px rgba(255, 255, 255, 0.4), 2px 3px 1px rgba(255, 255, 255, 0.4), 3px -3px 1px rgba(255, 255, 255, 0.4), 3px -2px 1px rgba(255, 255, 255, 0.4), 3px -1px 1px rgba(255, 255, 255, 0.4), 3px 0px 1px rgba(255, 255, 255, 0.4), 3px 1px 1px rgba(255, 255, 255, 0.4), 3px 2px 1px rgba(255, 255, 255, 0.4), 3px 3px 1px rgba(255, 255, 255, 0.4);
}
input {
width: 90%;
margin-left: 5%;
}
</style>
</head>
<body>
<div id="canvas">
<div class="label-wrapper box-count">
<div class="label">Box count</div>
<input class="count" type="range" min="1" max="100" value="50"></input>
</div>
<div class="label-wrapper rotation-speed">
<div class="label">Rotation speed</div>
<input class="speed" type="range" min="0" max="3" value="1" step=".1"></input>
</div>
</div>
<script src="https://d3js.org/d3-array.v2.min.js"></script>
<script src="https://d3js.org/d3-selection.v1.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v1.min.js"></script>
<script src="https://d3js.org/d3-timer.v1.min.js"></script>
<script src="https://d3js.org/d3-scale.v3.min.js"></script>
<script>
let width,
height,
center,
l,
m,
count = 50,
speed = 1,
rotation = 0;
const svg = d3.select("#canvas").append("svg");
const g = svg.append("g");
d3.selectAll("input").on("input", function(){
count = +d3.select("input.count").property("value");
speed = +d3.select("input.speed").property("value");
draw();
});
d3.timer(_ => {
rotation += speed;
g.attr("transform", "rotate(" + rotation + " " + center[0] + " " + center[1] + ")");
});
size();
onresize = size;
function draw(){
const s = d3.scaleLinear().domain([1, count]).range([1, 10]);
let sum = 0;
const boxes = g.selectAll(".box")
.data(d3.range(count + 1));
boxes.exit().remove();
boxes.enter().append("rect")
.attr("class", "box")
.merge(boxes)
.attr("x", d => center[0] - ((m * d / count) / 2))
.attr("y", d => center[1] - ((m * d / count) / 2))
.attr("width", d => m * d / count)
.attr("height", d => m * d / count)
.attr("transform", d => {
sum += d;
const theta = sum / d * Math.PI;
return theta ? `rotate(${theta + (d * (360 / count))} ${center[0]} ${center[1]})` : null;
})
.style("stroke-width", d => s(d))
.lower();
}
function size(){
width = innerWidth;
height = innerHeight;
center = [width / 2, height / 2];
l = Math.min(width, height);
m = Math.max(width, height);
svg
.attr("width", width)
.attr("height", height);
g
.attr("width", l)
.attr("height", l);
draw();
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment