Last active
December 10, 2015 10:18
-
-
Save amiika/4419701 to your computer and use it in GitHub Desktop.
Happy New Year with D3!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="http://d3js.org/d3.v3.min.js"></script> | |
<style type="text/css"> | |
body { background: #151515;} | |
circle { fill: none;stroke-width: 2.5px;} | |
</style> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
// Firework colors | |
var z = ["#E0F2FC","#F7921E","#EA1D22","#29AAE4","#652D92","#D2D3D5","#3AB54A","#FFDD1C","#FDD017"]; | |
var width = 960, | |
height = 500; | |
var svg = d3.select("body").append("svg:svg"); | |
svg.attr("width", width); | |
svg.attr("height", height); | |
svg.style("pointer-events", "all"); | |
var filter = svg.append("svg:defs") | |
.append("svg:filter") | |
.attr("id", "blur") | |
.attr("width","500%") | |
.attr("height","500%"); | |
filter.append("svg:feOffset") | |
.attr("result","offOut") | |
.attr("in","SourceGraphic") | |
.attr("dx",100) | |
.attr("dy",100); | |
filter.append("svg:feGaussianBlur") | |
.attr("result","blurOut") | |
.attr("in","SourceGraphic") | |
.attr("stdDeviation", 10); | |
filter.append("svg:feBlend") | |
.attr("in2","blurOut") | |
.attr("in","SourceGraphic") | |
.attr("mode","lighten"); | |
// Particle class | |
var Particle = function(pos, target, explode, control, color) { | |
// Create quadratic path from pos to target | |
var path = svg.append("svg:path") | |
.style("fill","none") | |
.attr("d","M"+pos.x+","+pos.y+" Q"+control.x+","+control.y+" "+target.x+","+target.y) | |
// Color for path debugging | |
//.attr("stroke","white"); | |
var totalLength = path.node().getTotalLength(); | |
if(explode) { | |
// Draw particle for explosion | |
var particle = svg.append("svg:circle") | |
.attr("r", 5) | |
.style("fill",color) | |
.transition() | |
.duration(400) | |
.ease(Math.sqrt) | |
.attrTween("transform", translateAlong(path.node(),color)) | |
.attr("r",3) | |
.each("end",function(d) { | |
d3.select(this).transition().duration(2000).ease("exp-out").attr("r",1).style("fill-opacity", 1e-6).attr("cx",Math.floor(Math.random() * (50 + 50)-50) ).attr("cy",Math.random()*200).remove(); | |
path.remove(); | |
}); | |
} | |
else { | |
// Draw "rocket"-path | |
path | |
.attr("stroke","yellow") | |
.attr("stroke-width",3) | |
.style("stroke-opacity", 0.5) | |
.attr("filter", "url(#blur)") | |
.attr("stroke-dasharray", totalLength + " " + totalLength) | |
.attr("stroke-dashoffset", totalLength) | |
.transition() | |
.duration(800) | |
.ease("cubic-in-out") | |
.attr("stroke-width",2) | |
.style("stroke-opacity", 1e-6) | |
.attr("stroke-dashoffset", -totalLength) | |
.remove() | |
.each("end",function(d) { | |
//Explode with timeout | |
setTimeout("explode("+target.x+","+target.y+",'"+color+"',"+Math.floor(Math.random()*(50-5)+5)+")",200); | |
}); | |
} | |
function translateAlong(path,color) { | |
var l = path.getTotalLength(); | |
return function(d, i, a) { | |
return function(t) { | |
var p = path.getPointAtLength(t * l); | |
// Create some sparkle along the path | |
sparkle(p.x,p.y,4,500,color); | |
return "translate(" + p.x + "," + p.y + ")"; | |
}; | |
}; | |
} | |
function sparkle(x,y,r,dur,color) { | |
svg.append("svg:circle") | |
.attr("r", r) | |
.style("fill",color) | |
.attr("filter", "url(#blur)") | |
.attr("cy",y) | |
.attr("cx",x) | |
.transition() | |
.duration(500) | |
.ease(Math.sqrt) | |
.attr("r", 1) | |
.style("fill-opacity", 1e-6) | |
.remove() | |
} | |
}; | |
// "Explodes" the particle. | |
function explode(x,y,color,count) { | |
var mx = Math.floor(Math.random()*400-150)+150; | |
// Creates new particles around the current x,y | |
while(count--) new Particle({x:x,y:y},randXY(x,y,Math.floor(Math.random() * (mx - mx-50 + 1)) + mx-50),true,{x:x,y:y-100},color); | |
} | |
// Returns random point around the circle | |
function randXY(x,y,w) { | |
var rand = Math.random(); | |
var ag = rand * Math.PI * 2; | |
var xl = x + Math.cos(ag) * w; | |
var yl = y + Math.sin(ag) * w; | |
return {x:xl,y:yl}; | |
} | |
// Fires new rocket | |
function fire() { | |
var color = z[Math.floor ( Math.random() * z.length )]; | |
new Particle({x:width,y:height},{x:Math.floor(Math.random() * (width - 200) + 200),y:Math.floor(Math.random() * (height/2 - 200) + 200)},false,{x:height,y:width-200},color); | |
} | |
var rockets = 10; | |
while(rockets--) setTimeout("fire()",2000*rockets); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment