Google Maps, with a random SVG overlay drawn by D3.
draw()
is not called when map pans, only on zoom.Forked from Neutral Blue, by Adam Krogh.
xxxxxxxxxx
<meta charset="utf-8">
<title>Google Maps + D3 Overlay</title>
<style>
html, body {
margin: 0;
padding: 0;
background: #002732;
}
</style>
<script src="https://d3js.org/d3.v4.min.js"></script>
<body>
<div id="map" style="width: 960px; height: 500px;"></div>
<script>
window.initMap = function() {
var el = document.querySelector('#map');
var google = window.google;
// https://www.colourlovers.com/palette/937624/Dance_To_Forget
var colors = ['#FF4E50','#FC913A','#F9D423','#EDE574','#E1F5C4','#FF4E50','#FC913A','#F9D423'];
function SVGOverlay (map) {
this.map = map;
this.svg = null;
this.coords = [];
this.onPan = this.onPan.bind(this);
this.setMap(map);
}
SVGOverlay.prototype = new google.maps.OverlayView();
SVGOverlay.prototype.onAdd = function () {
this.svg = document.createElementNS('https://www.w3.org/2000/svg', 'svg');
this.svg.style.position = 'absolute';
this.svg.style.top = 0;
this.svg.style.left = 0;
this.svg.style.width = '960px';
this.svg.style.height = '500px';
this.svg.style.pointerEvents = 'none';
var bounds = this.map.getBounds(),
center = bounds.getCenter(),
ne = bounds.getNorthEast(),
sw = bounds.getSouthWest();
for (var i = 0; i < 40; i++) {
this.coords.push({
id: i,
color: colors[i % colors.length],
latLng: new google.maps.LatLng(
center.lat() + (Math.random() - 0.5) * Math.abs(ne.lat() - sw.lat()),
center.lng() + (Math.random() - 0.5) * Math.abs(ne.lng() - sw.lng())
)
});
}
var proj = this.getProjection();
d3.select(this.svg)
.attr('width', 960)
.attr('height', 500)
.append('g')
.attr('class', 'coords')
.selectAll('circle')
.data(this.coords, (d) => d.id)
.enter().append('circle')
.attr('cx', (d) => proj.fromLatLngToContainerPixel(d.latLng).x)
.attr('cy', (d) => proj.fromLatLngToContainerPixel(d.latLng).y)
.attr('r', 5)
.attr('fill', (d) => d.color);
this.onPan();
document.body.appendChild(this.svg);
this.map.addListener('center_changed', this.onPan);
};
SVGOverlay.prototype.onPan = function () {
var proj = this.getProjection();
d3.select(this.svg)
.select('.coords')
.selectAll('circle')
.data(this.coords)
.attr('cx', (d) => proj.fromLatLngToContainerPixel(d.latLng).x)
.attr('cy', (d) => proj.fromLatLngToContainerPixel(d.latLng).y);
};
SVGOverlay.prototype.onRemove = function () {
this.map.removeListener('center_changed', this.onPan);
this.svg.parentNode.removeChild(this.svg);
this.svg = null;
};
SVGOverlay.prototype.draw = function () {
console.log('draw');
};
var map = new google.maps.Map(el, {
center: new google.maps.LatLng(-34.397, 150.644),
zoom: 8,
disableDefaultUI: true,
backgroundColor: '#002732'
});
fetch('map-styles.json')
.then((response) => response.json())
.then(function (styles) {
map.mapTypes.set('neutral-blue', new google.maps.StyledMapType(styles));
map.setMapTypeId('neutral-blue');
});
var overlay = new SVGOverlay(map);
};
</script>
<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=places&key=aizasydaoldv31y5ls8abbpuaqt9t8rzmdfomim&callback=initmap"></script>
</body>
Updated missing url https://maps.googleapis.com/maps/api/js?v=3&libraries=places&key=AIzaSyDaoLdV31Y5ls8ABBpuAQt9t8RzMDfOMiM&callback=initMap to https://maps.googleapis.com/maps/api/js?v=3&libraries=places&key=aizasydaoldv31y5ls8abbpuaqt9t8rzmdfomim&callback=initmap
https://d3js.org/d3.v4.min.js
https://maps.googleapis.com/maps/api/js?v=3&libraries=places&key=AIzaSyDaoLdV31Y5ls8ABBpuAQt9t8RzMDfOMiM&callback=initMap