Skip to content

Instantly share code, notes, and snippets.

@jrowlingson
Created August 17, 2017 18:24
Show Gist options
  • Save jrowlingson/8de4e34b9c56ac7bc3623d741ff89a61 to your computer and use it in GitHub Desktop.
Save jrowlingson/8de4e34b9c56ac7bc3623d741ff89a61 to your computer and use it in GitHub Desktop.
import Component from '@ember/component';
import { inject } from '@ember/service';
import { computed, get, set } from '@ember/object';
import { task } from 'ember-concurrency';
import { assert } from '@ember/debug';
export default Component.extend({
mapService: inject('components/map'),
mapZoomLevel: computed.alias('mapService.mapZoomLevel'),
_startZoomLevel: undefined, // <- ideally, I would like to avoid having to set this property
actions: {
zoom(zoomLevelStep) {
assert(Number.isInteger(zoomLevelStep), 'zoomLevelStep must be an integer.');
// HACK: the call to `map.setExtent` will update the map zoom level value
// and fire the `zoom-end` event prior to the resolution of the deffered returned
// by `map.setExtent`. Because of this, we can't rely on the zoom level to
// be correct when we are calculating the target zoom level so we need to store
// the starting zoom level to be used in this calculation.
if (!get(this, '_zoomInTask.isRunning') && !get(this, '_zoomOutTask.isRunning')) {
set(this, '_startZoomLevel', get(this, 'mapZoomLevel'));
}
if (zoomLevelStep > 0) {
get(this, '_zoomInTask').perform(zoomLevelStep + zoomLevelStep * (get(this, '_zoomInTask.concurrency') - get(this, '_zoomOutTask.concurrency')));
} else {
get(this, '_zoomOutTask').perform(zoomLevelStep + zoomLevelStep * (get(this, '_zoomOutTask.concurrency') - get(this, '_zoomInTask.concurrency')));
}
},
},
_zoomInTask: task(function* (zoomLevelDelta) {
yield this._zoom(zoomLevelDelta);
}),
_zoomOutTask: task(function* (zoomLevelDelta) {
yield this._zoom(zoomLevelDelta);
}),
_zoom(zoomLevelDelta) {
const targetZoomLevel = get(this, '_startZoomLevel') + zoomLevelDelta;
// resolves after the zooming animation has completed. subsequent calls will
// cancel any in progress animation and immediately resume the animation to the
// target zoom level.
return get(this, 'mapService').setZoomLevel(targetZoomLevel).then(() => {
this._cancelInProgressZoomTasks();
});
},
_cancelInProgressZoomTasks() {
get(this, '_zoomInTask').cancelAll();
get(this, '_zoomOutTask').cancelAll();
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment