display items on map, switch to grid layout

closes #2
This commit is contained in:
jomo 2022-08-05 22:04:56 +02:00
parent fda7352e22
commit 8e19a1dbad
6 changed files with 151 additions and 42 deletions

View file

@ -20,9 +20,9 @@
<b>Coordinates</b> (click on map)
<div id="plan">
<div id="map">
<img src="80x80.svg" onclick="mapClick(event)">
<div id="grid"></div>
<div id="mapgrid"></div>
</div>
<label for="coords_bl">Bottom left</label><label for="coords_tr">Top right</label>

View file

@ -35,7 +35,7 @@ function fillForm() {
document.getElementById('note').value = item.note;
document.getElementById('hidden').checked = item.hidden;
coordsToMap(item.coords_bl, item.coords_tr);
formCoordsToMap();
}
const saveBtn = document.getElementById('save');

View file

@ -5,15 +5,26 @@
<link rel="stylesheet" href="style.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="index.js"></script>
<script src="shared.js"></script>
</head>
<body>
<h1>in?</h1>
<div id="grid">
<div id="searchcontainer">
<input type="text" id="search" value="" autocomplete="off" placeholder="RegEx search" tabindex="1" autofocus>
<label for="showhidden">Show hidden items</label> <input type="checkbox" id="showhidden">
<label for="showhidden">Show hidden items</label>
<input type="checkbox" id="showhidden">
</div>
<div id="mapcontainer">
<div id="map">
<img src="80x80.svg">
<div id="mapgrid"></div>
</div>
<p id="mapnote"></p>
</div>
<div id="results">
<span id="loading">loading…</span>
<template id="item">
<div id="" class="result" tabindex="0">
<div id="" class="result" tabindex="0" onfocus="showItem(event)" onfocusout="hideItem(event)">
<h2>
<span class="id"></span>
<span class="name"></span>
@ -27,5 +38,6 @@
</template>
</div>
<a href="form.html" class="btn green">+</a>
</div>
</body>
</html>

View file

@ -39,23 +39,23 @@ function renderItems() {
}
function getLocString(items, item) {
let ancestors = [];
item.ancestors = [];
let next = item;
let loop = false;
while (next) {
if (ancestors.includes(next)) {
if (item.ancestors.includes(next)) {
loop = true;
if (ancestors.length == 1) {
ancestors.push(null);
if (item.ancestors.length == 1) {
item.ancestors.push(null);
}
break;
}
ancestors.unshift(next);
item.ancestors.unshift(next);
next = items[next.is_in];
}
ancestors.pop();
let loc = ancestors.map(i => i.id).join(' ➜ ') || '⬚';
let longloc = ancestors.map(i => `${i.type || ''} ${i.id} ${i.name && `(${i.name})` || ''}`).join(' ➜ ') || 'universe';
item.ancestors.pop();
let loc = item.ancestors.map(i => i.id).join(' ➜ ') || '⬚';
let longloc = item.ancestors.map(i => `${i.type || ''} ${i.id} ${i.name && `(${i.name})` || ''}`).join(' ➜ ') || 'universe';
if (loop) {
loc += ' ↻';
longloc += ' ↻';
@ -69,7 +69,7 @@ function search(e) {
const regex = new RegExp(query, 'i')
for (const elem of document.getElementsByClassName('result')) {
const item = items[elem.id.substr(5)];
const item = items[elem.id.slice(5)];
let found = false;
if (query) {
for (const a in searchAttrs) {
@ -99,3 +99,23 @@ function showhidden(e){
results.classList.remove('showhidden');
}
}
function showItem(e) {
const item = items[e.target.id.slice(5)];
const ancestors = item.ancestors.concat(item);
for (let i = ancestors.length-1; i >= 0; i--) {
const ancestor = ancestors[i];
if (ancestor.coords_bl && ancestor.coords_tr) {
if (ancestor != item) {
const mapnote = `Showing ${ancestor.type || ''} ${ancestor.id} ${ancestor.name && `(${ancestor.name})` || ''}`;
document.getElementById('mapnote').textContent = mapnote;
}
coordsToMap(ancestor.coords_bl, ancestor.coords_tr);
break;
}
}
}
function hideItem(e) {
clearMap();
}

View file

@ -2,7 +2,7 @@ function renderMap(xx, yy) {
if (xx[0] > 0 && xx[0] < 31 && yy[0] > 0 && yy[0] < 9 &&
xx[1] > 0 && xx[1] < 31 && yy[1] > 0 && yy[1] < 9 &&
xx[1] >= xx[0] && yy[1] >= yy[0]) {
let grid = document.getElementById('grid');
let grid = document.getElementById('mapgrid');
grid.style.top = `${yy[0]*10}%`;
grid.style.left = `${100/31*xx[0]}%`;
grid.style.height = `${(yy[1] - yy[0] + 1) * 10}%`;
@ -12,6 +12,14 @@ function renderMap(xx, yy) {
}
}
function clearMap() {
const mapnote = document.getElementById('mapnote');
if (mapnote) {
mapnote.textContent = '';
}
document.getElementById('mapgrid').removeAttribute('style');
}
function coordsToMap(coords_bl, coords_tr) {
let bl_y = coords_bl[0];
let tr_y = coords_tr[0];

View file

@ -4,10 +4,8 @@
body {
font-family: sans-serif;
max-width: 600px;
margin: auto;
padding-bottom: 1em;
background: #fefefe;
padding: 1em;
}
h1, #search {
@ -28,7 +26,12 @@ h1 a {
.result {
background: #eee;
padding: 1em;
margin: 1em 0;
border: 1px solid #bbb;
}
.result:focus {
outline: 2px solid #08f;
border-radius: 1px;
}
.result a {
@ -91,8 +94,10 @@ h2 {
font-weight: bold;
text-align: center;
font-size: 1.5em;
margin: 0.5em 0;
margin: 0.5em auto;
cursor: pointer;
grid-column: 1/-1;
max-width: 400px;
}
.btn.green {
@ -105,6 +110,11 @@ h2 {
color: white;
}
form {
max-width: 600px;
margin: auto;
}
form label {
display: block;
width: 100%;
@ -127,7 +137,7 @@ input, textarea, select {
padding: 0.3em;
font-family: monospace;
font-size: 1.4em;
background: initial;
background: #eee;
border: 1px solid gray;
}
@ -135,34 +145,93 @@ input[type=checkbox] {
width: initial;
display: initial;
min-width: initial;
margin: 0;
}
textarea {
min-height: 8em;
}
#plan {
#mapcontainer {
grid-column: 1/-1;
text-align: center;
position: sticky;
pointer-events: none;
top: 0;
}
#mapcontainer * {
pointer-events: all;
}
#map {
position: relative;
border: 1px solid black;
background: #fff;
max-width: 800px;
max-height: 50vh;
aspect-ratio: 31 / 10;
margin: 0 auto;
}
#plan img {
#mapnote {
min-height: 1.95em;
font-style: italic;
margin: 0;
padding: 0.5em;
display: inline-block;
background: #fff;
border: 1px solid;
border-top: none;
}
#mapnote:empty {
background: none;
border: none;
}
#map img {
width: 100%;
max-height: 100%;
max-width: 100%;
display: block;
}
form #plan {
form #map {
margin: 0.3em 0 1em 0;
}
#grid {
#mapgrid {
position: absolute;
pointer-events: none;
outline: 2px solid #f00;
background: #ff08;
}
#grid:not([style]) {
#mapgrid:not([style]) {
outline: none;
}
#grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
gap: 1em;
}
@media only screen and (max-width: 500px) {
#grid {
grid-template-columns: none;
}
}
#grid #results {
display: contents;
}
#grid #searchcontainer {
grid-column: 1/-1;
width: calc(min(600px, 100%));
max-width: 100%;
text-align: center;
margin: auto;
}