187 lines
6.2 KiB
JavaScript
187 lines
6.2 KiB
JavaScript
/*
|
|
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
|