Skip to content

Instantly share code, notes, and snippets.

@twelch
Last active May 30, 2018 05:00
Show Gist options
  • Save twelch/051d5070594a1e1426fcf6a080a0e431 to your computer and use it in GitHub Desktop.
Save twelch/051d5070594a1e1426fcf6a080a0e431 to your computer and use it in GitHub Desktop.
Multiple animated paths
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.12.1/mapbox-gl.js'></script>
<script src='http://api.tiles.mapbox.com/mapbox.js/plugins/turf/v2.0.2/turf.min.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.12.1/mapbox-gl.css' rel='stylesheet' />
<style>
body { margin:0; padding:0; }
#map { position:absolute; top:0; bottom:0; width:100%; }
</style>
</head>
<body>
<div id='map'></div>
<script>
function animatePointAlongPath (type, duration, delay = 0, line, lineStart, lineSource, aPoint, pointSource, onDone, onLocUpdate) {
let aFrame = null; // Animation frame ID
let dPoint = aPoint;
let running = true; // Running state
const startTime = new Date();
const lineLength = turf.lineDistance(line, 'miles');
let lineSoFar = [];
if (type === 'grow') {
lineSoFar = lineStart;
}
/* Stop animation loop */
function stop() {
running = false;
window.cancelAnimationFrame(aFrame);
if (onDone) {
onDone();
}
}
/* Get new point position and line segment */
function getGeoms(percDone) {
const curDistance = percDone * lineLength;
dPoint = turf.along(line, curDistance, 'miles');
if (type === 'grow') {
lineSoFar.geometry.coordinates.push(dPoint.geometry.coordinates);
} else if (type === 'shrink') {
const coords = line.geometry.coordinates;
const curP = turf.along(line, lineLength * percDone, 'miles');
const endP = turf.point(coords[coords.length - 1]);
lineSoFar = turf.lineSlice(curP, endP, line);
}
return {
point: dPoint,
line: lineSoFar
};
}
/* Animation loop */
function animate() {
const curTime = new Date();
const elapsed = curTime - startTime;
// If not ready yet
if (elapsed < delay) {
return window.requestAnimationFrame(animate);
}
const percDone = (elapsed - delay) / duration;
// If complete
if (percDone >= 1) {
stop();
return false;
}
const geoms = getGeoms(percDone);
if (geoms) {
if (onLocUpdate) {
onLocUpdate(geoms.point);
}
pointSource.setData(geoms.point);
lineSource.setData(geoms.line);
if (running) {
return window.requestAnimationFrame(animate);
}
}
}
// Start animation and return stop method to caller
aFrame = animate(startTime);
return stop;
}
var Tour = function() {
mapboxgl.accessToken = 'pk.eyJ1IjoidHdlbGNoIiwiYSI6ImNqZW5vazRvcjEyczAyd25xamczMmh3OG0ifQ.vJy47O0vb1Z_F7OWIbZpyg';
this.videos = {};
};
Tour.prototype.start = function() {
this.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/twelch/cihxvsxy000oeaikoz39jjthw',
center: [-115.17427,36.08035],
zoom: 11,
minzoom: 19
});
this.map.on('style.load', function () {
this.startTour();
}.bind(this));
};
var path1 = turf.linestring([
[-115.17313,36.10199],[-115.17312,36.10095],[-115.17576,36.10093],[-115.17961,36.10086],[-115.18099,36.10084],[-115.18131,36.10055],[-115.18108,36.09515],[-115.18137,36.08572],[-115.18115,36.07942],[-115.18114,36.06611]
]);
var path2 = turf.linestring([
[-115.17427,36.00935],[-115.17274,36.01008],[-115.17231,36.01339],[-115.17845,36.01331],[-115.17994,36.0135],[-115.18052,36.02428],[-115.18064,36.0417],[-115.18061,36.0741],[-115.18053,36.091],[-115.18042,36.10823],[-115.18022,36.12265],[-115.17821,36.12605],[-115.17883,36.1278],[-115.17758,36.12814],[-115.17757,36.12814],[-115.17754,36.12817],[-115.17883,36.1278],[-115.1778,36.13003],[-115.17649,36.12973],[-115.17754,36.12817],[-115.17755,36.12816],[-115.17754,36.12817],[-115.17754,36.12817],[-115.17754,36.12817],[-115.17883,36.1278],[-115.1778,36.13003],[-115.17649,36.12973],[-115.17754,36.12817],[-115.17755,36.12816],[-115.17643,36.12972],[-115.17449,36.12941],[-115.17614,36.12692],[-115.17353,36.12586],[-115.17972,36.12763],[-115.17972,36.13302],[-115.16905,36.1464],[-115.16099,36.15563],[-115.16016,36.15909],[-115.15919,36.16771],[-115.15599,36.17227],[-115.14654,36.17541],[-115.14219,36.1741],[-115.14482,36.16953],[-115.14359,36.1692],[-115.14358,36.16921],[-115.14359,36.16918],[-115.13961,36.1673],[-115.13797,36.16659],[-115.1373,36.16767],[-115.13505,36.1713],[-115.13583,36.17164]
]);
var path3 = turf.flip(turf.linestring([
[36.16423,-115.13078],[36.16376,-115.13138],[36.16395,-115.13182],[36.16458,-115.1333],[36.16542,-115.13525],[36.16753,-115.14017],[36.16843,-115.14227],[36.16896,-115.14351],[36.16941,-115.1449],[36.16849,-115.14585],[36.16851,-115.1459],[36.16886,-115.14672],[36.16927,-115.14645],[36.16993,-115.14602],[36.17053,-115.14712],[36.1715,-115.14647],[36.17401,-115.14483],[36.17352,-115.14368],[36.17236,-115.14443],[36.17285,-115.14558],[36.17053,-115.14712],[36.17034,-115.14669],[36.17039,-115.14681],[36.17703,-115.14254],[36.17627,-115.14079],[36.17591,-115.14072],[36.17505,-115.1415],[36.17515,-115.14231],[36.17568,-115.14471],[36.17488,-115.15045],[36.17542,-115.15381],[36.17467,-115.15523],[36.17175,-115.15729],[36.16855,-115.15911],[36.16811,-115.15929],[36.16117,-115.16042],[36.15674,-115.16062],[36.15421,-115.16245],[36.14683,-115.16896],[36.13982,-115.17518],[36.13523,-115.17903],[36.13116,-115.18069],[36.12777,-115.18118],[36.12657,-115.18071],[36.12588,-115.17886],[36.12555,-115.1741],[36.1252,-115.1697],[36.12496,-115.16975],[36.12341,-115.17076],[36.12359,-115.17119],[36.12374,-115.17169],[36.12374,-115.17185],[36.12375,-115.17191]
]));
var path4 = turf.flip(turf.linestring([
[36.13621,-115.15008],[36.13619,-115.15008],[36.13619,-115.15008],[36.13484,-115.15001],[36.13475,-115.14908],[36.13383,-115.14895],[36.13309,-115.14781],[36.13153,-115.14768],[36.13108,-115.14731],[36.13081,-115.14669],[36.1304,-115.14607],[36.12984,-115.14595],[36.12982,-115.14617],[36.1295,-115.14795],[36.12947,-115.15128],[36.12957,-115.15436],[36.12961,-115.15487],[36.12744,-115.15493],[36.12669,-115.15494],[36.1222,-115.15499],[36.12044,-115.155],[36.11605,-115.15455],[36.11462,-115.15411],[36.11306,-115.1536],[36.11062,-115.15285],[36.10803,-115.15205],[36.10803,-115.1523],[36.10803,-115.15646],[36.10809,-115.16375],[36.10794,-115.16577],[36.10798,-115.16374],[36.10802,-115.16303],[36.10814,-115.16943],[36.10814,-115.16954],[36.10814,-115.16997],[36.10717,-115.16995],[36.10701,-115.16998],[36.10701,-115.16998],[36.1069,-115.17143],[36.10617,-115.17143],[36.10618,-115.17035],[36.10698,-115.17031],[36.10701,-115.16995],[36.10724,-115.16995],[36.10793,-115.16996],[36.10793,-115.16973],[36.10795,-115.16865],[36.10795,-115.16803],[36.10802,-115.1619],[36.10793,-115.15261],[36.10791,-115.15212],[36.10711,-115.15206],[36.10711,-115.15206],[36.10711,-115.15206],[36.10708,-115.15205],[36.10742,-115.15216],[36.10737,-115.15186],[36.1059,-115.15142],[36.10253,-115.15035],[36.10245,-115.14734],[36.10264,-115.14673],[36.10376,-115.14914],[36.10569,-115.14982],[36.10571,-115.15112],[36.10572,-115.15137],[36.10253,-115.15035],[36.1025,-115.14695],[36.10264,-115.14673],[36.10391,-115.14928],[36.10578,-115.14984],[36.10597,-115.14989],[36.1072,-115.15034],[36.10889,-115.15045],[36.11154,-115.1505],[36.11244,-115.14997],[36.11337,-115.1472],[36.11442,-115.14639],[36.11442,-115.14639],[36.11937,-115.14624],[36.12702,-115.14609],[36.1301,-115.14597],[36.13072,-115.14649],[36.13122,-115.14748],[36.13173,-115.14772],[36.13287,-115.14773],[36.13333,-115.14812],[36.13362,-115.14875],[36.13425,-115.14908],[36.13577,-115.14908],[36.13635,-115.14955],[36.13714,-115.15124],[36.13763,-115.15168],[36.13807,-115.15178]
]));
var path5 = turf.flip(turf.linestring([
[36.1735,-115.08838],[36.17337,-115.08937],[36.17284,-115.08937],[36.16672,-115.08925],[36.16627,-115.08924],[36.16616,-115.08891],[36.16618,-115.08565],[36.16624,-115.08078],[36.16624,-115.08075],[36.16626,-115.07806],[36.16639,-115.06665],[36.16646,-115.06236],[36.16669,-115.0581],[36.16686,-115.05349],[36.16677,-115.05319],[36.16061,-115.05333],[36.15875,-115.05319],[36.15875,-115.05238],[36.15863,-115.05231],[36.15391,-115.0523],[36.15146,-115.05229],[36.15092,-115.05181],[36.15087,-115.05137],[36.15127,-115.05134],[36.15151,-115.05129],[36.15155,-115.05117],[36.15162,-115.04888],[36.15214,-115.04888],[36.15255,-115.04889],[36.15255,-115.04848],[36.15324,-115.04869],[36.15272,-115.04869],[36.15316,-115.04847],[36.15316,-115.04847],[36.15316,-115.04847],[36.15335,-115.04847],[36.15335,-115.04848],[36.15335,-115.04847],[36.15353,-115.04783],[36.15352,-115.04847],[36.15352,-115.04857],[36.15346,-115.0487],[36.15255,-115.04848],[36.15255,-115.04889],[36.15354,-115.04889],[36.15439,-115.04889],[36.155,-115.04889],[36.155,-115.04976],[36.1575,-115.04976],[36.15751,-115.04872],[36.15751,-115.04755],[36.15761,-115.04736],[36.15948,-115.04741],[36.15948,-115.04748],[36.15948,-115.04769],[36.15938,-115.05316],[36.15937,-115.0537],[36.15909,-115.0621],[36.15922,-115.06341],[36.16027,-115.06337],[36.1622,-115.06343],[36.16274,-115.06339],[36.16268,-115.06342],[36.16124,-115.06344],[36.16078,-115.06336],[36.15909,-115.06356],[36.15907,-115.06769],[36.15906,-115.07221],[36.15886,-115.07221],[36.15665,-115.07221],[36.15262,-115.07219],[36.15118,-115.07236],[36.15118,-115.07288],[36.15118,-115.07403],[36.15125,-115.07426],[36.15567,-115.07443],[36.15685,-115.07445],[36.15685,-115.07423],[36.15686,-115.07039],[36.15686,-115.06793],[36.15687,-115.06562],[36.15679,-115.0655]
]));
Tour.prototype.startTour = function() {
var time = 0;
var timePerStep = 100;
var interval = setInterval(function() {
time += timePerStep;
if (time === 2000) {this.startPerson(1, 'shrink', path1, "#4999D2", 8000);}
if (time === 4000) {this.startPerson(2, 'shrink', path2, "#0DFF93", 6000);}
if (time === 6000) {this.startPerson(3, 'shrink', path3, "#FF0000", 4000);}
if (time === 8000) {this.startPerson(4, 'shrink', path4, "#FFFC19", 4000);}
if (time === 10000) {this.startPerson(5, 'shrink', path5, "#ED00FF", 4000);}
}.bind(this), timePerStep);
};
Tour.prototype.startPerson = function(id, type, iPath, color, duration) {
var iPathLength = turf.lineDistance(iPath, 'miles');
var iPoint = turf.along(iPath, 0, 'miles');
this.pPointSource = new mapboxgl.GeoJSONSource({
"type": "geojson",
"data": iPoint,
"maxzoom": 20
});
this.map.addSource(id + "-pDot", this.pPointSource);
this.map.addLayer({
"id": id + "-pDot",
"type": "symbol",
"source": id + "-pDot",
"layout": {
"icon-image": "car-15",
"icon-size": {
"base": 0.5,
"stops": [
[0,1],
[15,1.2],
[20,2]]
},
},
"paint": {},
"interactive": true
});
this.pLineSource = new mapboxgl.GeoJSONSource({
"type": "geojson",
"data": iPath,
"maxzoom": 20
});
this.map.addSource(id + "-pLine", this.pLineSource);
this.map.addLayer({
"id": id + "-pLine",
"type": "line",
"source": id + "-pLine",
"layout": {
"line-join": "round",
"line-cap": "round"
},
"paint": {
"line-color": color,
"line-opacity": "0.6",
"line-width": 6,
"line-blur": 1
}
}, id + "-pDot");
animatePointAlongPath(
type,
duration,
1000,
iPath,
iPath,
this.pLineSource,
iPoint,
this.pPointSource,
function() { console.log('done animating'); },
function(newPoint) { console.log('new point', newPoint); }
)
//type, duration, delay = 0, line, lineStart, lineSource, aPoint, pointSource, onDone, onLocUpdate
};
Tour.prototype.stopPerson = function() {
this.map.removeLayer('pLine');
this.map.removeLayer('pDot');
this.map.removeSource('pLine');
this.map.removeSource('pDot');
clearInterval(this.personInterval);
};
var tour = new Tour();
tour.start();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment