Plane rotate along path
by Viet Phan
HTML
<script src="http://d3js.org/topojson.v1.min.js"></script>
<script src="https://raw.githubusercontent.com/markmarkoh/datamaps/v0.2.10/dist/datamaps.world.min.js"></script>
<div id="container" style="position: relative; width: 700px; height: 400px;">
<div id="spiral" style="width: 100%; height: 100%;">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" id="spiralSVG" width = 100% height="280px" preserveAspectRatio="none" viewBox="0 0 1600 800" >
<path id="planeSVG" d="M 45.102065,97.705811 C 43.951007,97.612411 38.945827,96.864561 38.853217,96.772201 38.809017,96.728101 38.809017,96.658341 38.853217,96.617081 38.897417,96.575881 47.128741,91.537912 57.14511,85.421702 72.972389,75.757222 75.641253,74.061202 77.53027,72.467322 L 79.703865,70.633322 79.318206,70.143042 C 79.106096,69.873382 78.932557,69.454252 78.932557,69.211622 78.932557,68.251422 80.524374,67.023742 82.55786,66.415632 83.055469,66.266822 83.540368,65.953452 83.768287,65.633372 84.183716,65.049952 86.480822,63.813072 87.50616,63.620722 87.950789,63.537322 89.021597,62.761832 90.975043,61.108552 L 93.800757,58.717042 71.245872,58.717042 C 58.840687,58.717042 48.645238,58.643042 48.589308,58.552522 48.533408,58.462022 47.855999,58.329772 47.083991,58.258602 43.037809,57.885592 35.552564,56.554232 28.919017,55.027712 14.832555,51.786102 3.1621393,47.490622 0.4766545,44.559052 0.02057542,44.061182 -0.00495453,43.914962 5.7545885e-4,41.831602 0.00657545,39.738142 0.0302754,39.606352 0.49340447,39.143232 1.2638731,38.372752 4.0330275,37.570952 8.4508283,36.839182 9.1843868,36.717672 9.1945868,36.704392 9.091017,36.005792 8.3790384,31.203272 4.281117,0.29533282 4.3475469,0.22890282 4.3968468,0.17960282 6.7295921,0.32920282 9.5314261,0.56134282 L 14.625666,0.98341282 25.333854,15.929952 36.042043,30.876492 38.103399,32.662782 40.164745,34.449072 56.801731,34.435872 C 74.987585,34.421472 74.855325,34.428872...
CSS
#spiral {
z-index: 100;
position:absolute;
top: 0;
left:-5%;
}
#spiralSVG {
position:absolute;
bottom: 0;
left: 5%;
}
path {
fill: none;
}
#planeSVG {
fill: #e67e22;
stroke: #666;
opacity: 0;
}
JavaScript
var spiralData = "m 190.79664,517.11414 c 30.90934,-6.54998 -3.92944,-41.28388 -16.658,-46.55459 C 101.629,440.53436 31.208349,503.75377 19.691609,553.37288 -7.0984697,668.79611 142.50632,777.8444 277.35418,759.01888 511.6369,726.3117 1429.5677,239.15024 1550.4691,101.7018";
//define Spiral path for plane
var canvas = d3.select("#spiralSVG").append("svg")
.attr("width", "100%")
.attr("height", "100%")
.attr("x", "5%")
.style("overflow","visible");
var path = canvas.append("path")
.attr("d", spiralData)
.style("fill","none")
.style("stroke","#666")
.style("opacity","0");
var plane = d3.select("#planeSVG");
function transitionThis(d,i) {
d3.select(this).transition()
.duration(3000)
.delay(3000) //causes error in the animation
.ease("exp")
.each("start", function() { d3.select(this).style("opacity", "1"); })
.attrTween("transform", translateAlong(path.node()))
.styleTween("opacity", function () {return d3.interpolate("1", "0");});
}
plane.each(transitionThis);
// Returns an attrTween for translating along the specified path element.
function translateAlong(path) {
var l = path.getTotalLength();
var t0 = 0;
return function(i) {
return function(t) {
// Happens every once in a while
if(t == t0) {
// Move t0 "back in time" a bit
t0 -= .00001;
}
var p0 = path.getPointAtLength(t0 * l);//previous point
var p = path.getPointAtLength(t * l);////current point
var angle = Math.atan2(p.y - p0.y, p.x - p0.x) * 180 / Math.PI;//angle for tangent
t0 = t;
return "translate(" + p.x + "," + p.y + ")scale(" + (0.2+t*4) + ")rotate(" + angle +"15"+")";
};
};
}