<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/ol3/3.5.0/ol.min.css" type="text/css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div id="map" tabindex="0"></div>
<script src="//cdnjs.cloudflare.com/ajax/libs/ol3/3.5.0/ol.min.js" type="text/javascript"></script>
<script src="ol-popup.js"></script>
<script src="script.js"></script>
</body>
</html>
var olview = new ol.View({
center: [-9120944.666442728, 2653259.4403269454],
resolution: 39135.75848201024,
minZoom: 2,
maxZoom: 20
});
var sourceFeatures = new ol.source.Vector(),
layerFeatures = new ol.layer.Vector({source: sourceFeatures});
var map = new ol.Map({
target: document.getElementById('map'),
loadTilesWhileAnimating: true,
loadTilesWhileInteracting: true,
view: olview,
renderer: 'canvas',
layers: [
new ol.layer.Tile({
style: 'Aerial',
source: new ol.source.MapQuest({layer: 'sat'})
}),
layerFeatures
]
});
var popup = new ol.Overlay.Popup;
popup.setOffset([0, -55]);
map.addOverlay(popup);
var long_string = 'a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text a long text ';
var style1 = [
new ol.style.Style({
image: new ol.style.Icon(({
scale: 0.7,
rotateWithView: false,
anchor: [0.5, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
opacity: 1,
src: '//raw.githubusercontent.com/jonataswalker/map-utils/master/images/marker.png'
})),
zIndex: 5
}),
new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: 'rgba(255,255,255,1)'
}),
stroke: new ol.style.Stroke({
color: 'rgba(0,0,0,1)'
})
})
})
];
var feature = new ol.Feature({
type: 'click',
desc: long_string,
geometry: new ol.geom.Point([-9120944.666442728, 2653259.4403269454])
});
var feature2 = new ol.Feature({
type: 'click',
desc: long_string,
geometry: new ol.geom.Point([-8347855.579795895, -679521.3556101936])
});
feature.setStyle(style1);
sourceFeatures.addFeature(feature);
feature2.setStyle(style1);
sourceFeatures.addFeature(feature2);
map.on('click', function(evt) {
var f = map.forEachFeatureAtPixel(
evt.pixel,
function(ft, layer){return ft;}
);
if (f && f.get('type') == 'click') {
var geometry = f.getGeometry();
var coord = geometry.getCoordinates();
var content = '<p>'+f.get('desc')+'</p>';
popup.show(coord, content);
} else { popup.hide(); }
});
map.on('pointermove', function(e) {
if (e.dragging) { popup.hide(); return; }
var pixel = map.getEventPixel(e.originalEvent);
var hit = map.hasFeatureAtPixel(pixel);
map.getTarget().style.cursor = hit ? 'pointer' : '';
});
#map{
position:absolute;
z-index:1;
width:100%; height:100%;
top:0; bottom:0;
}
.ol-popup {
position: absolute;
background-color: white;
-webkit-filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
filter: drop-shadow(0 1px 4px rgba(0,0,0,0.2));
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -50px;
}
.ol-popup:after, .ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: white;
border-width: 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-content {
position: relative;
min-width: 200px;
min-height: 150px;
height: 100%;
max-height: 250px;
padding:2px;
white-space: normal;
background-color: #f7f7f9;
border: 1px solid #e1e1e8;
overflow-y: auto;
overflow-x: hidden;
}
.ol-popup-content p{
font-size: 14px;
padding: 2px 4px;
color: #222;
margin-bottom: 15px;
}
.ol-popup-closer {
position: absolute;
top: -4px;
right: 2px;
font-size: 100%;
color: #0088cc;
text-decoration: none;
}
a.ol-popup-closer:hover{
color: #005580;
text-decoration: underline;
}
.ol-popup-closer:after {
content: "✖";
}
/**
* OpenLayers 3 Popup Overlay.
* See [the examples](./examples) for usage. Styling can be done via CSS.
* @constructor
* @extends {ol.Overlay}
* @param {Object} opt_options Overlay options, extends olx.OverlayOptions adding:
* **`panMapIfOutOfView`** `Boolean` - Should the
* map be panned so that the popup is entirely
* within view.
*/
ol.Overlay.Popup = function(opt_options) {
var options = opt_options || {};
this.panMapIfOutOfView = options.panMapIfOutOfView;
if (this.panMapIfOutOfView === undefined) {
this.panMapIfOutOfView = true;
}
this.ani = options.ani;
if (this.ani === undefined) {
this.ani = ol.animation.pan;
}
this.ani_opts = options.ani_opts;
if (this.ani_opts === undefined) {
this.ani_opts = {'duration': 250};
}
this.container = document.createElement('div');
this.container.className = 'ol-popup';
this.closer = document.createElement('a');
this.closer.className = 'ol-popup-closer';
this.closer.href = '#';
this.container.appendChild(this.closer);
var that = this;
this.closer.addEventListener('click', function(evt) {
that.container.style.display = 'none';
that.closer.blur();
evt.preventDefault();
}, false);
this.content = document.createElement('div');
this.content.className = 'ol-popup-content';
this.container.appendChild(this.content);
ol.Overlay.call(this, {
element: this.container,
stopEvent: true
});
};
ol.inherits(ol.Overlay.Popup, ol.Overlay);
/**
* Show the popup.
* @param {ol.Coordinate} coord Where to anchor the popup.
* @param {String} html String of HTML to display within the popup.
*/
ol.Overlay.Popup.prototype.show = function(coord, html) {
this.setPosition(coord);
this.content.innerHTML = html;
this.container.style.display = 'block';
var content = this.content;
window.setTimeout(function(){
content.scrollTop = 0;
}, 100);
if (this.panMapIfOutOfView) {
this.panIntoView_(coord);
}
return this;
};
/**
* @private
*/
ol.Overlay.Popup.prototype.panIntoView_ = function(coord) {
var popSize = {
width: this.getElement().clientWidth + 20,
height: this.getElement().clientHeight + 20
},
mapSize = this.getMap().getSize();
var tailHeight = 20,
tailOffsetLeft = 60,
tailOffsetRight = popSize.width - tailOffsetLeft,
popOffset = this.getOffset(),
popPx = this.getMap().getPixelFromCoordinate(coord);
var fromLeft = (popPx[0] - tailOffsetLeft),
fromRight = mapSize[0] - (popPx[0] + tailOffsetRight);
var fromTop = popPx[1] - popSize.height + popOffset[1],
fromBottom = mapSize[1] - (popPx[1] + tailHeight) - popOffset[1];
var center = this.getMap().getView().getCenter(),
px = this.getMap().getPixelFromCoordinate(center);
if (fromRight < 0) {
px[0] -= fromRight;
} else if (fromLeft < 0) {
px[0] += fromLeft;
}
if (fromTop < 0) {
//px[1] = 170 + fromTop;
px[1] += fromTop; //original
} else if (fromBottom < 0) {
px[1] -= fromBottom;
}
if (this.ani && this.ani_opts) {
this.ani_opts.source = center;
this.getMap().beforeRender(this.ani(this.ani_opts));
}
this.getMap().getView().setCenter(this.getMap().getCoordinateFromPixel(px));
return this.getMap().getView().getCenter();
};
/**
* Hide the popup.
*/
ol.Overlay.Popup.prototype.hide = function() {
this.container.style.display = 'none';
return this;
};