UNPKG

kmap-ui

Version:

A components of zmap base on vue2.X

294 lines (270 loc) 9.29 kB
/* Copyright (c) 2016 Jean-Marc VIGLINO, released under the CeCILL-B license (French BSD license) (http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.txt). */ import ol_ext_inherits from '../util/ext' import ol_Overlay from 'ol/Overlay' import ol_ext_element from '../util/element' /** * @classdesc * A popup element to be displayed over the map and attached to a single map * location. The popup are customized using CSS. * * @example var popup = new ol_Overlay_Popup(); map.addOverlay(popup); popup.show(coordinate, "Hello!"); popup.hide(); * * @constructor * @extends {ol_Overlay} * @param {} options Extend Overlay options * @param {String} options.popupClass the a class of the overlay to style the popup. * @param {bool} options.closeBox popup has a close box, default false. * @param {function|undefined} options.onclose: callback function when popup is closed * @param {function|undefined} options.onshow callback function when popup is shown * @param {Number|Array<number>} options.offsetBox an offset box * @param {ol.OverlayPositioning | string | undefined} options.positioning * the 'auto' positioning var the popup choose its positioning to stay on the map. * @api stable */ var ol_Overlay_Popup = function (options) { var self = this; options = options || {}; if (typeof(options.offsetBox)==='number') this.offsetBox = [options.offsetBox,options.offsetBox,options.offsetBox,options.offsetBox]; else this.offsetBox = options.offsetBox; // Popup div var element = document.createElement("div"); //element.classList.add('ol-overlaycontainer-stopevent'); options.element = element; // Anchor div var anchorElement = document.createElement("div"); anchorElement.classList.add("anchor"); element.appendChild(anchorElement); // Content this.content = ol_ext_element.create("div", { html: options.html || '', className: "ol-popup-content", parent: element }); // Closebox this.closeBox = options.closeBox; this.onclose = options.onclose; this.onshow = options.onshow; var button = document.createElement("button"); button.classList.add("closeBox"); if (options.closeBox) button.classList.add('hasclosebox'); button.setAttribute('type', 'button'); element.insertBefore(button, anchorElement); button.addEventListener("click", function() { self.hide(); }); // Stop event if (options.stopEvent) { element.addEventListener("mousedown", function(e){ e.stopPropagation(); }); element.addEventListener("touchstart", function(e){ e.stopPropagation(); }); } ol_Overlay.call(this, options); this._elt = element; // call setPositioning first in constructor so getClassPositioning is called only once this.setPositioning(options.positioning || 'auto'); this.setPopupClass(options.popupClass || options.className || 'default'); // Show popup on timeout (for animation purposes) if (options.position) { setTimeout(function(){ this.show(options.position); }.bind(this)); } }; ol_ext_inherits(ol_Overlay_Popup, ol_Overlay); /** * Get CSS class of the popup according to its positioning. * @private */ ol_Overlay_Popup.prototype.getClassPositioning = function () { var c = ""; var pos = this.getPositioning(); if (/bottom/.test(pos)) c += "ol-popup-bottom "; if (/top/.test(pos)) c += "ol-popup-top "; if (/left/.test(pos)) c += "ol-popup-left "; if (/right/.test(pos)) c += "ol-popup-right "; if (/^center/.test(pos)) c += "ol-popup-middle "; if (/center$/.test(pos)) c += "ol-popup-center "; return c; }; /** * Set a close box to the popup. * @param {bool} b * @api stable */ ol_Overlay_Popup.prototype.setClosebox = function (b) { this.closeBox = b; if (b) this.element.classList.add("hasclosebox"); else this.element.classList.remove("hasclosebox"); }; /** * Set the CSS class of the popup. * @param {string} c class name. * @api stable */ ol_Overlay_Popup.prototype.setPopupClass = function (c) { this.element.className = ""; var classesPositioning = this.getClassPositioning().split(' ') .filter(function(className) { return className.length > 0; }); var classes = ["ol-popup"]; if (c) { c.split(' ').filter(function(className) { return className.length > 0; }) .forEach(function(className) { classes.push(className); }); } else { classes.push("default"); } classesPositioning.forEach(function(className) { classes.push(className); }); if (this.closeBox) { classes.push("hasclosebox"); } this.element.classList.add.apply(this.element.classList, classes); }; /** * Add a CSS class to the popup. * @param {string} c class name. * @api stable */ ol_Overlay_Popup.prototype.addPopupClass = function (c) { this.element.classList.add(c); }; /** * Remove a CSS class to the popup. * @param {string} c class name. * @api stable */ ol_Overlay_Popup.prototype.removePopupClass = function (c) { this.element.classList.remove(c); }; /** * Set positionning of the popup * @param {ol.OverlayPositioning | string | undefined} pos an ol.OverlayPositioning * or 'auto' to var the popup choose the best position * @api stable */ ol_Overlay_Popup.prototype.setPositioning = function (pos) { if (pos === undefined) return; if (/auto/.test(pos)) { this.autoPositioning = pos.split('-'); if (this.autoPositioning.length==1) this.autoPositioning[1]="auto"; } else this.autoPositioning = false; pos = pos.replace(/auto/g,"center"); if (pos=="center") pos = "bottom-center"; this.setPositioning_(pos); }; /** @private * @param {ol.OverlayPositioning | string | undefined} pos */ ol_Overlay_Popup.prototype.setPositioning_ = function (pos) { if (this.element) { ol_Overlay.prototype.setPositioning.call(this, pos); this.element.classList.remove("ol-popup-top", "ol-popup-bottom", "ol-popup-left", "ol-popup-right", "ol-popup-center", "ol-popup-middle"); var classes = this.getClassPositioning().split(' ') .filter(function(className) { return className.length > 0; }); this.element.classList.add.apply(this.element.classList, classes); } }; /** Check if popup is visible * @return {boolean} */ ol_Overlay_Popup.prototype.getVisible = function () { return this.element.classList.contains("visible"); }; /** * Set the position and the content of the popup. * @param {ol.Coordinate|string} coordinate the coordinate of the popup or the HTML content. * @param {string|undefined} html the HTML content (undefined = previous content). * @example var popup = new ol_Overlay_Popup(); // Show popup popup.show([166000, 5992000], "Hello world!"); // Move popup at coord with the same info popup.show([167000, 5990000]); // set new info popup.show("New informations"); * @api stable */ ol_Overlay_Popup.prototype.show = function (coordinate, html) { if (!html && typeof(coordinate)=='string') { html = coordinate; coordinate = null; } if (coordinate===true) { coordinate = this.getPosition(); } var self = this; var map = this.getMap(); if (!map) return; if (html && html !== this.prevHTML) { // Prevent flickering effect this.prevHTML = html; this.content.innerHTML = ""; if (html instanceof Element) { this.content.appendChild(html); } else { this.content.insertAdjacentHTML('beforeend', html); } // Refresh when loaded (img) Array.prototype.slice.call(this.content.querySelectorAll('img')) .forEach(function(image) { image.addEventListener("load", function() { map.renderSync(); }); }); } if (coordinate) { // Auto positionning if (this.autoPositioning) { var p = map.getPixelFromCoordinate(coordinate); var s = map.getSize(); var pos=[]; if (this.autoPositioning[0]=='auto') { pos[0] = (p[1]<s[1]/3) ? "top" : "bottom"; } else pos[0] = this.autoPositioning[0]; pos[1] = (p[0]<2*s[0]/3) ? "left" : "right"; this.setPositioning_(pos[0]+"-"+pos[1]); if (this.offsetBox) { this.setOffset([this.offsetBox[pos[1]=="left"?2:0], this.offsetBox[pos[0]=="top"?3:1] ]); } } else { if (this.offsetBox){ this.setOffset(this.offsetBox); } } // Show this.setPosition(coordinate); // Set visible class (wait to compute the size/position first) this.element.parentElement.style.display = ''; if (typeof (this.onshow) == 'function') this.onshow(); this._tout = setTimeout (function() { self.element.classList.add("visible"); }, 0); } }; /** * Hide the popup * @api stable */ ol_Overlay_Popup.prototype.hide = function () { if (this.getPosition() == undefined) return; if (typeof (this.onclose) == 'function') this.onclose(); this.setPosition(undefined); if (this._tout) clearTimeout(this._tout); this.element.classList.remove("visible"); }; export default ol_Overlay_Popup