Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
<link rel="import" href="../bower_components/polymer/polymer.html" />
<link rel="import" href="../bower_components/google-apis/google-apis.html" />
<polymer-element attributes="lat lng" name="gmaps-google-map-marker">
<template>
<content id="marker" select="a"></content>
</template>
<script>
"use strict";
Polymer({
"getLatLng": function () {
return new google.maps.LatLng(Number(this.lat), Number(this.lng));
}
});
</script>
</polymer-element>
<polymer-element attributes="lat lng zoom" name="gmaps-google-map">
<template>
<style>
:host {
display: block;
height: 100%;
overflow: hidden;
position: relative;
}
#map {
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
}
.markerContainer {
position: absolute;
}
</style>
<google-maps-api libraries="places" on-api-load="{{mapApiLoaded}}"></google-maps-api>
<div id="map"></div>
<div style="transform: translateX({{markerContainerOffsetLeft}}px) translateY({{markerContainerOffsetTop}}px) translateZ(0px)">
<template repeat="{{marker, markerIndex in markers}}">
<div class="markerContainer" style="left: {{marker.left}}px; top: {{marker.top}}px">
<content select="gmaps-google-map-marker[lat='{{marker.element.lat}}'][lng='{{marker.element.lng}}']"></content>
</div>
</template>
</div>
</template>
<script>
"use strict";
Polymer({
"lat": 0,
"lognitude": 0,
"markerContainerOffsetLeft": 0,
"markerContainerOffsetTop": 0,
"zoom": 8,
"domReady": function () {
this.markers = Array.prototype.map.call(this.querySelectorAll("gmaps-google-map-marker"), function (markerElement) {
return {
"element": markerElement,
"left": 0,
"top": 0
};
});
},
"getLatLngProjection": function (mapProjection, mapScale, markerLatLng, worldCoordinates) {
var markerPoint = mapProjection.fromLatLngToPoint(markerLatLng);
return this.getPointProjection(mapProjection, mapScale, markerPoint, worldCoordinates);
},
"getPointProjection": function (mapProjection, mapScale, markerPoint, worldCoordinates) {
var pointX = (markerPoint.x - worldCoordinates.x) * mapScale,
pointY = (markerPoint.y - worldCoordinates.y) * mapScale;
return new google.maps.Point(pointX, pointY);
},
"getStyle": function () {
return this.querySelector("gmaps-google-map-style").getStyle();
},
"mapApiLoaded": function () {
var map,
mapOffsetHeight = this.$.map.offsetHeight,
mapOffsetWidth = this.$.map.offsetWidth;
map = new google.maps.Map(this.$.map, {
"center": new google.maps.LatLng(Number(this.lat), Number(this.lng)),
"styles": this.getStyle(),
"zoom": Number(this.zoom)
});
function curryMapProperties(self, cb) {
return function () {
var mapBounds = map.getBounds(),
mapProjection = map.getProjection(),
mapScale = Math.pow(2, map.getZoom()),
worldCoordinates = map.getProjection().fromLatLngToPoint(new google.maps.LatLng(mapBounds.getNorthEast().lat(), mapBounds.getSouthWest().lng()));
return cb(self, mapProjection, mapScale, worldCoordinates);
};
}
function onBoundsChanged(self, mapProjection, mapScale, worldCoordinates) {
self.updateMarkersContainerOffset(mapOffsetHeight, mapOffsetWidth, mapProjection, mapScale, worldCoordinates);
}
function onZoomChanged(self, mapProjection, mapScale, worldCoordinates) {
onBoundsChanged(self, mapProjection, mapScale, worldCoordinates);
self.updateMarkersOffset(mapProjection, mapScale, worldCoordinates);
}
google.maps.event.addListener(map, "bounds_changed", curryMapProperties(this, onBoundsChanged));
google.maps.event.addListener(map, "drag", curryMapProperties(this, onBoundsChanged));
// google.maps.event.addListener(map, "idle", curryMapProperties(this, onZoomChanged));
google.maps.event.addListener(map, "projection_changed", curryMapProperties(this, onZoomChanged));
google.maps.event.addListener(map, "zoom_changed", curryMapProperties(this, onZoomChanged));
},
"updateMarkersContainerOffset": function (mapOffsetHeight, mapOffsetWidth, mapProjection, mapScale, worldCoordinates) {
var i,
markersBounds = new google.maps.LatLngBounds(),
markersNorthEastProjection,
markersSouthWestProjection;
for (i = 0; i < this.markers.length; i += 1) {
markersBounds.extend(this.markers[i].element.getLatLng());
}
markersNorthEastProjection = this.getLatLngProjection(mapProjection, mapScale, markersBounds.getNorthEast(), worldCoordinates);
markersSouthWestProjection = this.getLatLngProjection(mapProjection, mapScale, markersBounds.getSouthWest(), worldCoordinates);
this.markerContainerOffsetLeft = markersSouthWestProjection.x;
this.markerContainerOffsetTop = markersNorthEastProjection.y;
},
"updateMarkersOffset": function (mapProjection, mapScale, worldCoordinates) {
var i,
markerProjection;
for (i = 0; i < this.markers.length; i += 1) {
markerProjection = this.getLatLngProjection(mapProjection, mapScale, this.markers[i].element.getLatLng(), worldCoordinates);
this.markers[i].left = markerProjection.x - this.markerContainerOffsetLeft;
this.markers[i].top = markerProjection.y - this.markerContainerOffsetTop;
}
}
});
</script>
</polymer-element>
<polymer-element name="gmaps-google-map-style">
<template>
<style>
:host {
display: none;
}
</style>
<content id="style"></content>
</template>
<script>
"use strict";
Polymer({
"getStyle": function () {
return JSON.parse(this.$.style.getDistributedNodes().item(0).textContent);
}
});
</script>
</polymer-element>

Birowsky commented Feb 1, 2017

How did you get access to the google namespace within this component?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment