diff --git a/src/ui/control/scale_control.js b/src/ui/control/scale_control.js index 256ef1dace3..4270124cb79 100644 --- a/src/ui/control/scale_control.js +++ b/src/ui/control/scale_control.js @@ -5,6 +5,11 @@ const util = require('../../util/util'); import type Map from '../map'; +const defaultOptions = { + maxWidth: 100, + unit: 'metric' +}; + /** * A `ScaleControl` control displays the ratio of a distance on the map to the corresponding distance on the ground. * @@ -13,10 +18,13 @@ import type Map from '../map'; * @param {number} [options.maxWidth='100'] The maximum length of the scale control in pixels. * @param {string} [options.unit='metric'] Unit of the distance (`'imperial'`, `'metric'` or `'nautical'`). * @example - * map.addControl(new mapboxgl.ScaleControl({ + * var scale = new mapboxgl.ScaleControl({ * maxWidth: 80, * unit: 'imperial' - * })); + * }); + * map.addControl(scale); + * + * scale.setUnit('metric'); */ class ScaleControl { _map: Map; @@ -24,10 +32,11 @@ class ScaleControl { options: any; constructor(options: any) { - this.options = options; + this.options = util.extend({}, defaultOptions, options); util.bindAll([ - '_onMove' + '_onMove', + 'setUnit' ], this); } @@ -54,6 +63,16 @@ class ScaleControl { this._map.off('move', this._onMove); this._map = (undefined: any); } + + /** + * Set the scale's unit of the distance + * + * @param {string} unit Unit of the distance (`'imperial'`, `'metric'` or `'nautical'`). + */ + setUnit(unit: string) { + this.options.unit = unit; + updateScale(this._map, this._container, this.options); + } } module.exports = ScaleControl; diff --git a/test/unit/ui/control/scale.test.js b/test/unit/ui/control/scale.test.js new file mode 100644 index 00000000000..43244c4dd28 --- /dev/null +++ b/test/unit/ui/control/scale.test.js @@ -0,0 +1,51 @@ +'use strict'; + +const test = require('mapbox-gl-js-test').test; +const window = require('../../../../src/util/window'); +const Map = require('../../../../src/ui/map'); +const ScaleControl = require('../../../../src/ui/control/scale_control'); + +function createMap() { + const container = window.document.createElement('div'); + return new Map({ + container, + style: { + version: 8, + sources: {}, + layers: [] + }, + hash: true + }); + +} + +test('ScaleControl appears in bottom-left by default', (t) => { + const map = createMap(); + map.addControl(new ScaleControl()); + + t.equal(map.getContainer().querySelectorAll('.mapboxgl-ctrl-bottom-left .mapboxgl-ctrl-scale').length, 1); + t.end(); +}); + +test('ScaleControl appears in the position specified by the position option', (t) => { + const map = createMap(); + map.addControl(new ScaleControl(), 'top-left'); + + t.equal(map.getContainer().querySelectorAll('.mapboxgl-ctrl-top-left .mapboxgl-ctrl-scale').length, 1); + t.end(); +}); + +test('ScaleControl should change unit of distance after calling setUnit', (t) => { + const map = createMap(); + const scale = new ScaleControl(); + const selector = '.mapboxgl-ctrl-bottom-left .mapboxgl-ctrl-scale'; + map.addControl(scale); + + let contents = map.getContainer().querySelector(selector).innerHTML; + t.match(contents, /km/); + + scale.setUnit('imperial'); + contents = map.getContainer().querySelector(selector).innerHTML; + t.match(contents, /mi/); + t.end(); +});