Skip to content

Instantly share code, notes, and snippets.

@veltman
Last active July 3, 2016 05:09
Show Gist options
  • Save veltman/250d10e53f9df0a2e507739ad39fbe5b to your computer and use it in GitHub Desktop.
Save veltman/250d10e53f9df0a2e507739ad39fbe5b to your computer and use it in GitHub Desktop.
Loopy tile
<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
stroke-width: 2px;
stroke: #444;
fill: none;
}
line {
stroke-width: 4px;
stroke-linecap: round;
}
circle {
stroke: none;
fill: #444;
}
.done line,
.done circle {
display: none;
}
.done path {
stroke-width: 12px;
fill: url("#crosshatch");
stroke: #0c238d;
}
</style>
<body>
<svg>
<defs>
<pattern id="crosshatch" patternUnits="userSpaceOnUse" width="16" height="16">
<image xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiI+CjxyZWN0IHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0iI2ZmZiI+PC9yZWN0Pgo8cGF0aCBkPSJNMCAwTDE2IDE2Wk0xNiAwTDAgMTZaIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZT0iIzBjMjM4ZCI+PC9wYXRoPgo8L3N2Zz4="
x="0" y="0" width="16" height="16">
</image>
</pattern>
</defs>
</svg>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.16/d3.min.js"></script>
<script>
var margin = { left: 10, right: 10, top: 10, bottom: 10 },
width = 960,
height = 500,
duration = 10000,
size = Math.min(width - margin.left - margin.right, height - margin.top - margin.bottom);
var svg = d3.select("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + ((width - size) / 2) + " " + ((height - size) / 2) + ")");
var colors = ["#ae3cb4", "#ff7146", "#b3e94e"];
var trace = svg.append("path")
.attr("fill-rule", "evenodd")
.datum("M" + size + "," + (size / 2));
var arms = getArms();
var segments = svg.selectAll("line")
.data(arms)
.enter()
.append("line")
.style("stroke",function(d,i){
return colors[i];
});
var pen = svg.append("circle")
.attr("r", 4);
var t = 0;
requestAnimationFrame(update);
function update() {
segments.each(function(arm, i){
var rotation = Math.PI * 2 * t * arm.speed;
arm.start = i ? arms[i - 1].end : [size / 2, size / 2];
arm.end = [
arm.start[0] + arm.length * Math.cos(rotation),
arm.start[1] + arm.length * Math.sin(rotation)
];
d3.select(this)
.attr({
x1: arm.start[0],
y1: arm.start[1],
x2: arm.end[0],
y2: arm.end[1]
})
});
var last = arms[arms.length - 1].end;
trace.datum(trace.datum() + "L" + last.join(","))
.attr("d", Object);
pen.attr("cx", last[0])
.attr("cy", last[1]);
if (t >= duration) {
trace.datum(trace.datum() + "Z");
svg.classed("done", true);
return true;
}
// Manually ticking frames
t += 1000 / 60;
requestAnimationFrame(update);
}
function getArms() {
var lengths = [160, 106, 25];
var rotations = [1,5,21];
var totalLength = d3.sum(lengths);
return lengths.map(function(l,i){
return {
length: (size / 2) * l / totalLength,
speed: -rotations[i] / duration
};
});
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment