block by nbremer e563beea62ef820883410ca0f5be6fa3

Gooey effect - Rotating circles - Non-blending colors

Full Screen

This example appears on my blog on More fun data visualizations with the gooey effect

The SVG Gooey effect is created by applying an SVG filter to a group element in which the circles are created. In this version the colors do not blend nicely because I’ve placed the original sharp SVG shape back on top the blurred one.

By placing the original shape back on top we can assure that the eventual SVG elements are still the correct size

To see the same visual, but with the last step of the filter removed, so that the colors blend in nicely, please check out my other bl.ock: Gooey effect Rotating circles Blending colors

You can find the other examples from the blog here

Older examples with the Gooey effect

Built with blockbuilder.org

index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		
		<!-- D3.js -->
		<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>

	</head>	
	<body>

		<div id="chart" style="text-align: center;"></div>

		<script language="javascript" type="text/javascript">

			///////////////////////////////////////////////////////////////////////////
			//////////////////// Set up and initiate svg containers ///////////////////
			///////////////////////////////////////////////////////////////////////////	

			var margin = {
				top: 10,
				right: 10,
				bottom: 10,
				left: 10
			};
			var width = 400,
				height = 400;
						
			//SVG container
			var svg = d3.select('#chart')
				.append("svg")
				.attr("width", width + margin.left + margin.right)
				.attr("height", height + margin.top + margin.bottom)
				.append("g")
				.attr("transform", "translate(" + (margin.left + width/2) + "," + (margin.top + height/2) + ")");

			///////////////////////////////////////////////////////////////////////////
			///////////////////////////// Create filter ///////////////////////////////
			///////////////////////////////////////////////////////////////////////////	

			//SVG filter for the gooey effect
			//Code taken from //tympanus.net/codrops/2015/03/10/creative-gooey-effects/
			var defs = svg.append("defs");
			var filter = defs.append("filter").attr("id","gooeyCodeFilter");
			filter.append("feGaussianBlur")
				.attr("in","SourceGraphic")
				.attr("stdDeviation","10")
				//to fix safari: //stackoverflow.com/questions/24295043/svg-gaussian-blur-in-safari-unexpectedly-lightens-image
				.attr("color-interpolation-filters","sRGB") 
				.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 19 -9")
				.attr("result","gooey");
			//If you want the end shapes to be exactly the same size as without the filter
			//add the feComposite below. However this will result in a less beautiful gooey effect
			filter.append("feBlend")
				.attr("in","SourceGraphic")
				.attr("in2","gooey");
			//Instead of the feBlend, you can do feComposite. This will also place a sharp image on top
			//But it will result in smaller circles
			// filter.append("feComposite") //feBlend
			// 	.attr("in","SourceGraphic")
			// 	.attr("in2","gooey")
			// 	.attr("operator","atop");

		///////////////////////////////////////////////////////////////////////////
		/////////////////////////// Create circles ////////////////////////////////
		///////////////////////////////////////////////////////////////////////////	

		//Create scale
		var xScale = d3.scale.linear()
			.domain([-1.25, 1.25])
			.range([-width/2, width/2]);
	
		//Create a wrapper for the circles that has the Gooey effect applied to it
		var circleWrapper = svg.append("g")
			.style("filter", "url(#gooeyCodeFilter)");

		//Create the circles that will move out and in the center circle
		var steps = 14;
		var colors = ["#F95B34", "#EE3E64", "#F36283", "#FF9C34", "#EBDE52", "#B7D84B", "#44ACCF"];
		var flyCircleData = [];
		for (var i = 0; i < steps; i++) {
			flyCircleData.push({ 
				fixedAngle: (i/steps)*(2*Math.PI),
				randomAngle: (i/steps)*(2*Math.PI),
				speed: Math.random() * 7000 + 3000,
				r: Math.floor(Math.random() * 20 + 15),
				color: colors[i%colors.length]
			})
		}//for i

		//Set up the circles
		var flyCircles = circleWrapper.selectAll(".flyCircle")
			.data(flyCircleData)
			.enter().append("circle")
			.attr("class", "flyCircle")
			.style("fill", function(d) { return d.color; })
			.attr("cy", 0)
			.attr("cx", 0)
			.attr("r", 0)
			.transition().duration(500)//.delay(function(d,i) { return i*50; })
			.attr("cy", function(d) { return xScale(Math.sin(d.fixedAngle)); })
			.attr("cx", function(d) { return xScale(Math.cos(d.fixedAngle)); })
			.attr("r", function(d) { return d.r; })
			.each("end", goRound);
		
		//Continuously moves the circles with different speeds
		function goRound(d) {
			d3.select(this)
				.transition().duration(function(d) { return d.speed; })
				.ease("linear")
				.attrTween("transform", function() { return d3.interpolateString("rotate(0)", "rotate(360)"); })
				.each("end", goRound);
		}//function goRound
									
		</script>

	</body>
</html>