Skip to content

Instantly share code, notes, and snippets.

@mcharytoniuk
Last active February 1, 2017 10:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mcharytoniuk/ad012e860c165d2457b2 to your computer and use it in GitHub Desktop.
Save mcharytoniuk/ad012e860c165d2457b2 to your computer and use it in GitHub Desktop.
<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
Copy link

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