Merged in feature/MAPG-4-show-the-real-position-on-a-map-after-the-guess (pull request #4)
Feature/MAPG-4 show the real position on a map after the guess
This commit is contained in:
commit
1d4bfd75d8
@ -5,8 +5,8 @@ require '../main.php';
|
|||||||
// very basic routing
|
// very basic routing
|
||||||
$url = $_SERVER['REQUEST_URI'];
|
$url = $_SERVER['REQUEST_URI'];
|
||||||
switch($url) {
|
switch($url) {
|
||||||
case '/':
|
case '/game':
|
||||||
$controller = new MapGuesser\Controller\GuessController();
|
$controller = new MapGuesser\Controller\GameController();
|
||||||
break;
|
break;
|
||||||
case '/getNewPosition.json':
|
case '/getNewPosition.json':
|
||||||
$controller = new MapGuesser\Controller\GetNewPosition();
|
$controller = new MapGuesser\Controller\GetNewPosition();
|
||||||
|
@ -1,9 +1,53 @@
|
|||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
font-size: 100%;
|
||||||
|
vertical-align: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p, button {
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bold {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #ffffff;
|
||||||
|
background-color: #5e77aa;
|
||||||
|
padding: 8px 15px;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover, button:focus {
|
||||||
|
background-color: #29457f;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:disabled {
|
||||||
|
cursor: no-drop;
|
||||||
|
color: #dddddd;
|
||||||
|
background-color: #808080;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
#panorama {
|
#panorama {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -18,6 +62,7 @@ html, body {
|
|||||||
height: 150px;
|
height: 150px;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
visibility: visible;
|
||||||
transition-property: width, height, opacity;
|
transition-property: width, height, opacity;
|
||||||
transition-duration: 0.1s;
|
transition-duration: 0.1s;
|
||||||
transition-delay: 0.8s;
|
transition-delay: 0.8s;
|
||||||
@ -26,7 +71,7 @@ html, body {
|
|||||||
#guess:hover {
|
#guess:hover {
|
||||||
width: 500px;
|
width: 500px;
|
||||||
height: 350px;
|
height: 350px;
|
||||||
opacity: 1.0;
|
opacity: 0.95;
|
||||||
transition-delay: 0s;
|
transition-delay: 0s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,26 +95,39 @@ html, body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#guessButton {
|
#guessButton {
|
||||||
cursor: pointer;
|
padding: 0;
|
||||||
font-size: 14px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #ffffff;
|
|
||||||
background-color: #5e77aa;
|
|
||||||
border: none;
|
|
||||||
border-radius: 3px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
#guessButton:hover, #guessButton:focus {
|
#result {
|
||||||
background-color: #29457f;
|
position: absolute;
|
||||||
outline: none;
|
top: 50px;
|
||||||
|
left: 50px;
|
||||||
|
right: 50px;
|
||||||
|
bottom: 50px;
|
||||||
|
opacity: 0.95;
|
||||||
|
z-index: 2;
|
||||||
|
visibility: hidden;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#guessButton:disabled {
|
#resultMap {
|
||||||
cursor: no-drop;
|
height: 70%;
|
||||||
color: #dddddd;
|
width: 100%;
|
||||||
background-color: #808080;
|
}
|
||||||
opacity: 0.7;
|
|
||||||
|
#resultInfo {
|
||||||
|
height: 30%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
#resultInfo p {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
font-size: 24px;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,18 @@ var Util = {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return angle * Util.EARTH_RADIUS_IN_METER;
|
return angle * Util.EARTH_RADIUS_IN_METER;
|
||||||
|
},
|
||||||
|
|
||||||
|
printDistanceForHuman: function (distance) {
|
||||||
|
if (distance < 1000) {
|
||||||
|
return Number.parseFloat(distance).toFixed(0) + ' m';
|
||||||
|
} else if (distance < 10000) {
|
||||||
|
return Number.parseFloat(distance / 1000).toFixed(2) + ' km';
|
||||||
|
} else if (distance < 100000) {
|
||||||
|
return Number.parseFloat(distance / 1000).toFixed(1) + ' km';
|
||||||
|
} else {
|
||||||
|
return Number.parseFloat(distance / 1000).toFixed(0) + ' km';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -49,11 +61,11 @@ var realPosition;
|
|||||||
var panorama;
|
var panorama;
|
||||||
var guessMap;
|
var guessMap;
|
||||||
var guessMarker;
|
var guessMarker;
|
||||||
|
var resultMap;
|
||||||
|
var resultMarkers = { guess: null, real: null };
|
||||||
var googleLink;
|
var googleLink;
|
||||||
|
|
||||||
function initialize() {
|
function initialize() {
|
||||||
getNewPosition();
|
|
||||||
|
|
||||||
guessMap = new google.maps.Map(document.getElementById('guessMap'), {
|
guessMap = new google.maps.Map(document.getElementById('guessMap'), {
|
||||||
disableDefaultUI: true,
|
disableDefaultUI: true,
|
||||||
clickableIcons: false,
|
clickableIcons: false,
|
||||||
@ -71,41 +83,21 @@ function initialize() {
|
|||||||
guessMarker = new google.maps.Marker({
|
guessMarker = new google.maps.Marker({
|
||||||
map: guessMap,
|
map: guessMap,
|
||||||
position: e.latLng,
|
position: e.latLng,
|
||||||
draggable: true
|
clickable: false,
|
||||||
|
draggable: true,
|
||||||
|
label: {
|
||||||
|
color: '#ffffff',
|
||||||
|
fontFamily: 'Roboto',
|
||||||
|
fontSize: '18px',
|
||||||
|
fontWeight: '500',
|
||||||
|
text: '?'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('guessButton').disabled = false;
|
document.getElementById('guessButton').disabled = false;
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
function getNewPosition() {
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.responseType = 'json';
|
|
||||||
xhr.onreadystatechange = function () {
|
|
||||||
if (this.readyState == 4 && this.status == 200) {
|
|
||||||
realPosition = this.response.position;
|
|
||||||
|
|
||||||
var sv = new google.maps.StreetViewService();
|
|
||||||
sv.getPanorama({ location: this.response.position, preference: google.maps.StreetViewPreference.BEST }, loadPano);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.open('GET', 'getNewPosition.json', true);
|
|
||||||
xhr.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadPano(data, status) {
|
|
||||||
if (status !== google.maps.StreetViewStatus.OK) {
|
|
||||||
getNewPosition();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (panorama) {
|
|
||||||
panorama.setPano(data.location.pano);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
panorama = new google.maps.StreetViewPanorama(document.getElementById('panorama'), {
|
panorama = new google.maps.StreetViewPanorama(document.getElementById('panorama'), {
|
||||||
pano: data.location.pano,
|
|
||||||
disableDefaultUI: true,
|
disableDefaultUI: true,
|
||||||
linksControl: true,
|
linksControl: true,
|
||||||
showRoadLabels: false
|
showRoadLabels: false
|
||||||
@ -118,6 +110,37 @@ function loadPano(data, status) {
|
|||||||
panorama.addListener('pov_changed', function () {
|
panorama.addListener('pov_changed', function () {
|
||||||
MapManipulator.rewriteGoogleLink();
|
MapManipulator.rewriteGoogleLink();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
resultMap = new google.maps.Map(document.getElementById('resultMap'), {
|
||||||
|
disableDefaultUI: true,
|
||||||
|
clickableIcons: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
getNewPosition();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNewPosition() {
|
||||||
|
var xhr = new XMLHttpRequest();
|
||||||
|
xhr.responseType = 'json';
|
||||||
|
xhr.onreadystatechange = function () {
|
||||||
|
if (this.readyState == 4 && this.status == 200) {
|
||||||
|
realPosition = this.response.position;
|
||||||
|
|
||||||
|
var sv = new google.maps.StreetViewService();
|
||||||
|
sv.getPanorama({ location: this.response.position, preference: google.maps.StreetViewPreference.NEAREST }, loadPano);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.open('GET', 'getNewPosition.json', true);
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadPano(data, status) {
|
||||||
|
if (status !== google.maps.StreetViewStatus.OK) {
|
||||||
|
getNewPosition();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
panorama.setPano(data.location.pano);
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('guessButton').onclick = function () {
|
document.getElementById('guessButton').onclick = function () {
|
||||||
@ -126,14 +149,58 @@ document.getElementById('guessButton').onclick = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var guessedPosition = guessMarker.getPosition();
|
var guessedPosition = guessMarker.getPosition();
|
||||||
var distance = Util.calculateDistance(realPosition, { lat: guessedPosition.lat(), lng: guessedPosition.lng() });
|
|
||||||
|
|
||||||
alert('You were ' + (Math.round(distance) / 1000) + ' km close!');
|
|
||||||
|
|
||||||
this.disabled = true;
|
this.disabled = true;
|
||||||
guessMarker.setMap(null);
|
guessMarker.setMap(null);
|
||||||
guessMarker = null;
|
guessMarker = null;
|
||||||
//TODO: fit to the same size as on init
|
|
||||||
|
var distance = Util.calculateDistance(realPosition, { lat: guessedPosition.lat(), lng: guessedPosition.lng() });
|
||||||
|
|
||||||
|
document.getElementById('guess').style.visibility = 'hidden';
|
||||||
|
document.getElementById('result').style.visibility = 'visible';
|
||||||
|
|
||||||
|
var resultBounds = new google.maps.LatLngBounds();
|
||||||
|
resultBounds.extend(realPosition);
|
||||||
|
resultBounds.extend(guessedPosition);
|
||||||
|
|
||||||
|
resultMap.fitBounds(resultBounds);
|
||||||
|
|
||||||
|
resultMarkers.real = new google.maps.Marker({
|
||||||
|
map: resultMap,
|
||||||
|
position: realPosition,
|
||||||
|
clickable: true,
|
||||||
|
draggable: false
|
||||||
|
});
|
||||||
|
resultMarkers.guess = new google.maps.Marker({
|
||||||
|
map: resultMap,
|
||||||
|
position: guessedPosition,
|
||||||
|
clickable: false,
|
||||||
|
draggable: false,
|
||||||
|
label: {
|
||||||
|
color: '#ffffff',
|
||||||
|
fontFamily: 'Roboto',
|
||||||
|
fontSize: '18px',
|
||||||
|
fontWeight: '500',
|
||||||
|
text: '?'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
resultMarkers.real.addListener('click', function () {
|
||||||
|
window.open('https://www.google.com/maps/search/?api=1&query=' + realPosition.lat + ',' + realPosition.lng, '_blank');
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById('distance').innerHTML = Util.printDistanceForHuman(distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('continueButton').onclick = function () {
|
||||||
|
resultMarkers.real.setMap(null);
|
||||||
|
resultMarkers.real = null;
|
||||||
|
resultMarkers.guess.setMap(null);
|
||||||
|
resultMarkers.guess = null;
|
||||||
|
|
||||||
|
document.getElementById('guess').style.visibility = 'visible';
|
||||||
|
document.getElementById('result').style.visibility = 'hidden';
|
||||||
|
|
||||||
guessMap.fitBounds(guessMapBounds);
|
guessMap.fitBounds(guessMapBounds);
|
||||||
|
|
||||||
getNewPosition();
|
getNewPosition();
|
||||||
|
@ -6,7 +6,7 @@ use MapGuesser\View\HtmlView;
|
|||||||
use MapGuesser\View\ViewBase;
|
use MapGuesser\View\ViewBase;
|
||||||
use mysqli;
|
use mysqli;
|
||||||
|
|
||||||
class GuessController implements ControllerInterface
|
class GameController implements ControllerInterface
|
||||||
{
|
{
|
||||||
public function run(): ViewBase
|
public function run(): ViewBase
|
||||||
{
|
{
|
||||||
@ -30,6 +30,6 @@ class GuessController implements ControllerInterface
|
|||||||
$bounds = Bounds::createDirectly($map['bound_south_lat'], $map['bound_west_lng'], $map['bound_north_lat'], $map['bound_east_lng']);
|
$bounds = Bounds::createDirectly($map['bound_south_lat'], $map['bound_west_lng'], $map['bound_north_lat'], $map['bound_east_lng']);
|
||||||
|
|
||||||
$data = compact('bounds');
|
$data = compact('bounds');
|
||||||
return new HtmlView('guess', $data);
|
return new HtmlView('game', $data);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,7 +3,8 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>MapGuesser</title>
|
<title>MapGuesser</title>
|
||||||
<link rel="stylesheet" type="text/css" href="static/css/mapguesser.css">
|
<link href="static/css/mapguesser.css" rel="stylesheet">
|
||||||
|
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;500&display=swap" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="panorama"></div>
|
<div id="panorama"></div>
|
||||||
@ -13,6 +14,13 @@
|
|||||||
<button id="guessButton" disabled>Guess</button>
|
<button id="guessButton" disabled>Guess</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="result">
|
||||||
|
<div id="resultMap"></div>
|
||||||
|
<div id="resultInfo">
|
||||||
|
<p>You were <span id="distance" class="bold"></span> close.</p>
|
||||||
|
<button id="continueButton">Continue</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script>
|
<script>
|
||||||
var guessMapBounds = <?= $bounds->toJson() ?>;
|
var guessMapBounds = <?= $bounds->toJson() ?>;
|
||||||
</script>
|
</script>
|
Loading…
Reference in New Issue
Block a user