UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

104 lines (98 loc) 5.98 kB
import { CONTROL_EVENTS, GLOBE_VIEW_EVENTS, PLANAR_CONTROL_EVENT, VIEW_EVENTS } from 'itowns'; import Widget from "./Widget.js"; const DEFAULT_OPTIONS = { width: 200, height: 30, position: 'bottom-left' }; /** * A widget for scale * * To use it, you need to link the widgets' stylesheet to your html webpage. This stylesheet is included in * [itowns bundles](https://github.com/iTowns/itowns/releases) if you downloaded them, or it can be found in * `node_modules/itowns/examples/css` if you installed iTowns with npm. Otherwise, it can be found at * [this link](https://raw.githubusercontent.com/iTowns/itowns/master/examples/css/widgets.css). See * [this example](http://www.itowns-project.org/itowns/examples/#widgets_scale) for more details. * * @extends Widget * * @property {HTMLElement} domElement An html div containing the scale. * @property {HTMLElement} parentElement The parent HTML container of `this.domElement`. */ class Scale extends Widget { /** * @param {View} view The iTowns view the scale should be * linked to. If it is a * {@link PlanarView} or a * {@link GlobeView}, the scale will be * automatically updated. Otherwise, user * will need to implement the update * automation using the `Scale.update` * method. * @param {Object} [options] The scale optional configuration. * @param {HTMLElement} [options.parentElement=view.domElement] The parent HTML container of the div * which contains scale widgets. * @param {number} [options.width=200] The width in pixels of the scale. * @param {number} [options.height=30] The height in pixels of the scale. * @param {string} [options.position='bottom-left'] Defines which position within the * `parentElement` the scale should be * displayed to. Possible values are * `top`, `bottom`, `left`, `right`, * `top-left`, `top-right`, `bottom-left` * and `bottom-right`. If the input value * does not match one of these, it will * be defaulted to `bottom-left`. * @param {Object} [options.translate] An optional translation of the scale. * @param {number} [options.translate.x=0] The scale translation along the page * x-axis. * @param {number} [options.translate.y=0] The scale translation along the page * y-axis. */ constructor(view) { let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; // ---------- BUILD PROPERTIES ACCORDING TO DEFAULT OPTIONS AND OPTIONS PASSED IN PARAMETERS : ---------- super(view, options, DEFAULT_OPTIONS); // ---------- this.domElement SETTINGS SPECIFIC TO SCALE : ---------- this.domElement.id = 'widgets-scale'; this.view = view; // Initialize the text content of the scale, which will later be updated by a numerical value. this.domElement.innerHTML = 'Scale'; this.width = options.width || DEFAULT_OPTIONS.width; if (this.view.isGlobeView) { this.view.addEventListener(GLOBE_VIEW_EVENTS.GLOBE_INITIALIZED, () => { this.update(); }); this.view.controls.addEventListener(CONTROL_EVENTS.RANGE_CHANGED, () => { this.update(); }); } else if (this.view.isPlanarView) { this.view.addEventListener(VIEW_EVENTS.INITIALIZED, () => { this.update(); }); this.view.addEventListener(PLANAR_CONTROL_EVENT.MOVED, () => { this.update(); }); } else { console.warn('The \'view\' linked to scale widget is neither a \'GlobeView\' nor a \'PlanarView\'. The ' + 'scale wont automatically update. You can implement its update automation using \'Scale.update\' ' + 'method.'); } } addEventListeners() {} /** * Update the scale size and content according to view camera position. */ update() { // Calculate the rounded metric distance which matches the scale width in pixels. let metricDistance = Math.round(this.view.getPixelsToMeters(this.width)); const digit = 10 ** (metricDistance.toString().length - 1); metricDistance = Math.round(metricDistance / digit) * digit; const pixelDistance = this.view.getMetersToPixels(metricDistance); let unit = 'm'; if (metricDistance >= 1000) { metricDistance /= 1000; unit = 'km'; } this.domElement.innerHTML = `${metricDistance} ${unit}`; this.domElement.style.width = `${pixelDistance}px`; } } export default Scale;