Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Animated Civis Analytics Logo

Created by Christopher Manning

Summary

I created this to experiment with SVG rotate, chained transitions, and arc generated paths. I picked my company's logo since it has an interesting design and I had an idea of animating it.

My first attempt had me just using the d3.svg.arc() startAngle and endAngle to create the arcs, but that left the arcs with angled edges when they were rotated to line up. Instead, the arcs are full circles and white rectangles rotate around each arc to give the illusion that the arcs are rotating. This made the rotation easier since "rotating" the arcs only requires updating the rotate transform on the rects.

Controls

  • Click the logo to show the hidden rects.

References

This is not affiliated with or endorsed by Civis Analytics.

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Animated Civis Analytics Logo</title>
<style type="text/css">
body {
padding: 0;
margin: 0;
}
rect, path {
fill: white
}
.corange {
fill: #f4a30f;
}
.cblack {
fill: #434041;
}
.debug {
opacity: .25;
fill: white;
stroke: black;
stroke-width: 2px;
</style>
</head>
<body>
<div style="position:absolute; top:15%; left: 30%; "></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript">
config = {"r": 43, "s": 20}
width = 344
height = 344
debug = false
d3.select(document).on("mousedown", function() {
debug = !debug
d3.selectAll("rect.cover").classed("debug", debug)
})
svg = d3.select("body div").append("svg")
.attr("width", width)
.attr("height", height)
.on("mouseover", function(){
d3.selectAll("rect")
.transition().attr("transform", "rotate(0)")
.transition().delay(250).attr("height", function(d) { return d.i == 1 ? d.height + (config["s"] * 4.25) : d.height })
.transition().delay(500).attr("transform", "rotate(270)")
})
.on("mouseout", function(){
d3.selectAll("rect")
.transition().attr("height", function(d) { return d.height })
.transition().delay(250).attr("transform", function(d) { return "rotate(" + d.r + ")" })
})
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.style("pointer-events", "none")
var deg2rad = Math.PI / 180.0;
var arc = d3.svg.arc()
.startAngle(function(d) { return 0; })
.endAngle(function(d) { return 360; })
.innerRadius(function(d) { return ((d.i) * config["r"]) - config["s"] })
.outerRadius(function(d) { return arc.innerRadius()(d, d.i) + config["s"]})
var g = svg.selectAll("g")
.data([{r: 0, i: 2}, {r: 135, i: 3}, {r: 315, i: 4}, {r: 0, i: 1}])
.enter().append("g");
g.append("path")
.attr("d", arc)
.attr("class", function(d) { return d.i == 1 ? "corange" : "cblack"})
g.append("rect")
.attr("d", arc)
.attr("x", function(d) { return d.i == 1 ? 0 - config["r"]/4 : 0 - config["r"]/1.25})
.attr("y", function(d, i) { return ((d.i) * config["r"]) - config["s"] - (d.i == 1 ? 0 : 10) })
.attr("height", function(d) { return d.height = (d.i == 1 ? config["r"]*1.45 : config["r"]/1.25)})
.attr("width", function(d) { return d.i == 1 ? config["r"]/2 : config["r"]*1.5})
.attr("class", function(d) { return d.i == 1 ? "corange" : "cover"})
.attr("transform", function(d) { return "rotate(" + d.r + ")" })
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.