var margin = {top: 10,right: 0,bottom: 50,left: 0}; var width = 700 - margin.left - margin.right - 10, height = 500 - margin.top - margin.bottom - 20; //SVG container var svg = d3.select('#gooContainer') .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + 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","gooeyCodeFilter"); filter.append("feGaussianBlur") .attr("in","SourceGraphic") .attr("stdDeviation","10") //to fix safari: http://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"); //Create gradients var gradients ={ green:["#0AAF00","#00ff0e","#aaff5b","#f7ffa7"], purple:["#520076","#c53ffe","#e297fe","#f4d6ff"], red:["#950c14","#fb3930","#fb673c","#fcaa44"], gray:["#2a2a2a","#545454","#7e7e7e","#d3d3d3"] } defs.append("linearGradient") .attr("id", "lavaGradient") .attr("gradientUnits", "userSpaceOnUse") .attr("y1", -height/2*0.85).attr("x1", 0) .attr("y2", height/2*0.85).attr("x2", 0) .selectAll("stop") .data(d3.range(gradients.green.length)) .enter().append("stop") .attr("offset", function(d,i) { return (i/(gradients.green.length-1)*100) + "%"; }) .attr("stop-color", function(d) { return gradients.green[d]; }); defs.append("clipPath") .attr("id", "clip") .append("ellipse") .attr("cx",width/2) .attr("cy",height/2) .attr("rx",width/12) .attr("ry",height/2); defs.append("clipPath") .attr("id", "clip_cap") .append("ellipse") .attr("cx",width/2) .attr("cy",(height/2)) .attr("rx",(width/12)+2) .attr("ry",(height/2)+2); svg.append("ellipse") .attr("class","water") .attr("cx",width/2) .attr("cy",height/2) .attr("rx",width/12) .attr("ry",height/2) .style("fill", "#AAD4E0"); //First append a group for the clip path, then a new group that can be transformed var circleWrapper = svg.append("g") .attr("clip-path", "url(#clip") .style("clip-path", "url(#clip)") //make it work in safari .append("g") .attr("transform", "translate(" + (width/2) + "," + (height/2) + ")") .style("filter", "url(#gooeyCodeFilter)"); //Create dataset with random radius randStart = []; for(var i = 0; i < 20; i++) { randStart.push({ r: 15 + Math.random()*10 }); } var circle = circleWrapper.selectAll(".dots") .data(randStart) .enter().append("circle") .attr("class", "dots") .attr("cx", 0) .attr("cy", function(d){return (height/2)-d.r;}) .attr("r", function(d){return d.r}) .style("fill", "url(#lavaGradient)") .style("opacity", 1) .each(move); var footer = circleWrapper.selectAll(".footer") .data([{r:50}]) .enter().append("circle") .attr("class", "footer") .attr("cx", 0) .attr("cy", function(d){return (height/2)-(d.r)}) .attr("r", function(d){return d.r}) .style("fill", "url(#lavaGradient)") .style("opacity", 1); var header = circleWrapper.selectAll(".header") .data([{r:50}]) .enter().append("circle") .attr("class", "header") .attr("cx", 0) .attr("cy", function(d){return (-height/2)+d.r}) .attr("r", function(d){return d.r}) .style("fill", "url(#lavaGradient)") .style("opacity", 1); svg.append("ellipse") .attr("class","ellipse") .attr("cx",width/2) .attr("cy",height/2) .attr("rx",width/12) .attr("ry",height/2) .style("stroke", "#6C6C6C") .style("stroke-width", "4px") .style("fill", "none"); svg.append("rect") .attr("class","cap") .attr("clip-path", "url(#clip_cap") .style("clip-path", "url(#clip_cap)") //make it work in safari .attr("x",width/4) .attr("y",-10) .attr("height",75) .attr("width",width) .style("fill", "black"); function changeColor(){ var selectedColor = document.getElementById("color-select") .options[document.getElementById("color-select").selectedIndex].value; d3.select("#lavaGradient") .selectAll("stop") .transition("change-color").duration(3000) .attr("stop-color", function(d) { return gradients[selectedColor][d]; }); } function move(d) { var currenty = parseFloat(d3.select(this).attr("cy")); var newx = (Math.random() <0.5)?-Math.random()*50:Math.random()*50; var newy = currenty*-1; //Transition the circle to its new location d3.select(this) .transition("move") .duration(8000+8000*Math.random()) .ease("easeInQuart") .attr("cy", newy) .attr("cx", newx) .attr("r",function(){return 15 + Math.random()*10}) .each("end", move) }