Skip to content

Instantly share code, notes, and snippets.

@sxywu
Last active May 3, 2019 14:26
Show Gist options
  • Save sxywu/408b80e2e186c481b9ee99d86d116781 to your computer and use it in GitHub Desktop.
Save sxywu/408b80e2e186c481b9ee99d86d116781 to your computer and use it in GitHub Desktop.
Gooey Circle Effect with Colors

I was most fascinated by Nadieh's gooey example from her OpenVis Conf talk, and especially with the gooey color blending. After reading her blog post, I decided to give the circles some colors - and it turned out to be as straightforward as I was hoping for.

The only two things I had to change:

  • add a colorScale and replace the circles' fills with the colorScale outputs

  • remove feComposite from the filters (I'm looking into why this is)

Thank you Nadieh for your brilliance 💕

--

forked from nbremer's block: Gooey Effect - Circle

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/ >
<title>Gooey Effect</title>
<script src="http://d3js.org/d3.v3.min.js"></script>
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Bootstrap 3 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
</head>
<body>
<div id="cont" class="container-fluid">
<div class="row text-center">
<div class="col-sm-12 column text-center">
<div class="chart"></div>
</div>
</div>
</div>
<script>
//////////////////////////////////////////////////////////////
//////////////////////// Initiate ////////////////////////////
//////////////////////////////////////////////////////////////
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
totalHeight = w.innerHeight || e.clientHeight || g.clientHeight;
var margin = {top: 30, right: 30, bottom: 30, left: 30};
width = Math.min(500, (totalHeight - 20), $(".chart").width() - margin.left - margin.right);
height = width;
//Create scale
var xScale = d3.scale.linear()
.domain([-1.5, 1.5])
.range([-width/2, width/2]);
// color from http://colrd.com/palette/24070/
var colors = ["#1a1334", "#26294a", "#01545a", "#017351", "#03c383", "#aad962",
"#fbbf45", "#ef6a32", "#ed0345", "#a12a5e", "#710162", "#110141"];
var colorScale = d3.scale.ordinal().range(colors);
//Create SVG
var svg = d3.select(".chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.style("filter", "url(#gooey)") //Set the filter on the container svg
.attr("transform", "translate(" + (width/2 + margin.left) + "," +(height/2 + margin.top) + ")");
//SVG filter for the gooey effect
//Code taken from http://tympanus.net/codrops/2015/03/10/creative-gooey-effects/
var defs = svg.append('defs');
var filter = defs.append('filter').attr('id','gooey');
filter.append('feGaussianBlur')
.attr('in','SourceGraphic')
.attr('stdDeviation','10')
.attr('result','blur');
filter.append('feColorMatrix')
.attr('in','blur')
.attr('mode','matrix')
.attr('values','1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7');
// (swu): commenting out the feComposite actually makes the color blend
// I wonder why that is?
// filter.append('feComposite')
// .attr('in','SourceGraphic')
// .attr('in2','gooey')
// .attr('operator','atop');
//Append circle at center
svg.append("circle")
.attr("class", "centerCircle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", 20)
.style("fill", "#cfcfcf");
//Create the circles that will move out and in the center circle
var steps = 12;
svg.selectAll(".flyCircle")
.data(d3.range(steps).map(function(num) {return (num/steps)*(2*Math.PI); }))
.enter().append("circle")
.attr("class", "flyCircle")
.attr("cx", 0)
.attr("cy", 0)
.attr("r", 15)
.style("fill", function(d, i) {return colorScale(i)})
.call(update);
//Continuously moves the circles outward and inward
function update() {
var circle = d3.selectAll(".flyCircle");
var dur = 1500,
del = 500;
(function repeat() {
circle
.transition("outward").duration(dur).delay(function(d,i) { return i*del; })
.attr("cy", function(d) { return xScale(Math.sin(d)); })
.attr("cx", function(d) { return xScale(Math.cos(d)); })
.transition("inward").duration(dur).delay(function(d,i) { return steps*del + i*del; })
.attr("cx", 0)
.attr("cy", 0)
.call(endall, repeat);
})();
}//update
//Taken from https://groups.google.com/forum/#!msg/d3-js/WC_7Xi6VV50/j1HK0vIWI-EJ
//Calls a function only after the total transition ends
function endall(transition, callback) {
var n = 0;
transition
.each(function() { ++n; })
.each("end", function() { if (!--n) callback.apply(this, arguments); });
}//endall
</script>
</body>
</html>
@akashwadhwani
Copy link

This is brilliant.

Is there a way to get more circles out of the circles which are coming out?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment