import { Control } from 'ol/control';
import View from 'ol/View';
import Map from 'ol/Map';
import Collection from 'ol/Collection';
import TileLayer from 'ol/layer/Tile';
/**
* Displays an interface that shows slide at max zoom level under pointer's position
* @param {object} opt_options Options to initialize the magnifier control
* @param {string} [opt_options.target] Target DOM element to add magnifier control
* @param {boolean} [opt_options.collapsed] Whether the control starts collapsed
*/
export class Magnifier extends Control {
constructor(opt_options) {
var options = opt_options || {};
var element = document.createElement('div');
super({
element: element,
target: options.target
});
this.collapsed_ = false;
if (options.collapsed === true) {
this.collapsed_ = true;
}
element.className = "ol-control ";
if (!options.target) {
// create inside the viewport
element.className += " ol-magnifier";
this.magnifierDiv = document.createElement('div');
this.magnifierDiv.className = "magnifier-map-container";
element.appendChild(this.magnifierDiv);
// also create grow shrink buttons
var enlargeButton = document.createElement('button');
enlargeButton.type = 'button';
enlargeButton.title = "Enlarge";
enlargeButton.className = "size";
enlargeButton.innerHTML = "+";
if ('ontouchstart' in document.documentElement) {
enlargeButton.addEventListener('touchstart', this.enlargeButtonClick.bind(this), false);
}
else {
enlargeButton.addEventListener('click', this.enlargeButtonClick.bind(this), false);
}
element.appendChild(enlargeButton);
var shrinkButton = document.createElement('button');
shrinkButton.type = 'button';
shrinkButton.title = "Shrink";
shrinkButton.className = "size";
shrinkButton.innerHTML = "-";
if ('ontouchstart' in document.documentElement) {
shrinkButton.addEventListener('touchstart', this.shrinkButtonClick.bind(this), false);
}
else {
shrinkButton.addEventListener('click', this.shrinkButtonClick.bind(this), false);
}
element.appendChild(shrinkButton);
}
else {
this.magnifierDiv = element;
}
this.magnifierMap = null;
this.mouseMoveFunc = null;
}
handleMouseMove(event) {
if (this.getCollapsed() === true) {
return;
}
var map = this.getMap();
var mousePosition = map.getEventPixel(event);
var coordinate = map.getCoordinateFromPixel(mousePosition);
if (coordinate) {
this.magnifierMap.getView().setCenter(coordinate);
}
}
/**
* Gets the collapsed state of the control
* @return {boolean} True if the control is currently collapsed
*/
getCollapsed() {
return (" " + this.element.className + " ").indexOf(' ol-collapsed ') > -1;
}
/**
* Sets the collapsed state of the control
* @param {boolean} collapsed - True to collapse the control, otherwise false
*/
setCollapsed(collapsed) {
if (this.getCollapsed() != collapsed) {
if ((" " + this.element.className + " ").indexOf(' ol-collapsed ') > -1) {
this.element.className = this.element.className.replace(/ol-collapsed/g, '');
if (this.magnifierMap) {
this.magnifierMap.updateSize();
}
}
else {
this.element.className += ' ol-collapsed';
}
}
this.collapsed_ = collapsed;
}
/**
* Changes magnifier control size by factor
* @param {number} factor Factor to change magnifier's size
*/
changeMagnifierSize(factor) {
if (this.element) {
var diagonalSize = Math.sqrt(this.element.clientHeight * this.element.clientHeight + this.element.clientWidth * this.element.clientWidth);
if (diagonalSize < 60 || diagonalSize > 600) {
return;
}
this.element.style.width = this.element.clientWidth * factor + "px";
this.element.style.height = this.element.clientHeight * factor + "px";
}
if (this.magnifierMap) {
this.magnifierMap.updateSize();
}
}
/**
* Sets the OpenLayers map this control handles. This is automatically called by OpenLayers
* @param {ol.Map} map
*/
setMap(map) {
if (!map) {
if (this.magnifierMap) {
var el = this.element;
if (el) {
el.parentElement.removeChild(el);
}
}
if (this.getMap() && this.mouseMoveFunc) {
this.getMap().getViewport().removeEventListener('mousemove', this.mouseMoveFunc);
}
return;
}
var oldMap = this.getMap();
if (map === oldMap) {
return;
}
super.setMap(map);
var mapView = map.getView();
var newView = new View({
projection: mapView.getProjection(),
center: mapView.getCenter(),
extent: mapView.getProjection().getExtent(),
maxResolution: 1,
minResolution: 1,
zoom: 0
});
var firstLayer = map.getLayers().item(0);
// Magnifier map
this.magnifierMap = new Map({
controls: new Collection(),
interactions: new Collection(),
target: this.magnifierDiv,
view: newView,
layers: [new TileLayer({ source: firstLayer.getSource() })]
});
var changing = false;
this.magnifierMap.on("change:size", (function () {
if (!changing) {
changing = true;
this.magnifierMap.updateSize();
changing = false;
}
}).bind(this));
this.mouseMoveFunc = this.handleMouseMove.bind(this);
map.getViewport().addEventListener('mousemove', this.mouseMoveFunc);
if (this.collapsed_ !== this.getCollapsed()) {
this.setCollapsed(this.collapsed_);
}
}
enlargeButtonClick(event) {
if (event) {
event.preventDefault();
event.stopPropagation();
}
this.changeMagnifierSize(1.25);
}
shrinkButtonClick(event) {
if (event) {
event.preventDefault();
event.stopPropagation();
}
this.changeMagnifierSize(0.75);
}
}