Skip to content

Instantly share code, notes, and snippets.

@EmilienDupont
Last active June 5, 2016 12:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EmilienDupont/13bbd43aa30acf3acb2460811b4bfa83 to your computer and use it in GitHub Desktop.
Save EmilienDupont/13bbd43aa30acf3acb2460811b4bfa83 to your computer and use it in GitHub Desktop.
Dragonfly Morphing
{
"body" : [{"x":441,"y":229},{"x":439,"y":239},{"x":434,"y":246},{"x":424,"y":254},{"x":416,"y":258},{"x":404,"y":263},{"x":393,"y":266},{"x":381,"y":271},{"x":364,"y":275},{"x":350,"y":276},{"x":333,"y":278},{"x":319,"y":279},{"x":305,"y":279},{"x":295,"y":276},{"x":276,"y":274},{"x":256,"y":274},{"x":236,"y":271},{"x":221,"y":267},{"x":201,"y":263},{"x":187,"y":254},{"x":181,"y":243},{"x":187,"y":229},{"x":203,"y":218},{"x":214,"y":213},{"x":230,"y":208},{"x":248,"y":206},{"x":265,"y":204},{"x":282,"y":200},{"x":298,"y":198},{"x":310,"y":198},{"x":320,"y":197},{"x":332,"y":197},{"x":344,"y":192},{"x":359,"y":186},{"x":373,"y":182},{"x":385,"y":177},{"x":399,"y":175},{"x":411,"y":172},{"x":426,"y":170},{"x":428,"y":165},{"x":422,"y":168},{"x":411,"y":169},{"x":394,"y":171},{"x":375,"y":176},{"x":354,"y":177},{"x":338,"y":177},{"x":318,"y":176},{"x":301,"y":173},{"x":281,"y":168},{"x":268,"y":162},{"x":250,"y":155},{"x":228,"y":148},{"x":212,"y":138},{"x":199,"y":130},{"x":188,"y":123},{"x":179,"y":113},{"x":176,"y":102},{"x":184,"y":93},{"x":193,"y":89},{"x":204,"y":86},{"x":216,"y":86},{"x":228,"y":88},{"x":242,"y":93},{"x":259,"y":96},{"x":275,"y":99},{"x":294,"y":105},{"x":314,"y":110},{"x":330,"y":110},{"x":347,"y":114},{"x":367,"y":117},{"x":384,"y":120},{"x":401,"y":122},{"x":416,"y":130},{"x":430,"y":137},{"x":444,"y":224},{"x":440,"y":212},{"x":435,"y":202},{"x":435,"y":191},{"x":440,"y":180},{"x":435,"y":175},{"x":429,"y":173},{"x":429,"y":160},{"x":433,"y":151},{"x":430,"y":145},{"x":426,"y":131},{"x":427,"y":123},{"x":432,"y":116},{"x":438,"y":108},{"x":427,"y":110},{"x":419,"y":110},{"x":412,"y":109},{"x":407,"y":101},{"x":405,"y":92},{"x":403,"y":78},{"x":401,"y":67},{"x":400,"y":59},{"x":408,"y":72},{"x":408,"y":81},{"x":408,"y":89},{"x":409,"y":98},{"x":419,"y":104},{"x":430,"y":104},{"x":441,"y":102},{"x":448,"y":97},{"x":447,"y":89},{"x":443,"y":81},{"x":434,"y":79},{"x":427,"y":84},{"x":425,"y":91},{"x":425,"y":99},{"x":457,"y":102},{"x":466,"y":102},{"x":475,"y":100},{"x":477,"y":87},{"x":469,"y":80},{"x":459,"y":82},{"x":452,"y":83},{"x":463,"y":73},{"x":457,"y":66},{"x":450,"y":66},{"x":441,"y":68},{"x":435,"y":73},{"x":447,"y":82},{"x":447,"y":74},{"x":475,"y":105},{"x":482,"y":103},{"x":489,"y":99},{"x":489,"y":92},{"x":489,"y":84},{"x":489,"y":77},{"x":492,"y":69},{"x":499,"y":60},{"x":496,"y":68},{"x":495,"y":79},{"x":493,"y":89},{"x":491,"y":98},{"x":489,"y":105},{"x":478,"y":111},{"x":466,"y":108},{"x":470,"y":115},{"x":476,"y":124},{"x":470,"y":133},{"x":465,"y":141},{"x":472,"y":151},{"x":471,"y":160},{"x":476,"y":166},{"x":470,"y":176},{"x":462,"y":182},{"x":466,"y":189},{"x":467,"y":201},{"x":465,"y":213},{"x":459,"y":224}, {"x":446,"y":240},{"x":442,"y":248},{"x":441,"y":260},{"x":440,"y":273},{"x":443,"y":285},{"x":442,"y":298},{"x":442,"y":315},{"x":442,"y":333},{"x":441,"y":349},{"x":441,"y":366},{"x":439,"y":382},{"x":439,"y":400},{"x":439,"y":418},{"x":439,"y":431},{"x":442,"y":454},{"x":449,"y":465},{"x":458,"y":454},{"x":459,"y":434},{"x":460,"y":415},{"x":461,"y":403},{"x":461,"y":389},{"x":461,"y":377},{"x":462,"y":365},{"x":462,"y":347},{"x":462,"y":331},{"x":462,"y":317},{"x":464,"y":303},{"x":464,"y":285},{"x":464,"y":271},{"x":463,"y":259},{"x":459,"y":243},{"x":457,"y":234},{"x":446,"y":233},{"x":468,"y":217},{"x":466,"y":225},{"x":466,"y":233},{"x":470,"y":244},{"x":480,"y":253},{"x":495,"y":261},{"x":511,"y":264},{"x":527,"y":268},{"x":546,"y":270},{"x":562,"y":270},{"x":576,"y":270},{"x":589,"y":269},{"x":604,"y":268},{"x":622,"y":267},{"x":641,"y":267},{"x":657,"y":264},{"x":675,"y":258},{"x":690,"y":255},{"x":702,"y":250},{"x":712,"y":244},{"x":722,"y":236},{"x":717,"y":218},{"x":702,"y":210},{"x":686,"y":202},{"x":666,"y":197},{"x":651,"y":196},{"x":632,"y":192},{"x":614,"y":191},{"x":596,"y":189},{"x":584,"y":190},{"x":571,"y":188},{"x":555,"y":185},{"x":541,"y":181},{"x":529,"y":179},{"x":516,"y":177},{"x":501,"y":173},{"x":486,"y":168},{"x":476,"y":167},{"x":494,"y":169},{"x":507,"y":170},{"x":520,"y":172},{"x":535,"y":172},{"x":550,"y":174},{"x":568,"y":177},{"x":585,"y":177},{"x":602,"y":173},{"x":622,"y":169},{"x":632,"y":168},{"x":646,"y":161},{"x":662,"y":153},{"x":680,"y":146},{"x":696,"y":141},{"x":707,"y":131},{"x":719,"y":121},{"x":727,"y":110},{"x":719,"y":94},{"x":701,"y":86},{"x":684,"y":86},{"x":666,"y":89},{"x":652,"y":93},{"x":636,"y":97},{"x":625,"y":101},{"x":610,"y":104},{"x":598,"y":106},{"x":583,"y":109},{"x":570,"y":109},{"x":555,"y":111},{"x":539,"y":113},{"x":524,"y":116},{"x":511,"y":119},{"x":497,"y":123},{"x":487,"y":128},{"x":473,"y":134}],
"wing_pattern" : [{"x":618,"y":262},{"x":617,"y":254},{"x":612,"y":243},{"x":601,"y":234},{"x":590,"y":223},{"x":578,"y":217},{"x":564,"y":209},{"x":553,"y":203},{"x":542,"y":197},{"x":530,"y":194},{"x":522,"y":193},{"x":510,"y":189},{"x":500,"y":188},{"x":530,"y":199},{"x":520,"y":206},{"x":505,"y":209},{"x":504,"y":215},{"x":516,"y":220},{"x":530,"y":226},{"x":540,"y":233},{"x":552,"y":244},{"x":558,"y":255},{"x":559,"y":262},{"x":559,"y":201},{"x":569,"y":206},{"x":585,"y":211},{"x":596,"y":211},{"x":607,"y":214},{"x":618,"y":219},{"x":622,"y":225},{"x":632,"y":232},{"x":642,"y":238},{"x":654,"y":243},{"x":630,"y":218},{"x":644,"y":218},{"x":661,"y":217},{"x":672,"y":219},{"x":684,"y":223},{"x":697,"y":230},{"x":678,"y":232},{"x":662,"y":226},{"x":652,"y":223},{"x":485,"y":180},{"x":477,"y":176},{"x":286,"y":267},{"x":286,"y":257},{"x":291,"y":251},{"x":299,"y":241},{"x":307,"y":233},{"x":316,"y":225},{"x":329,"y":217},{"x":342,"y":209},{"x":355,"y":202},{"x":371,"y":198},{"x":388,"y":194},{"x":402,"y":189},{"x":415,"y":182},{"x":427,"y":175},{"x":348,"y":260},{"x":355,"y":248},{"x":366,"y":232},{"x":381,"y":223},{"x":394,"y":219},{"x":399,"y":211},{"x":392,"y":209},{"x":378,"y":205},{"x":372,"y":201},{"x":332,"y":207},{"x":323,"y":211},{"x":313,"y":217},{"x":302,"y":219},{"x":289,"y":222},{"x":284,"y":229},{"x":274,"y":235},{"x":265,"y":243},{"x":256,"y":247},{"x":283,"y":222},{"x":271,"y":224},{"x":258,"y":226},{"x":246,"y":233},{"x":232,"y":240},{"x":247,"y":224},{"x":232,"y":226},{"x":223,"y":228},{"x":215,"y":233},{"x":211,"y":236},{"x":202,"y":242},{"x":646,"y":152},{"x":640,"y":141},{"x":621,"y":134},{"x":602,"y":130},{"x":585,"y":130},{"x":570,"y":128},{"x":551,"y":128},{"x":531,"y":132},{"x":512,"y":136},{"x":491,"y":141},{"x":255,"y":151},{"x":259,"y":140},{"x":275,"y":135},{"x":293,"y":130},{"x":308,"y":129},{"x":325,"y":126},{"x":341,"y":126},{"x":358,"y":128},{"x":376,"y":133},{"x":394,"y":136},{"x":418,"y":144},{"x":293,"y":124},{"x":277,"y":124},{"x":260,"y":119},{"x":245,"y":115},{"x":233,"y":108},{"x":218,"y":106},{"x":590,"y":124},{"x":606,"y":124},{"x":618,"y":122},{"x":634,"y":122},{"x":651,"y":117},{"x":661,"y":110},{"x":679,"y":105},{"x":693,"y":105}]
}
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.node {
stroke: #fff;
stroke-width: 1.5px;
}
.link {
stroke: #999;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
then = Date.now();
var color = d3.scale.category20();
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
// Note that distance is measured as x^2 + y^2 without the square root to speed up computation
function distance(node1, node2) {
return (node1.x - node2.x) * (node1.x - node2.x) + (node1.y - node2.y) * (node1.y - node2.y);
}
function create_close_links(nodes, distance_from_node) {
var links = [];
var num_nodes = nodes.length;
for (i = 0; i < num_nodes; i++) {
var source = i;
for (j = i + 1; j < num_nodes; j++) {
var target = j;
if (distance(nodes[source], nodes[target]) < distance_from_node) {
var value = 2 * Math.random() + 1;
links.push({"source" : source, "target": target, "value" : value});
}
}
}
return links;
}
d3.json("dragonfly.json", function(error, dragonfly) {
if (error) throw error;
var dragonfly_data = dragonfly.body.concat(dragonfly.wing_pattern);
var links = create_close_links(dragonfly_data, 400);
function draw() {
// Create random nodes, transition to dragonfly shape, then fade
svg.selectAll(".node")
.data(dragonfly_data)
.enter()
.append("circle")
.attr("class", "node")
.attr("cx", function(d) { return width * Math.random(); })
.attr("cy", function(d) { return height * Math.random(); })
.attr("r", function(d) { return 2 + 2 * Math.random(); })
.attr("fill", function(d) { return color( Math.floor(Math.random() * 6) );})
.attr("opacity", 0)
.transition()
.duration(1000)
.delay(function(d) { return 300 * Math.random();})
.attr("opacity", 1)
.transition()
.duration(1000)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.transition()
.duration(3000)
.delay(4000)
.ease("linear")
.attr("cx", function(d) { return d.x + 20 * Math.random() + 30; })
.attr("cy", function(d) { return d.y + 20 * Math.random(); })
.attr("opacity", 0)
.remove();
// Display edges so they look like high-frequency noise
svg.selectAll(".link")
.data(links)
.enter()
.append("line")
.attr("class", "link")
.attr("stroke-width", function(d) { return d.value; })
.attr("x1", function(d) { return dragonfly_data[d.source].x; })
.attr("y1", function(d) { return dragonfly_data[d.source].y; })
.attr("x2", function(d) { return dragonfly_data[d.target].x; })
.attr("y2", function(d) { return dragonfly_data[d.target].y; })
.attr("stroke-opacity", 0)
.transition()
.delay(2800)
.duration(1000)
.ease("bounce")
.attr("stroke-opacity", 0.2)
.transition()
.duration(1000)
.ease("bounce")
.attr("stroke-opacity", 0)
.remove();
}
draw();
d3.timer(function() {
var time = Date.now() - then;
if (time > 8500) {
draw();
then = Date.now();
}
})
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment