Skip to content

Instantly share code, notes, and snippets.

@elemoine
Last active August 29, 2015 14:07
Show Gist options
  • Save elemoine/c760ac48772b048bc211 to your computer and use it in GitHub Desktop.
Save elemoine/c760ac48772b048bc211 to your computer and use it in GitHub Desktop.
OpenLayers 3 – create a mask on shift-drag

This gist shows how to create a mask on the map using shift-drag. This is in response to a question on the ol3-dev mailing list.

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="http://openlayers.org/en/master/css/ol.css" type="text/css">
<style type="text/css">
body {
width: 960px;
height: 500px;
position: relative;
}
#map {
width: 100%;
height: 100%;
}
</style>
<title>Create mask on shift-drag</title>
</head>
<body>
<div id="map"></div>
<script src="http://openlayers.org/en/master/build/ol.js" type="text/javascript"></script>
<script type="text/javascript">
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
// Flag indicating whether the postcompose listener should
// draw the "mask" on the map.
var drawMask = false;
// Create a drag box interaction that sets drawMask to true
// on "boxstart" and sets drawMask to false on "boxend".
var boxInteraction = new ol.interaction.DragBox({
condition: ol.events.condition.shiftKeyOnly,
style: new ol.style.Style({})
});
boxInteraction.on('boxstart', function() {
drawMask = true;
});
boxInteraction.on('boxend', function() {
drawMask = false;
});
map.addInteraction(boxInteraction);
// Add a "postcompose" listener that draws on mask on the map
// when drawMask is true.
map.on('postcompose', function(evt) {
if (!drawMask) {
return;
}
var ctx = evt.context;
var size = map.getSize();
var height = size[1] * ol.has.DEVICE_PIXEL_RATIO;
var width = size[0] * ol.has.DEVICE_PIXEL_RATIO;
var polygon = boxInteraction.getGeometry();
var coordinates = polygon.getCoordinates()[0];
var bl, br, tr, tl;
bl = map.getPixelFromCoordinate(coordinates[0]);
tl = map.getPixelFromCoordinate(coordinates[1]);
tr = map.getPixelFromCoordinate(coordinates[2]);
br = map.getPixelFromCoordinate(coordinates[3]);
ctx.beginPath();
// Outside polygon, must be clockwise
ctx.moveTo(0, 0);
ctx.lineTo(width, 0);
ctx.lineTo(width, height);
ctx.lineTo(0, height);
ctx.lineTo(0, 0);
ctx.closePath();
// Inner polygon, must be counter-clockwise
ctx.moveTo(bl[0], bl[1]);
ctx.lineTo(tl[0], tl[1]);
ctx.lineTo(tr[0], tr[1]);
ctx.lineTo(br[0], br[1]);
ctx.lineTo(bl[0], bl[1]);
ctx.closePath();
ctx.fillStyle = 'rgba(0, 5, 25, 0.75)';
ctx.fill();
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment