-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use MessageChannel instead of setTimeout to avoid processing delays (#…
…8673) * use MessageChannel instead of setTimeout to avoid processing delays * move invocation throttling to ThrottledInvoker class also adds a fallback for environments that don't support MessageChannel
- Loading branch information
Showing
3 changed files
with
119 additions
and
9 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Mapbox GL JS debug page</title> | ||
<meta charset='utf-8'> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> | ||
<link rel='stylesheet' href='../dist/mapbox-gl.css' /> | ||
<style> | ||
#map { width: 764px; height: 400px; } | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<div id='map'></div> | ||
|
||
<script src='../dist/mapbox-gl-dev.js'></script> | ||
<script src='access_token_generated.js'></script> | ||
<script> | ||
|
||
var map = window.map = new mapboxgl.Map({ | ||
container: 'map', | ||
style: 'mapbox://styles/mapbox/streets-v11', | ||
center: [0, 0], | ||
zoom: 2 | ||
}); | ||
|
||
var radius = 20; | ||
|
||
function pointOnCircle(angle) { | ||
return { | ||
"type": "Point", | ||
"coordinates": [ | ||
Math.cos(angle) * radius, | ||
Math.sin(angle) * radius | ||
] | ||
}; | ||
} | ||
|
||
map.on('load', function () { | ||
// Add a source and layer displaying a point which will be animated in a circle. | ||
map.addSource('point', { | ||
"type": "geojson", | ||
"data": pointOnCircle(0) | ||
}); | ||
|
||
map.addLayer({ | ||
"id": "point", | ||
"source": "point", | ||
"type": "circle", | ||
"paint": { | ||
"circle-radius": 10, | ||
"circle-color": "#007cbf" | ||
} | ||
}); | ||
|
||
function animateMarker(timestamp) { | ||
// Update the data to a new position based on the animation timestamp. The | ||
// divisor in the expression `timestamp / 1000` controls the animation speed. | ||
map.getSource('point').setData(pointOnCircle(timestamp / 1000)); | ||
|
||
// Request the next frame of the animation. | ||
requestAnimationFrame(animateMarker); | ||
} | ||
|
||
// Start the animation. | ||
animateMarker(0); | ||
}); | ||
</script> | ||
|
||
</body> | ||
</html> |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
// @flow | ||
|
||
/** | ||
* Invokes the wrapped function in a non-blocking way when trigger() is called. Invocation requests | ||
* are ignored until the function was actually invoked. | ||
* | ||
* @private | ||
*/ | ||
class ThrottledInvoker { | ||
_channel: MessageChannel; | ||
_triggered: boolean; | ||
_callback: Function | ||
|
||
constructor(callback: Function) { | ||
this._callback = callback; | ||
this._triggered = false; | ||
if (typeof MessageChannel !== 'undefined') { | ||
this._channel = new MessageChannel(); | ||
this._channel.port2.onmessage = () => { | ||
this._triggered = false; | ||
this._callback(); | ||
}; | ||
} | ||
} | ||
|
||
trigger() { | ||
if (!this._triggered) { | ||
this._triggered = true; | ||
if (this._channel) { | ||
this._channel.port1.postMessage(true); | ||
} else { | ||
setTimeout(() => { | ||
this._triggered = false; | ||
this._callback(); | ||
}, 0); | ||
} | ||
} | ||
} | ||
} | ||
|
||
export default ThrottledInvoker; |