Skip to content

Instantly share code, notes, and snippets.

@headwinds
Last active April 26, 2016 16:43
Show Gist options
  • Save headwinds/98fadafeff932b17b274 to your computer and use it in GitHub Desktop.
Save headwinds/98fadafeff932b17b274 to your computer and use it in GitHub Desktop.
Slinky Chained Transitions
license: gpl-3.0
<!DOCTYPE html>
<meta charset="utf-8">
<style>
circle {
fill: #000;
}
body{
width:100%;
height: 100%;
}
#serpent {
width:100%;
height: 100%;
}
svg {
width:100%;
height: 100%;
}
</style>
<body>
<div id="serpent">
<svg id="viewport" width="1000" height="1000">
<filter id="fancy-goo">
<feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 19 -9" result="goo" />
<feComposite in="SourceGraphic" in2="goo" operator="atop"/>
</filter>
</svg>
</div>
<script src="//d3js.org/d3.v4.0.0-alpha.28.min.js"></script>
<script>
/*
http://bimba.info/en/new/2016/04/17/huge-prehistoric-whales-found-in-egyptian-desert
*/
var margin = {top: 40, right: 40, bottom: 40, left: 40},
width = 1000 - margin.left - margin.right,
height = 1000 - margin.top - margin.bottom;
var y = d3.scalePoint()
.domain(d3.range(20))
.range([0, height]);
var z = d3.scaleLinear()
.domain([10, 0])
.range(["hsl(62,100%,90%)", "hsl(228,30%,20%)"])
.interpolate(d3.interpolateHcl);
var svg = d3.select("#viewport")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
var defs = svg.append('defs');
// gooey seems to perform better than fancy-goo
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')
.attr('result','gooey');
filter.append('feComposite')
.attr('in','SourceGraphic')
.attr('in2','gooey')
.attr('operator','atop');
svg
.append("g")
.style("filter", "url(#gooey)")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// svg:ellipse cx="0" cy="0" rx="0" ry="0"
var getAngle = function(shipPoint, targetPoint) {
var cx = shipPoint.x;
var cy = shipPoint.y;
var ex = targetPoint.x;
var ey = targetPoint.y;
var dy = ey - cy;
var dx = ex - cx;
var theta = Math.atan2(dy, dx); // range (-PI, PI]
theta *= 180 / Math.PI; // rads to degs, range (-180, 180]
//if (theta < 0) theta = 360 + theta; // range [0, 360)
return theta;
}
svg.selectAll("ellipse")
.data(y.domain())
.enter().append("ellipse")
.attr("rx", 25)
.attr("ry", 75)
.attr("cx", 0)
.attr("cy", y)
.style("fill", function(d) { return z(Math.abs(d % 20 - 10)); })
.transition()
.duration(3500)
.delay(function(d) { return d * 90; })
.on("start", slide);
var end = {x: 500, y: 500};
var start = {x: 0, y: 0};
function onSlideComplete(){
end.x = Math.floor( Math.random() * width);
end.y = Math.floor( Math.random() * height);
start.x = 0;
start.y = Math.floor( Math.random() * height);
}
/* todo
- change the rotation so the disc points in the direction of the next point
- apply a sine wave or something to the body
*/
//var rotate = d3.svg.transform().rotate(-45);
var getTransform = function(ship,target){
var shipX = d3.select(ship).attr("cx");
var shipY = d3.select(ship).attr("cy");
var shipPoint = {x:shipX,y:shipY};
var targetPoint = {x:target.x,y:target.y};
var angle = getAngle(shipPoint, targetPoint);
return "translate(" + target.x + "," + target.y + ") rotate(" + angle + ")"
}
function slide() {
d3.active(this)
.attr("cy", end.x)
.attr("cx", end.y)
//.attr("transform", getTransform(this,end) )
.transition()
.attr("cx", start.x)
.attr("cy", start.y)
//.attr("transform", getTransform(this,start) )
.transition()
.on("start", slide)
.on("end", onSlideComplete);
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment