A canvas version of this rainbow spinner.
Last active
July 3, 2016 05:09
-
-
Save veltman/259819801c0ff504d59ace06a9a6faec to your computer and use it in GitHub Desktop.
Rainbow spinner #2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
</head> | |
<body> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script> | |
var width = 960, | |
height = 500; | |
var context = d3.select("body").append("canvas") | |
.attr("width", width) | |
.attr("height", height) | |
.node() | |
.getContext("2d"); | |
var arc = d3.arc() | |
.context(context); | |
var angles = { | |
start: 0, | |
end: 5 / 8 | |
}; | |
context.translate(width / 2, height / 2); | |
stretch("start"); | |
d3.timer(function(t){ | |
angles.offset = t / 5000; | |
draw(); | |
}); | |
function draw() { | |
context.clearRect(0, 0, width, height); | |
arc.innerRadius(175) | |
.outerRadius(210); | |
d3.range(0, 181).forEach(function(deg){ | |
context.fillStyle = context.strokeStyle = d3.interpolateRainbow(deg / 180); | |
var start = angles.offset + deg / 180, | |
end = start + 1 / 180; | |
arc.startAngle(start * Math.PI * 2) | |
.endAngle(end * Math.PI * 2); | |
context.beginPath(); | |
arc(); | |
context.fill(); | |
context.stroke(); | |
}); | |
// lazy clip | |
context.fillStyle = context.strokeStyle = "#fff"; | |
context.beginPath(); | |
arc.startAngle((angles.offset + angles.end) * Math.PI * 2) | |
.endAngle((angles.offset + angles.start + 1) * Math.PI * 2) | |
.innerRadius(170) | |
.outerRadius(215)(); | |
context.fill(); | |
context.stroke(); | |
} | |
function stretch(type) { | |
var interpolate = d3.interpolateNumber(angles[type], angles[type] + 9 / 16); | |
d3.select("body").transition() | |
.delay(500) | |
.duration(1000) | |
.tween("angle", function(){ | |
return function(t){ | |
angles[type] = interpolate(t); | |
}; | |
}) | |
.on("end", function(){ | |
stretch(type === "start" ? "end" : "start"); | |
}); | |
} | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment