https://developers.google.com/maps/documentation/javascript/firebase
https://developers.google.com/maps/documentation/javascript/mysql-to-maps
<!DOCTYPE html> <html> <%%KEEPWHITESPACE%%> <head> <%%KEEPWHITESPACE%%> <meta name="viewport" content="initial-scale=1.0, user-scalable=no"> <%%KEEPWHITESPACE%%> <meta charset="utf-8"> <%%KEEPWHITESPACE%%> <title>Map Puzzle</title> <%%KEEPWHITESPACE%%> <style> <%%KEEPWHITESPACE%%> #map { <%%KEEPWHITESPACE%%> height: 100%; <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> html, body { <%%KEEPWHITESPACE%%> height: 100%; <%%KEEPWHITESPACE%%> margin: 0; <%%KEEPWHITESPACE%%> padding: 0; <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> </style> <%%KEEPWHITESPACE%%> </head> <%%KEEPWHITESPACE%%> <body> <%%KEEPWHITESPACE%%> <div id="map"></div> <%%KEEPWHITESPACE%%> <script src="https://www.gstatic.com/firebasejs/4.13.0/firebase.js"></script> <script> <%%KEEPWHITESPACE%%> // Initialize Firebase <%%KEEPWHITESPACE%%> var config = { <%%KEEPWHITESPACE%%> apiKey: "AIzaSyCdUZeJTXzbqEXfVzskUFOoY-Mqh9TnyvU", <%%KEEPWHITESPACE%%> authDomain: "click-function-test.firebaseapp.com", <%%KEEPWHITESPACE%%> databaseURL: "https://click-function-test.firebaseio.com", <%%KEEPWHITESPACE%%> projectId: "click-function-test", <%%KEEPWHITESPACE%%> storageBucket: "click-function-test.appspot.com", <%%KEEPWHITESPACE%%> messagingSenderId: "257165968755" <%%KEEPWHITESPACE%%> }; <%%KEEPWHITESPACE%%> firebase.initializeApp(config); </script> <%%KEEPWHITESPACE%%> <script> function PuzzleDemo() { <%%KEEPWHITESPACE%%> this.polys_ = []; <%%KEEPWHITESPACE%%> this.difficulty_ = 'easy'; <%%KEEPWHITESPACE%%> this.count_ = 0; <%%KEEPWHITESPACE%%> this.pieceDiv_ = null; <%%KEEPWHITESPACE%%> this.timeDiv_ = null; } PuzzleDemo.NUM_PIECES_ = 10; PuzzleDemo.START_COLOR_ = '#3c79de'; PuzzleDemo.END_COLOR_ = '#037e29'; PuzzleDemo.prototype.init = function(map) { <%%KEEPWHITESPACE%%> this.map_ = map; <%%KEEPWHITESPACE%%> this.createMenu_(map); <%%KEEPWHITESPACE%%> this.setDifficultyStyle_(); <%%KEEPWHITESPACE%%> this.loadData_(); }; PuzzleDemo.prototype.createMenu_ = function(map) { <%%KEEPWHITESPACE%%> var menuDiv = document.createElement('div'); <%%KEEPWHITESPACE%%> menuDiv.style.cssText = <%%KEEPWHITESPACE%%> 'margin: 40px 10px; border-radius: 8px; height: 320px; width: 180px;' + <%%KEEPWHITESPACE%%> 'background-color: white; font-size: 14px; font-family: Roboto;' + <%%KEEPWHITESPACE%%> 'text-align: center; color: grey;line-height: 32px; overflow: hidden'; <%%KEEPWHITESPACE%%> var titleDiv = document.createElement('div'); <%%KEEPWHITESPACE%%> titleDiv.style.cssText = <%%KEEPWHITESPACE%%> 'width: 100%; background-color: #4285f4; color: white; font-size: 20px;' + <%%KEEPWHITESPACE%%> 'line-height: 40px;margin-bottom: 24px'; <%%KEEPWHITESPACE%%> titleDiv.innerText = 'Game Options'; <%%KEEPWHITESPACE%%> var pieceTitleDiv = document.createElement('div'); <%%KEEPWHITESPACE%%> pieceTitleDiv.innerText = 'PIECE:'; <%%KEEPWHITESPACE%%> pieceTitleDiv.style.fontWeight = '800'; <%%KEEPWHITESPACE%%> var pieceDiv = this.pieceDiv_ = document.createElement('div'); <%%KEEPWHITESPACE%%> pieceDiv.innerText = '0 / ' + PuzzleDemo.NUM_PIECES_; <%%KEEPWHITESPACE%%> var timeTitleDiv = document.createElement('div'); <%%KEEPWHITESPACE%%> timeTitleDiv.innerText = 'TIME:'; <%%KEEPWHITESPACE%%> timeTitleDiv.style.fontWeight = '800'; <%%KEEPWHITESPACE%%> var timeDiv = this.timeDiv_ = document.createElement('div'); <%%KEEPWHITESPACE%%> timeDiv.innerText = '0.0 seconds'; <%%KEEPWHITESPACE%%> var difficultyTitleDiv = document.createElement('div'); <%%KEEPWHITESPACE%%> difficultyTitleDiv.innerText = 'DIFFICULTY:'; <%%KEEPWHITESPACE%%> difficultyTitleDiv.style.fontWeight = '800'; <%%KEEPWHITESPACE%%> var difficultySelect = document.createElement('select'); <%%KEEPWHITESPACE%%> ['Easy', 'Moderate', 'Hard', 'Extreme'].forEach(function(level) { <%%KEEPWHITESPACE%%> var option = document.createElement('option'); <%%KEEPWHITESPACE%%> option.value = level.toLowerCase(); <%%KEEPWHITESPACE%%> option.innerText = level; <%%KEEPWHITESPACE%%> difficultySelect.appendChild(option); <%%KEEPWHITESPACE%%> }); <%%KEEPWHITESPACE%%> difficultySelect.style.cssText = <%%KEEPWHITESPACE%%> 'border: 2px solid lightgrey; background-color: white; color: #4275f4;' + <%%KEEPWHITESPACE%%> 'padding: 6px;'; <%%KEEPWHITESPACE%%> difficultySelect.onchange = function() { <%%KEEPWHITESPACE%%> this.setDifficulty_(difficultySelect.value); <%%KEEPWHITESPACE%%> this.resetGame_(); <%%KEEPWHITESPACE%%> }.bind(this); <%%KEEPWHITESPACE%%> var resetDiv = document.createElement('div'); <%%KEEPWHITESPACE%%> resetDiv.innerText = 'Reset'; <%%KEEPWHITESPACE%%> resetDiv.style.cssText = <%%KEEPWHITESPACE%%> 'cursor: pointer; border-top: 1px solid lightgrey; margin-top: 18px;' + <%%KEEPWHITESPACE%%> 'color: #4275f4; line-height: 40px; font-weight: 800'; <%%KEEPWHITESPACE%%> resetDiv.onclick = this.resetGame_.bind(this); <%%KEEPWHITESPACE%%> menuDiv.appendChild(titleDiv); <%%KEEPWHITESPACE%%> menuDiv.appendChild(pieceTitleDiv); <%%KEEPWHITESPACE%%> menuDiv.appendChild(pieceDiv); <%%KEEPWHITESPACE%%> menuDiv.appendChild(timeTitleDiv); <%%KEEPWHITESPACE%%> menuDiv.appendChild(timeDiv); <%%KEEPWHITESPACE%%> menuDiv.appendChild(difficultyTitleDiv); <%%KEEPWHITESPACE%%> menuDiv.appendChild(difficultySelect); <%%KEEPWHITESPACE%%> menuDiv.appendChild(resetDiv); <%%KEEPWHITESPACE%%> map.controls[google.maps.ControlPosition.TOP_LEFT].push(menuDiv); }; PuzzleDemo.prototype.render = function(map) { <%%KEEPWHITESPACE%%> if (!this.dataLoaded_) { <%%KEEPWHITESPACE%%> return; <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> this.start_(); }; PuzzleDemo.prototype.loadData_ = function() { <%%KEEPWHITESPACE%%> var xmlhttpRequest = new XMLHttpRequest; <%%KEEPWHITESPACE%%> xmlhttpRequest.onreadystatechange = function() { <%%KEEPWHITESPACE%%> if (xmlhttpRequest.status != 200 || <%%KEEPWHITESPACE%%> xmlhttpRequest.readyState != XMLHttpRequest.DONE) return; <%%KEEPWHITESPACE%%> this.loadDataComplete_(JSON.parse(xmlhttpRequest.responseText)); <%%KEEPWHITESPACE%%> }.bind(this); <%%KEEPWHITESPACE%%> xmlhttpRequest.open( <%%KEEPWHITESPACE%%> 'GET', 'https://storage.googleapis.com/mapsdevsite/json/puzzle.json', <%%KEEPWHITESPACE%%> true); <%%KEEPWHITESPACE%%> xmlhttpRequest.send(null); }; PuzzleDemo.prototype.loadDataComplete_ = function(data) { <%%KEEPWHITESPACE%%> this.dataLoaded_ = true; <%%KEEPWHITESPACE%%> this.countries_ = data; <%%KEEPWHITESPACE%%> this.start_(); }; PuzzleDemo.prototype.setDifficulty_ = function(difficulty) { <%%KEEPWHITESPACE%%> this.difficulty_ = difficulty; <%%KEEPWHITESPACE%%> if (this.map_) { <%%KEEPWHITESPACE%%> this.setDifficultyStyle_(); <%%KEEPWHITESPACE%%> } }; PuzzleDemo.prototype.setDifficultyStyle_ = function() { <%%KEEPWHITESPACE%%> var styles = { <%%KEEPWHITESPACE%%> 'easy': [ <%%KEEPWHITESPACE%%> { <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'off' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> },{ <%%KEEPWHITESPACE%%> featureType: 'water', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'on' }, <%%KEEPWHITESPACE%%> { color: '#d4d4d4' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> },{ <%%KEEPWHITESPACE%%> featureType: 'landscape', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'on' }, <%%KEEPWHITESPACE%%> { color: '#e5e3df' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> }, { <%%KEEPWHITESPACE%%> featureType: 'administrative.country', <%%KEEPWHITESPACE%%> elementType: 'labels', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'on' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> }, { <%%KEEPWHITESPACE%%> featureType: 'administrative.country', <%%KEEPWHITESPACE%%> elementType: 'geometry', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'on' }, <%%KEEPWHITESPACE%%> { weight: 1.3 } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> ], <%%KEEPWHITESPACE%%> 'moderate': [ <%%KEEPWHITESPACE%%> { <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'off' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> },{ <%%KEEPWHITESPACE%%> featureType: 'water', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'on' }, <%%KEEPWHITESPACE%%> { color: '#d4d4d4' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> },{ <%%KEEPWHITESPACE%%> featureType: 'landscape', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'on' }, <%%KEEPWHITESPACE%%> { color: '#e5e3df' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> }, { <%%KEEPWHITESPACE%%> featureType: 'administrative.country', <%%KEEPWHITESPACE%%> elementType: 'labels', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'on' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> ], <%%KEEPWHITESPACE%%> 'hard': [ <%%KEEPWHITESPACE%%> { <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'off' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> },{ <%%KEEPWHITESPACE%%> featureType: 'water', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'on' }, <%%KEEPWHITESPACE%%> { color: '#d4d4d4' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> },{ <%%KEEPWHITESPACE%%> featureType: 'landscape', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'on' }, <%%KEEPWHITESPACE%%> { color: '#e5e3df' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> ], <%%KEEPWHITESPACE%%> 'extreme': [ <%%KEEPWHITESPACE%%> { <%%KEEPWHITESPACE%%> elementType: 'geometry', <%%KEEPWHITESPACE%%> stylers: [ <%%KEEPWHITESPACE%%> { visibility: 'off' } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> ] <%%KEEPWHITESPACE%%> }; <%%KEEPWHITESPACE%%> this.map_.set('styles', styles[this.difficulty_]); }; PuzzleDemo.prototype.resetGame_ = function() { <%%KEEPWHITESPACE%%> this.removeCountries_(); <%%KEEPWHITESPACE%%> this.count_ = 0; <%%KEEPWHITESPACE%%> this.setCount_(); <%%KEEPWHITESPACE%%> this.startClock_(); <%%KEEPWHITESPACE%%> this.addRandomCountries_(); }; PuzzleDemo.prototype.setCount_ = function() { <%%KEEPWHITESPACE%%> this.pieceDiv_.innerText = this.count_ + ' / ' + PuzzleDemo.NUM_PIECES_; <%%KEEPWHITESPACE%%> if (this.count_ == PuzzleDemo.NUM_PIECES_) { <%%KEEPWHITESPACE%%> this.stopClock_(); <%%KEEPWHITESPACE%%> } }; PuzzleDemo.prototype.stopClock_ = function() { <%%KEEPWHITESPACE%%> window.clearInterval(this.timer_); }; PuzzleDemo.prototype.startClock_ = function() { <%%KEEPWHITESPACE%%> this.stopClock_(); <%%KEEPWHITESPACE%%> var timeDiv = this.timeDiv_; <%%KEEPWHITESPACE%%> if (timeDiv) timeDiv.textContent = '0.0 seconds'; <%%KEEPWHITESPACE%%> var t = new Date; <%%KEEPWHITESPACE%%> this.timer_ = window.setInterval(function() { <%%KEEPWHITESPACE%%> var diff = new Date - t; <%%KEEPWHITESPACE%%> if (timeDiv) timeDiv.textContent = (diff / 1000).toFixed(2) + ' seconds'; <%%KEEPWHITESPACE%%> }, 100); }; PuzzleDemo.prototype.addRandomCountries_ = function() { <%%KEEPWHITESPACE%%> // Shuffle countries <%%KEEPWHITESPACE%%> this.countries_.sort(function() { <%%KEEPWHITESPACE%%> return Math.round(Math.random()) - 0.5; <%%KEEPWHITESPACE%%> }); <%%KEEPWHITESPACE%%> var countries = this.countries_.slice(0, PuzzleDemo.NUM_PIECES_); <%%KEEPWHITESPACE%%> for (var i = 0, country; country = countries[i]; i++) { <%%KEEPWHITESPACE%%> this.addCountry_(country); <%%KEEPWHITESPACE%%> } }; PuzzleDemo.prototype.addCountry_ = function(country) { <%%KEEPWHITESPACE%%> var options = { <%%KEEPWHITESPACE%%> strokeColor: PuzzleDemo.START_COLOR_, <%%KEEPWHITESPACE%%> strokeOpacity: 0.8, <%%KEEPWHITESPACE%%> strokeWeight: 2, <%%KEEPWHITESPACE%%> fillColor: PuzzleDemo.START_COLOR_, <%%KEEPWHITESPACE%%> fillOpacity: 0.35, <%%KEEPWHITESPACE%%> geodesic: true, <%%KEEPWHITESPACE%%> map: this.map_, <%%KEEPWHITESPACE%%> draggable: true, <%%KEEPWHITESPACE%%> zIndex: 2, <%%KEEPWHITESPACE%%> paths: country.start.map(google.maps.geometry.encoding.decodePath), <%%KEEPWHITESPACE%%> }; <%%KEEPWHITESPACE%%> var poly = new google.maps.Polygon(options); <%%KEEPWHITESPACE%%> google.maps.event.addListener(poly, 'dragend', function() { <%%KEEPWHITESPACE%%> this.checkPosition_(poly, country); <%%KEEPWHITESPACE%%> }.bind(this)); <%%KEEPWHITESPACE%%> this.polys_.push(poly); }; PuzzleDemo.prototype.boundsContainsPoly_ = function(bounds, poly) { <%%KEEPWHITESPACE%%> var b = new google.maps.LatLngBounds( <%%KEEPWHITESPACE%%> new google.maps.LatLng(bounds[0][0], bounds[0][1]), <%%KEEPWHITESPACE%%> new google.maps.LatLng(bounds[1][0], bounds[1][1])); <%%KEEPWHITESPACE%%> var paths = poly.getPaths().getArray(); <%%KEEPWHITESPACE%%> for (var i = 0; i < paths.length; i++) { <%%KEEPWHITESPACE%%> var p = paths[i].getArray(); <%%KEEPWHITESPACE%%> for (var j = 0; j < p.length; j++) { <%%KEEPWHITESPACE%%> if (!b.contains(p[j])) { <%%KEEPWHITESPACE%%> return false; <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> } <%%KEEPWHITESPACE%%> return true; }; PuzzleDemo.prototype.replacePiece_ = function(poly, country) { <%%KEEPWHITESPACE%%> var options = { <%%KEEPWHITESPACE%%> strokeColor: PuzzleDemo.END_COLOR_, <%%KEEPWHITESPACE%%> fillColor: PuzzleDemo.END_COLOR_, <%%KEEPWHITESPACE%%> draggable: false, <%%KEEPWHITESPACE%%> zIndex: 1, <%%KEEPWHITESPACE%%> paths: country.end.map(google.maps.geometry.encoding.decodePath), <%%KEEPWHITESPACE%%> }; <%%KEEPWHITESPACE%%> poly.setOptions(options); <%%KEEPWHITESPACE%%> this.count_++; <%%KEEPWHITESPACE%%> this.setCount_(); }; PuzzleDemo.prototype.checkPosition_ = function(poly, country) { <%%KEEPWHITESPACE%%> if (this.boundsContainsPoly_(country.bounds, poly)) { <%%KEEPWHITESPACE%%> this.replacePiece_(poly, country); <%%KEEPWHITESPACE%%> } }; PuzzleDemo.prototype.start_ = function() { <%%KEEPWHITESPACE%%> this.setDifficultyStyle_(); <%%KEEPWHITESPACE%%> this.resetGame_(); }; PuzzleDemo.prototype.removeCountries_ = function() { <%%KEEPWHITESPACE%%> for (var i = 0, poly; poly = this.polys_[i]; i++) { <%%KEEPWHITESPACE%%> poly.setMap(null); <%%KEEPWHITESPACE%%> }; <%%KEEPWHITESPACE%%> this.polys_ = []; }; function initMap() { <%%KEEPWHITESPACE%%> var map = new google.maps.Map(document.getElementById('map'), { <%%KEEPWHITESPACE%%> disableDefaultUI: true, <%%KEEPWHITESPACE%%> center: {lat: 10, lng: 60}, <%%KEEPWHITESPACE%%> zoom: 2 <%%KEEPWHITESPACE%%> }); <%%KEEPWHITESPACE%%> (new PuzzleDemo).init(map); } <%%KEEPWHITESPACE%%> </script> <%%KEEPWHITESPACE%%> <script src="https://maps.googleapis.com/maps/api/js?key= AIzaSyB6O25GLEFd5l6wYeEgmLzMWZS7bs-IyU8&libraries=geometry&callback=initMap" <%%KEEPWHITESPACE%%> async defer></script> <%%KEEPWHITESPACE%%> </body> </html>