MAPG-73 introduce map selection

unify CSS
This commit is contained in:
Bence Pőcze 2020-05-30 15:37:26 +02:00
parent 92c35a2087
commit 9ffedf6030
5 changed files with 275 additions and 43 deletions

View File

@ -9,6 +9,9 @@ if (($pos = strpos($url, '?')) !== false) {
$url = substr($url, 0, $pos);
}
switch($url) {
case '/maps':
$controller = new MapGuesser\Controller\MapsController();
break;
case '/game':
$mapId = isset($_GET['map']) ? (int) $_GET['map'] : 0;
$controller = new MapGuesser\Controller\GameController($mapId);
@ -22,7 +25,7 @@ switch($url) {
$controller = new MapGuesser\Controller\PositionController($mapId);
break;
case '/':
header('Location: ' . $host . '/game', true, 302);
header('Location: ' . $host . '/maps', true, 302);
die;
default:
echo 'Error 404';

View File

@ -12,13 +12,35 @@ html, body {
padding: 0;
}
p, button {
p, h1, h2, button, a {
font-family: 'Roboto', sans-serif;
}
h1, h2 {
font-weight: 500;
}
h1 {
font-size: 32px;
line-height: inherit;
}
h2 {
font-size: 24px;
}
p, h2 {
line-height: 150%;
}
p {
font-weight: 300;
font-size: 12px;
font-size: 16px;
}
img {
display: block;
max-width: 100%;
}
.mono {
@ -29,7 +51,37 @@ p {
font-weight: 500;
}
button {
.small {
font-size: 12px;
}
.justify {
text-align: justify;
}
.marginTop {
margin-top: 10px;
}
.marginBottom {
margin-bottom: 10px;
}
svg.inline {
vertical-align: -0.15em;
}
a:link, a:visited {
color: #3b5998;
font-weight: 500;
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
button, a.button {
cursor: pointer;
font-size: 16px;
font-weight: 500;
@ -39,11 +91,15 @@ button {
height: 35px;
border: none;
border-radius: 3px;
display: inline-block;
text-align: center;
line-height: 35px;
}
button:enabled:hover, button:enabled:focus {
button:enabled:hover, button:enabled:focus, a.button:hover, a.button:focus {
background-color: #29457f;
outline: none;
text-decoration: none;
}
button:disabled {
@ -52,33 +108,78 @@ button:disabled {
opacity: 0.7;
}
button.fullWidth {
button.fullWidth, a.button.fullWidth {
padding: 0;
width: 100%;
}
button.gray {
button.gray, a.button.gray {
background-color: #808080;
}
button.gray:hover, button.gray:focus {
button.gray:hover, button.gray:focus, a.button.gray:hover, a.button.gray:focus {
background-color: #555555;
}
div.header {
background-color: #333333;
height: 50px;
line-height: 50px;
padding: 0 12px;
color: white;
}
div.main {
padding: 6px 12px;
}
div.buttonContainer {
height: 35px;
}
div.buttonContainer > button {
div.buttonContainer>button {
margin: 0 auto;
}
div.buttonContainer.top {
margin-bottom: 10px;
div.mapContainer {
display: grid;
}
div.buttonContainer.bottom {
margin-top: 10px;
div.mapItem {
width: 375px;
background-color: #eeeeee;
border-radius: 3px;
margin: 10px auto;
}
div.mapItem>div.title {
background-color: #28a745;
color: white;
border-top-left-radius: 3px;
border-top-right-radius: 3px;
padding: 4px 8px;
}
div.mapItem>div.title>p.title {
font-weight: 500;
font-size: 18px;
}
div.mapItem>div.inner {
padding: 8px;
}
div.mapItem>div.inner>div.info {
display: grid;
grid-template-columns: auto auto;
}
div.mapItem>div.inner>div.info>p:nth-child(1) {
text-align: left;
}
div.mapItem>div.inner>div.info>p:nth-child(2) {
text-align: right;
}
#loading {
@ -108,11 +209,12 @@ div.buttonContainer.bottom {
#roundInfo p {
font-size: 16px;
line-height: inherit;
}
#panorama {
height: 100%;
width: 100%;
height: 100%;
z-index: 1;
}
@ -123,16 +225,15 @@ div.buttonContainer.bottom {
z-index: 2;
}
#guess > #continueButtonContainer {
#guess>#continueButtonContainer {
display: none;
}
#guess.result > #closeGuessButtonContainer,
#guess.result > #guessButtonContainer {
#guess.result>#closeGuessButtonContainer, #guess.result>#guessButtonContainer {
display: none;
}
#guess.result > #continueButtonContainer {
#guess.result>#continueButtonContainer {
display: block;
}
@ -141,14 +242,14 @@ div.buttonContainer.bottom {
border-radius: 3px;
}
#guess.result > #map {
#guess.result>#map {
height: calc(100% - 170px);
}
#resultInfo {
margin-top: 5px;
height: 120px;
width: 100%;
height: 120px;
padding: 5px 20px;
text-align: center;
box-sizing: border-box;
@ -157,13 +258,13 @@ div.buttonContainer.bottom {
display: none;
}
#guess.result > #resultInfo {
#guess.result>#resultInfo {
display: block;
}
#resultInfo > div {
height: 33.33%;
#resultInfo>div {
width: 100%;
height: 33.33%;
display: flex;
justify-content: center;
align-items: center;
@ -171,9 +272,10 @@ div.buttonContainer.bottom {
#resultInfo p {
font-size: 24px;
line-height: 1;
}
#distanceInfo > p:nth-child(2), #scoreInfo > p:nth-child(2) {
#distanceInfo>p:nth-child(2), #scoreInfo>p:nth-child(2) {
display: none;
}
@ -185,8 +287,8 @@ div.buttonContainer.bottom {
}
#scoreBar {
height: 100%;
width: 0;
height: 100%;
border-radius: 3px;
transition-property: width;
transition-duration: 2.0s;
@ -196,12 +298,35 @@ div.buttonContainer.bottom {
display: none;
}
@media screen and (min-width: 1600px) {
div.mapContainer {
grid-template-columns: auto auto auto auto;
}
}
@media screen and (min-width: 1200px) and (max-width: 1599px) {
div.mapContainer {
grid-template-columns: auto auto auto;
}
}
@media screen and (min-width: 800px) and (max-width: 1199px) {
div.mapContainer {
grid-template-columns: auto auto;
}
}
@media screen and (max-width: 799px) {
div.mapContainer {
grid-template-columns: auto;
}
}
@media screen and (max-width: 599px) {
button {
padding: 0;
width: 100%;
}
#showGuessButtonContainer {
position: absolute;
left: 20px;
@ -209,18 +334,15 @@ div.buttonContainer.bottom {
right: 20px;
z-index: 2;
}
#guess {
left: 20px;
top: 40px;
opacity: 0.95;
visibility: hidden;
}
#map {
height: calc(100% - 90px);
}
#scoreBarBase {
width: 100%;
}
@ -230,13 +352,11 @@ div.buttonContainer.bottom {
#showGuessButtonContainer {
display: none;
}
#guess {
width: 500px;
height: 375px;
opacity: 0.95;
}
#guess.adapt {
top: initial;
width: 250px;
@ -246,22 +366,18 @@ div.buttonContainer.bottom {
transition-duration: 0.1s;
transition-delay: 0.8s;
}
#guess.adapt:hover {
width: 500px;
height: 375px;
opacity: 0.95;
transition-delay: 0s;
}
#closeGuessButtonContainer {
display: none;
}
#map {
height: calc(100% - 45px);
}
#guess.result {
width: initial;
height: initial;
@ -270,22 +386,18 @@ div.buttonContainer.bottom {
right: 50px;
bottom: 50px;
}
#scoreBarBase {
width: 60%;
}
@media screen and (max-height: 424px) {
#guess {
top: 40px;
height: initial;
}
#guess.adapt:hover {
top: 40px;
height: initial;
}
#guess.result {
left: 20px;
right: 20px;

View File

@ -0,0 +1,60 @@
<?php
namespace MapGuesser\Controller;
use MapGuesser\Database\Query\Select;
use MapGuesser\Database\RawExpression;
use MapGuesser\Interfaces\Controller\IController;
use MapGuesser\Interfaces\Database\IResultSet;
use MapGuesser\Interfaces\View\IView;
use MapGuesser\Util\Geo\Bounds;
use MapGuesser\View\HtmlView;
class MapsController implements IController
{
public function run(): IView
{
$select = new Select(\Container::$dbConnection, 'maps');
$select->columns([
['maps', 'id'],
['maps', 'name'],
['maps', 'description'],
['maps', 'bound_south_lat'],
['maps', 'bound_west_lng'],
['maps', 'bound_north_lat'],
['maps', 'bound_east_lng'],
new RawExpression('COUNT(places.id) AS num_places')
]);
$select->leftJoin('places', ['places', 'map_id'], '=', ['maps', 'id']);
$select->orderBy('name');
$result = $select->execute();
$maps = [];
while ($map = $result->fetch(IResultSet::FETCH_ASSOC)) {
$bounds = Bounds::createDirectly($map['bound_south_lat'], $map['bound_west_lng'], $map['bound_north_lat'], $map['bound_east_lng']);
$map['area'] = $this->formatMapArea($bounds->calculateApproximateArea());
$maps[] = $map;
}
$data = ['maps' => $maps];
return new HtmlView('maps', $data);
}
private function formatMapArea(float $area): string
{
//TODO: this should be formatted more properly
if ($area < 100000.0) {
return round($area, 0) . ' m^2';
} elseif ($area < 100000000.0) {
return round($area / 1000000.0, 0) . ' km^2';
} elseif ($area < 10000000000.0) {
return round($area / 1000000.0, -2) . ' km^2';
} else {
return round($area / 1000000.0, -4) . ' km^2';
}
}
}

View File

@ -19,11 +19,11 @@
<button id="showGuessButton" class="fullWidth">Show guess map</button>
</div>
<div id="guess">
<div id="closeGuessButtonContainer" class="buttonContainer top">
<div id="closeGuessButtonContainer" class="buttonContainer marginBottom">
<button id="closeGuessButton" class="fullWidth gray">Close</button>
</div>
<div id="map"></div>
<div id="guessButtonContainer" class="buttonContainer bottom">
<div id="guessButtonContainer" class="buttonContainer marginTop">
<button id="guessButton" class="fullWidth" disabled>Guess</button>
</div>
<div id="resultInfo">
@ -41,10 +41,10 @@
</div>
</div>
</div>
<div id="continueButtonContainer" class="buttonContainer bottom">
<div id="continueButtonContainer" class="buttonContainer marginTop">
<button id="continueButton" class="fullWidth">Continue</button>
<button id="showSummaryButton" class="fullWidth">Show summary</button>
<button id="startNewGameButton" class="fullWidth">Start new game</button>
<button id="startNewGameButton" class="fullWidth">Play this map again</button>
</div>
</div>
<script>

57
views/maps.php Normal file
View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MapGuesser</title>
<link href="static/css/mapguesser.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;500&family=Roboto+Mono:wght@300;500&display=swap" rel="stylesheet">
</head>
<body>
<div class="header">
<h1>
<svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="#28a745" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M15.817.613A.5.5 0 0 1 16 1v13a.5.5 0 0 1-.402.49l-5 1a.502.502 0 0 1-.196 0L5.5 14.51l-4.902.98A.5.5 0 0 1 0 15V2a.5.5 0 0 1 .402-.49l5-1a.5.5 0 0 1 .196 0l4.902.98 4.902-.98a.5.5 0 0 1 .415.103zM10 2.41l-4-.8v11.98l4 .8V2.41zm1 11.98l4-.8V1.61l-4 .8v11.98zm-6-.8V1.61l-4 .8v11.98l4-.8z" />
</svg>
MapGuesser
</h1>
</div>
<div class="main">
<h2>Playable maps</h2>
<div class="mapContainer">
<?php foreach ($maps as $map) : ?>
<div class="mapItem">
<div class="title">
<p class="title"><?= $map['name'] ?></p>
</div>
<img src="https://maps.googleapis.com/maps/api/staticmap?size=375x200&visible=<?= $map['bound_south_lat'] . ',' . $map['bound_west_lng'] . '|' . $map['bound_north_lat'] . ',' . $map['bound_east_lng'] ?>&key=<?= $_ENV['GOOGLE_MAPS_JS_API_KEY'] ?>" width="375" height="200">
<div class="inner">
<div class="info">
<p>
<svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M8 16s6-5.686 6-10A6 6 0 0 0 2 6c0 4.314 6 10 6 10zm0-7a3 3 0 1 0 0-6 3 3 0 0 0 0 6z" />
</svg>
<?= $map['num_places'] ?> places
</p>
<p>
<svg class="inline" width="1em" height="1em" viewBox="0 0 16 16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" d="M12.5 2h-9V1h9v1zm-10 1.5v9h-1v-9h1zm11 9v-9h1v9h-1zM3.5 14h9v1h-9v-1z" />
<path fill-rule="evenodd" d="M14 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 11a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4zM2 3a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4zm0 11a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm0 1a2 2 0 1 0 0-4 2 2 0 0 0 0 4z" />
</svg>
~<?= $map['area'] ?>
</p>
</div>
<p class="small justify marginTop"><?= $map['description'] ?></p>
</div>
<a class="button fullWidth" href="game?map=<?= $map['id']; ?>" title="Play map '<?= $map['name'] ?>'">Play this map</a>
</div>
<?php endforeach; ?>
<?php if (count($maps) < 4): ?>
<?php for ($i = 0; $i < 4 - count($maps); ++$i): ?>
<div class="mapItem"></div>
<?php endfor; ?>
<?php endif; ?>
</div>
</div>
</body>
</html>