var osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', stamenUrl = 'http://{s}.tile.stamen.com/toner/{z}/{x}/{y}.png', attrib = '© Map tiles by Stamen Design, under CC BY 3.0 | OpenStreetMap contributors', main = L.tileLayer(stamenUrl, {maxZoom: 18, attribution: attrib}), map = new L.Map('map', { layers: [main], center: [55.7501, 37.6687], zoom: 11 }), overlay = L.tileLayer(osmUrl).addTo(map); overlay.getContainer().style.display = "none"; main.getContainer().style.filter = "url(#sepia)"; main.getContainer().style.WebkitFilter = "url(#sepia)"; //Convert Leaflet geometries to D3 geometries function projectPoint(x, y) { var point = map.latLngToLayerPoint(new L.LatLng(y, x)); this.stream.point(point.x, point.y); }; //Initialize SVG layer in Leaflet (works for leaflet-0.7.3) map._initPathRoot() var transform = d3.geo.transform({point: projectPoint}), path = d3.geo.path().projection(transform); var svg = d3.select(".leaflet-overlay-pane").select("svg"), // add "leaflet-zoom-hide" class to SVG container for turning off zoom defs = svg.append("defs"), filterBlur = defs.append("filter").attr("id", "blur"), filterGrayscale = defs.append("filter").attr("id", "grayscale"), clipPath = defs.append("clipPath").attr("id", "clipPath"); //Blur filter params filterBlur.append("feGaussianBlur").attr("stdDeviation", 2); filterGrayscale.append("feColorMatrix").attr("type", "saturate").attr("values", 0); //Leaflet.draw stuff var drawnItems = new L.FeatureGroup(); map.addLayer(drawnItems); var drawControl = new L.Control.Draw({ draw: { position: 'topleft', polygon: { title: 'Draw a sexy polygon!', allowIntersection: false, drawError: { color: '#b00b00', timeout: 1000 }, shapeOptions: { color: '#fff', weight: 10, opacity: 0.8, fill: false }, showArea: true }, rectangle: { shapeOptions: { color: '#fff', weight: 10, opacity: 0.8, fill: false } }, polyline: false, marker: false, circle: false }, edit: { featureGroup: drawnItems } }); map.addControl(drawControl); map.on('draw:created', function (e) { var type = e.layerType, layer = e.layer; drawnItems.addLayer(layer); var geoJSONlayer = layer.toGeoJSON(); geoJSONlayer.properties.id = 'l' + layer._leaflet_id; clipPath.append("path") .attr("id", 'l' + layer._leaflet_id) .datum(geoJSONlayer) .attr("d", path) .attr("fill", "white") .attr("opacity", 0.95); //change opacity to control masking clip(); }); map.on('draw:deleted', function (e) { var layers = e.layers; layers.eachLayer(function (layer) { clipPath.select("#l" + layer._leaflet_id).remove(); }); clip(); }); map.on('draw:edited', function (e) { var layers = e.layers; layers.eachLayer(function (layer) { var geoJSONlayer = layer.toGeoJSON(); clipPath.select("#l" + layer._leaflet_id) .datum(geoJSONlayer) .attr("d", path); }); clip(); }); //Clipping or masking change code accordingly function clip() { var clippingPaths = clipPath.selectAll("path"); clippingPaths.attr("d", path); if (clippingPaths.size() > 0) { overlay.getContainer().style.display = "inline"; overlay.getContainer().style.clipPath = 'url(#clipPath)'; overlay.getContainer().style.WebkitClipPath = 'url(#clipPath)'; } else { overlay.getContainer().style.display = "none"; overlay.getContainer().style.clipPath = 'none'; overlay.getContainer().style.WebkitClipPath = 'none'; }; }; //Some extra controls var filterDropdown = L.Control.extend({ options: { position: 'topright' }, onAdd: function (map) { // create the control container with a particular class name var container = L.DomUtil.create('div', 'dropdown-control'); // ... initialize other DOM elements, add listeners, etc. container.innerHTML = ''; L.DomEvent .on(container.firstChild.firstElementChild, 'change', function(e) { var filterStyle = main.getContainer().style.filter; if (this.value != 'none') { overlay.getContainer().style.filter = 'url(#'+ this.value + ')'; overlay.getContainer().style.WebkitFilter = 'url(#'+ this.value + ')'; } else { overlay.getContainer().style.filter = 'none'; overlay.getContainer().style.WebkitFilter = 'none'; }; }); return container; } }); map.addControl(new filterDropdown()); var patternDropdown = L.Control.extend({ options: { position: 'topright' }, onAdd: function (map) { // create the control container with a particular class name var container = L.DomUtil.create('div', 'dropdown-control'); // ... initialize other DOM elements, add listeners, etc. container.innerHTML = ''; L.DomEvent .on(container.firstChild.firstElementChild, 'change', function(e) { if (this.value != 'none') { drawControl.setDrawingOptions({ polygon: { shapeOptions: { color: '#fff', weight: 10, opacity: 0.8, fill: true, fillOpacity: 0.5, fillColor: 'url(#'+ this.value + ')' }, }, rectangle: { shapeOptions: { color: '#fff', weight: 10, opacity: 0.8, fill: true, fillOpacity: 0.5, fillColor: 'url(#'+ this.value + ')' } } }) } else { drawControl.setDrawingOptions({ polygon: { shapeOptions: { color: '#fff', fill: false }, showArea: true }, rectangle: { shapeOptions: { color: '#fff', weight: 10, opacity: 0.8, fill: false } } }); }; }); return container; } }); map.addControl(new patternDropdown()); var blurControl = L.Control.extend({ options: { position: 'topright' }, onAdd: function (map) { // create the control container with a particular class name var container = L.DomUtil.create('div', 'blur-control'); // ... initialize other DOM elements, add listeners, etc. container.innerHTML = ''; L.DomEvent .on(container.firstChild.firstElementChild, 'change', function(e) { if (this.value == 'clear') { svg.selectAll("g").selectAll('path').attr("filter", "url(#blur)"); this.value = 'blured'; } else { svg.selectAll("g").selectAll('path').attr("filter", "none"); this.value = 'clear'; }; clip(); }); return container; } }); map.addControl(new blurControl()); //Update on move and viewreset map.on('move', clip); map.on('viewreset', clip);