/* Copyright (c) 2015 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_control_Control from 'ol/control/Control.js' import {unByKey as ol_Observable_unByKey} from 'ol/Observable.js' /** A control that use a CSS clip rect to swipe the map * @classdesc Swipe Control. * @fires moving * @constructor * @extends {ol_control_Control} * @param {Object=} Control options. * @param {string} options.className control class name * @param {number} options.position position property of the swipe [0,1], default 0.5 * @param {string} options.orientation orientation property (vertical|horizontal), default vertical * @param {boolean} options.right true to position map on right side (resp. bottom for horizontal orientation), default false */ var ol_control_SwipeMap = class olcontrolSwipeMap extends ol_control_Control { constructor(options) { options = options || {}; var button = document.createElement('button'); var element = document.createElement('div'); element.className = (options.className || "ol-swipe") + " ol-unselectable ol-control"; super({ element: element }); element.appendChild(button); element.addEventListener("mousedown", this.move.bind(this)); element.addEventListener("touchstart", this.move.bind(this)); this.on('propertychange', function (e) { if (this.get('orientation') === "horizontal") { this.element.style.top = this.get('position') * 100 + "%"; this.element.style.left = ""; } else { if (this.get('orientation') !== "vertical") this.set('orientation', "vertical"); this.element.style.left = this.get('position') * 100 + "%"; this.element.style.top = ""; } if (e.key === 'orientation') { this.element.classList.remove("horizontal", "vertical"); this.element.classList.add(this.get('orientation')); if (this.getMap()) { this.getMap().getTargetElement().dataset.swipeOrientation = this.get('orientation') } } this._clip(); }.bind(this)); this.on('change:active', this._clip.bind(this)); this.set('position', options.position || 0.5); this.set('orientation', options.orientation || 'vertical'); this.set('right', options.right); } /** Set the map instance the control associated with. * @param {ol_Map} map The map instance. */ setMap(map) { if (this.getMap()) { if (this._listener) ol_Observable_unByKey(this._listener); var layerDiv = this.getMap().getViewport().querySelector('.ol-layers'); layerDiv.style.clip = ''; delete this.getMap().getTargetElement().dataset.swipeOrientation } super.setMap(map); if (map) { this._listener = map.on('change:size', this._clip.bind(this)); this._clip(); } } /** Clip * @private */ _clip() { if (this.getMap()) { var layerDiv = this.getMap().getViewport().querySelector('.ol-layers'); var rect = this.getRectangle(); if (rect) { layerDiv.style.clip = 'rect(' + rect[1] + 'px,' // top + rect[2] + 'px,' // right + rect[3] + 'px,' // bottom + rect[0] + 'px' //left + ')'; } // Orientation this.getMap().getTargetElement().dataset.swipeOrientation = this.get('orientation') } } /** Get visible rectangle * @returns {ol.extent} */ getRectangle() { var s = this.getMap().getSize(); if (!s) return; if (this.get('orientation') === 'vertical') { if (this.get('right')) { return [s[0] * this.get('position'), 0, s[0], s[1]]; } else { return [0, 0, s[0] * this.get('position'), s[1]]; } } else { if (this.get('right')) { return [0, s[1] * this.get('position'), s[0], s[1]]; } else { return [0, 0, s[0], s[1] * this.get('position')]; } } } /** @private */ move(e) { var self = this; var l; if (!this._movefn) this._movefn = this.move.bind(this); switch (e.type) { case 'touchcancel': case 'touchend': case 'mouseup': { self.isMoving = false; ["mouseup", "mousemove", "touchend", "touchcancel", "touchmove"] .forEach(function (eventName) { document.removeEventListener(eventName, self._movefn); }); break; } case 'mousedown': case 'touchstart': { self.isMoving = true; ["mouseup", "mousemove", "touchend", "touchcancel", "touchmove"] .forEach(function (eventName) { document.addEventListener(eventName, self._movefn); }); } // fallthrough case 'mousemove': case 'touchmove': { if (self.isMoving) { if (self.get('orientation') === 'vertical') { var pageX = e.pageX || (e.touches && e.touches.length && e.touches[0].pageX) || (e.changedTouches && e.changedTouches.length && e.changedTouches[0].pageX); if (!pageX) break; pageX -= self.getMap().getTargetElement().getBoundingClientRect().left + window.pageXOffset - document.documentElement.clientLeft; l = self.getMap().getSize()[0]; var w = l - Math.min(Math.max(0, l - pageX), l); l = w / l; self.set('position', l); self.dispatchEvent({ type: 'moving', size: [w, self.getMap().getSize()[1]], position: [l, 0] }); } else { var pageY = e.pageY || (e.touches && e.touches.length && e.touches[0].pageY) || (e.changedTouches && e.changedTouches.length && e.changedTouches[0].pageY); if (!pageY) break; pageY -= self.getMap().getTargetElement().getBoundingClientRect().top + window.pageYOffset - document.documentElement.clientTop; l = self.getMap().getSize()[1]; var h = l - Math.min(Math.max(0, l - pageY), l); l = h / l; self.set('position', l); self.dispatchEvent({ type: 'moving', size: [self.getMap().getSize()[0], h], position: [0, l] }); } } break; } default: break; } } } export default ol_control_SwipeMap