Skip to content

Instantly share code, notes, and snippets.

@veltman
Last active September 28, 2016 15:00
Show Gist options
  • Save veltman/1991fb321f8e91f00c7c to your computer and use it in GitHub Desktop.
Save veltman/1991fb321f8e91f00c7c to your computer and use it in GitHub Desktop.
Rainbow spiral II
<!DOCTYPE html>
<meta charset="utf-8">
<style>
path {
fill: url(#rainbow);
stroke: #444;
stroke-width: 1px;
}
</style>
<body>
<script src="//d3js.org/d3.v4.0.0-alpha.18.min.js"></script>
<script>
var rainbow = d3.scaleRainbow(); // lazy
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.14/d3.min.js"></script>
<script>
var width = 960,
height = 500,
cx = width / 2,
cy = height / 2;
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var gradient = svg.append("defs")
.append("radialGradient")
.attr("id","rainbow");
gradient
.selectAll("stop")
.data(d3.range(0,1,0.04))
.enter()
.append("stop")
.attr("offset",function(d){
return d;
})
.attr("stop-color",rainbow)
.each(rotateColor);
var spiral = svg.append("g")
.each(rotate);
spiral.append("path")
.attr("d",getSpiral());
function getSpiral() {
var inward = [],
outward = [],
rotation = 80 * Math.PI / 180; // rotation of each side from the center spiral
var maxAngle = Math.PI * 2 * 18; // max turn (radians)
var distance = d3.scale.sqrt()
.domain([0,maxAngle])
.range([0.25,5]); // distance between turnings
d3.range(0,maxAngle + rotation * 2,0.05).forEach(function(angle){
var a = distance(angle);
var point = [
cx + (a * angle) * Math.cos(angle),
cy + (a * angle) * Math.sin(angle)
];
inward.unshift(rotatePoint(point,-rotation));
if (angle < maxAngle) {
outward.push(rotatePoint(point,rotation));
}
});
return "M" + inward.join("L") + "L" + outward.join("L") + "Z";
}
function rotatePoint(point,rad) {
var x1 = point[0] - cx,
y1 = point[1] - cy;
var x2 = x1 * Math.cos(rad) - y1 * Math.sin(rad);
var y2 = x1 * Math.sin(rad) + y1 * Math.cos(rad);
return [x2 + cx,y2 + cy];
}
function rotateColor() {
d3.select(this).transition()
.duration(4000)
.ease("linear")
.attrTween("stop-color",function(d){
return function(t) {
return rainbow((d + t) % 1);
};
})
.each("end",rotateColor);
}
function rotate() {
d3.select(this).transition()
.duration(4000)
.ease("linear")
.attrTween("transform",function(){
return function(t) {
return "rotate(" + (t * 360) + " " + cx + " " + cy + ")";
};
})
.each("end",rotate);
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment