summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-10-19 01:31:31 +0200
committerTor Andersson <tor@ccxvii.net>2023-10-20 19:06:35 +0200
commit89d05a73e3e91ad727174f1d9ac6cb720e460332 (patch)
tree735b2e6e70fcac092e5ac18203d50f8e14229973
parent2a9f4e4e5bab2345e12d43ae7bbca307c829091b (diff)
downloadwilderness-war-89d05a73e3e91ad727174f1d9ac6cb720e460332.tar.gz
Mobile layout.
-rw-r--r--about.html6
-rw-r--r--play.css113
-rw-r--r--play.html115
-rw-r--r--play.js92
4 files changed, 183 insertions, 143 deletions
diff --git a/about.html b/about.html
index 4c8c869..9c020b9 100644
--- a/about.html
+++ b/about.html
@@ -9,16 +9,16 @@ frontier, build fortification networks through the harsh wilderness, recruit
Indian allies, besiege forts and fortresses, and deal with events occurring in
Europe that are above and beyond your control.
-<br clear="left">
<p>
Designer: Volko Ruhnke.
-
-<p>
+<br>
Copyright &copy; 2010
<a href="https://www.gmtgames.com/p-1045-wilderness-war-4th-printing.aspx">GMT Games, LLC</a>.
<br>
Cover art by Rodger B. MacGowan &copy; 2001, 2013.
+<br>
+Programming &copy; 2021 Tor Andersson.
<ul>
<li><a href="/wilderness-war/info/rulebook.html">Rulebook</a>
diff --git a/play.css b/play.css
index b5a87a7..ec67b56 100644
--- a/play.css
+++ b/play.css
@@ -5,7 +5,7 @@ body.France header.your_turn { background-color: lightskyblue; }
body.Britain header.your_turn { background-color: salmon; }
#role_France, #log .h2.france { background-color: #bdf; }
#role_Britain, #log .h2.britain { background-color: #fcb; }
-aside { width: 220px; }
+aside { min-width: 220px; }
:root {
--highlight-color: yellow;
@@ -17,6 +17,11 @@ aside { width: 220px; }
.checked::before { content: "\2714 " }
.unchecked::before { content: "\2714 "; color:transparent; }
+@media (max-width: 600px) {
+ #stack_menu { display: none }
+ #piece_button { display: none }
+}
+
/* LOG */
#log { background-color: floralwhite; }
@@ -53,11 +58,21 @@ aside { width: 220px; }
/* CARDS */
.hand {
- margin: 15px;
+ margin: 10px auto;
+ padding: 15px;
display: flex;
+ gap: 20px;
flex-wrap: wrap;
justify-content: center;
- min-height: 370px;
+ min-width: calc(242px * 3 + 30px + 20px * 2);
+ max-width: calc(2550px - 30px);
+ min-height: 340px;
+}
+
+@media (max-width: 800px) {
+ .hand {
+ min-width: calc(2550px - 30px);
+ }
}
.card {
@@ -85,7 +100,6 @@ aside { width: 220px; }
transform: translateY(-10px);
}
-.hand .card { margin: 10px; }
.hand .card { display: none; }
.hand .card.show { display: block; }
@@ -101,11 +115,17 @@ aside { width: 220px; }
margin: 0 auto;
}
+@media (max-height: 800px) {
+ .card_info {
+ display: none;
+ }
+}
+
#tooltip {
display: none;
pointer-events: none;
position: fixed;
- z-index: 300;
+ z-index: 600;
right: 240px;
top: 60px;
}
@@ -114,10 +134,21 @@ aside { width: 220px; }
display: block;
}
+@media (max-width: 800px) {
+ #tooltip {
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ margin: auto;
+ }
+}
+
/* CARD LIST DIALOGS */
.card_list_dialog {
position: fixed;
+ background-color: floralwhite;
width: 300px;
border: 1px solid black;
box-shadow: 0px 5px 10px 0px rgba(0,0,0,0.5);
@@ -141,8 +172,7 @@ aside { width: 220px; }
}
.card_list_body {
padding: 5px 10px;
- background-color: floralwhite;
- overflow-y: scroll;
+ overflow-y: auto;
max-height: 500px;
}
.card_list_body div {
@@ -150,29 +180,37 @@ aside { width: 220px; }
margin-left: 30px;
}
-#removed { top: 100px; left: 100px; z-index: 98; }
-#discard { top: 100px; left: 425px; z-index: 99; }
+#removed { top: 120px; left: 50px; z-index: 498; }
+#discard { top: 145px; left: 75px; z-index: 499; }
+
+@media (max-width: 400px) {
+ .card_list_dialog {
+ position: static;
+ grid-column: 1;
+ grid-row: 2;
+ width: auto;
+ box-shadow: none;
+ border: none;
+ }
+ .card_list_body {
+ max-height: none;
+ }
+}
/* CARD MENU */
#popup {
- position: fixed;
- user-select: none;
- background-color: white;
- left: 10px;
- top: 100px;
- box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.3);
- z-index: 300;
- min-width: 20ex;
- white-space: nowrap;
- display: none;
- border: 1px solid black;
+ box-shadow: 2px 2px 4px #0004;
+ min-width: 160px;
+ max-width: 250px;
}
-#popup div { padding: 3pt 8pt; color: gray; display: none; }
-#popup div.enabled { color: black; display: block; }
-#popup div.enabled:hover { background-color: black; color: white; }
-#popup div.always { display: block; }
-body:not(.shift) #popup #menu_discard { display: none; }
+
+#popup li.title {
+ text-align: center;
+ white-space: normal;
+}
+
+body:not(.shift) #popup li[data-action="discard"] { display: none; }
/* MAP */
@@ -615,28 +653,3 @@ body.bevel .unit.french.highlight{box-shadow:0 0 0 1px #29607a,0 0 0 4px var(--h
body.bevel .leader.selected{box-shadow:0 0 0 3px var(--selected-color)}
body.bevel .unit.british.selected{box-shadow:0 0 0 3px var(--selected-color)}
body.bevel .unit.french.selected{box-shadow:0 0 0 3px var(--selected-color)}
-
-/* MOBILE PHONE LAYOUT */
-
-@media (max-width: 640px) {
- .hand .card {
- width: 120px;
- height: 168px;
- border-radius: 8px;
- }
- .hand {
- min-height: 168px;
- }
- #tooltip {
- top: 10px;
- right: 10px;
- }
- #removed, #discard {
- position: static;
- box-shadow: none;
- border-top: none;
- width: auto;
- }
- #removed { grid-row: 3; }
- #discard { grid-row: 4; }
-}
diff --git a/play.html b/play.html
index 8d4451f..d7ac9b8 100644
--- a/play.html
+++ b/play.html
@@ -1,15 +1,16 @@
<!DOCTYPE html>
<html lang="en">
<head>
-<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1">
+<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, interactive-widget=resizes-content, viewport-fit=content, viewport-fit=cover">
+<meta name="theme-color" content="#444">
<meta charset="utf-8">
<title>WILDERNESS WAR</title>
<link rel="icon" href="logo.png">
<link rel="stylesheet" href="/fonts/fonts.css">
-<link rel="stylesheet" href="/common/play.css">
+<link rel="stylesheet" href="/common/client.css">
<link rel="stylesheet" href="play.css">
<link rel="stylesheet" href="images.css">
-<script defer src="/common/play.js"></script>
+<script defer src="/common/client.js"></script>
<script defer src="data.js"></script>
<script defer src="play.js"></script>
</head>
@@ -17,14 +18,16 @@
<div id="tooltip"></div>
-<div id="popup" onmouseleave="hide_popup_menu()">
-<div id="menu_play_event" class="always" onclick="on_play_event()">Play Event</div>
-<div id="menu_activate_force" class="always" onclick="on_activate_force()">Activate force</div>
-<div id="menu_activate_individually" class="always" onclick="on_activate_individually()">Activate individually</div>
-<div id="menu_construct_stockades" class="always" onclick="on_construct_stockades()">Construct stockades</div>
-<div id="menu_construct_forts" class="always" onclick="on_construct_forts()">Construct forts</div>
-<div id="menu_discard" onclick="on_discard()">Discard</div>
-</div>
+<menu id="popup">
+ <li class="title">CARD
+ <li class="separator">
+ <li data-action="play_event"> &#x1f3b4; &nbsp; Play Event
+ <li data-action="activate_force"> &#x1f464; &nbsp; Activate force
+ <li data-action="activate_individually"> &#x1f465; &nbsp; Activate individually
+ <li data-action="construct_stockades"> &#x1f528; &nbsp; Construct stockades
+ <li data-action="construct_forts"> &#x1f528; &nbsp; Construct forts
+ <li data-action="discard"> &#x1f6ab; &nbsp; Discard
+</menu>
<div id="removed" class="card_list_dialog hide">
<div id="removed_x" class="card_list_x" onclick="hide_card_list('removed')">&#x274c;</div>
@@ -40,53 +43,49 @@
<header>
<div id="toolbar">
- <div class="menu">
- <div class="menu_title"><img src="/images/cog.svg"></div>
- <div class="menu_popup">
- <a class="menu_item" href="info/rulebook.html" target="_blank">Rulebook</a>
- <a class="menu_item" href="info/playbook.html" target="_blank">Playbook</a>
- <a class="menu_item" href="info/charts.html" target="_blank">Charts &amp; Tables</a>
- <a class="menu_item" href="info/cards.html" target="_blank">Cards</a>
- <a class="menu_item" href="info/pieces.html" target="_blank">Leaders &amp; Units</a>
- <div class="resign menu_separator"></div>
- <div class="resign menu_item" onclick="confirm_resign()">Resign</div>
- </div>
- </div>
- <div class="menu">
- <div class="menu_title"><img src="/images/stack.svg"></div>
- <div class="menu_popup">
- <div id="stack_v" class="menu_item unchecked" onclick="set_layout(0)">Vertical</div>
- <div id="stack_h" class="menu_item unchecked" onclick="set_layout(1)">Horizontal</div>
- <div id="stack_d" class="menu_item unchecked" onclick="set_layout(2)">Diagonal</div>
- <div class="menu_separator"></div>
- <div id="mouse_focus" class="menu_item unchecked" onclick="set_mouse_focus()">Mouse-focus</div>
- <div class="menu_separator"></div>
- <div id="style_bevel" class="menu_item unchecked" onclick="set_style('bevel')">Beveled</div>
- <div id="style_flat" class="menu_item unchecked" onclick="set_style('flat')">Flat</div>
- </div>
- </div>
- <div class="menu">
- <div class="menu_title"><img src="/images/wooden-sign.svg"></div>
- <div class="menu_popup">
- <div class="menu_item" onclick="send_query('supply')">Supply lines</div>
- <div class="menu_item" onclick="send_query('removed')">Removed</div>
- <div class="menu_item" onclick="send_query('discard')">Discard</div>
- </div>
- </div>
- <div class="icon_button" onclick="toggle_counters()"><img src="/images/earth-america.svg"></div>
- <div class="icon_button" onclick="toggle_zoom()"><img src="/images/magnifying-glass.svg"></div>
- <div class="icon_button" onclick="toggle_log()"><img src="/images/scroll-quill.svg"></div>
- <div id="demolish_menu" class="menu hide">
- <div class="menu_title"><img src="/images/dig-dug.svg"></div>
- <div class="menu_popup">
- <div id="demolish_fort" class="menu_item" onclick="send_action('demolish_fort')">Demolish fort</div>
- <div id="demolish_stockade" class="menu_item" onclick="send_action('demolish_stockade')">Demolish stockade</div>
- <div id="demolish_fieldworks" class="menu_item" onclick="send_action('demolish_fieldworks')">Demolish fieldworks</div>
- </div>
- </div>
+ <details>
+ <summary><img src="/images/cog.svg"></summary>
+ <menu>
+ <li><a href="info/rulebook.html" target="_blank">Rulebook</a>
+ <li><a href="info/playbook.html" target="_blank">Playbook</a>
+ <li><a href="info/charts.html" target="_blank">Charts &amp; Tables</a>
+ <li><a href="info/cards.html" target="_blank">Cards</a>
+ <li><a href="info/pieces.html" target="_blank">Leaders &amp; Units</a>
+ <li class="resign separator">
+ <li class="resign" onclick="confirm_resign()">Resign
+ </menu>
+ </details>
+ <details id="stack_menu">
+ <summary><img src="/images/stack.svg"></summary>
+ <menu>
+ <li class="unchecked" id="stack_v" onclick="set_layout(0)"> Vertical
+ <li class="unchecked" id="stack_h" onclick="set_layout(1)"> Horizontal
+ <li class="unchecked" id="stack_d" onclick="set_layout(2)"> Diagonal
+ <li class="separator">
+ <li class="unchecked" id="mouse_focus" onclick="set_mouse_focus()"> Mouse-focus
+ <li class="separator">
+ <li class="unchecked" id="style_bevel" onclick="set_style('bevel')"> Beveled
+ <li class="unchecked" id="style_flat" onclick="set_style('flat')"> Flat
+ </menu>
+ </details>
+ <details id="info_menu">
+ <summary><img src="/images/wooden-sign.svg"></summary>
+ <menu>
+ <li onclick="send_query('supply')"> Supply lines
+ <li onclick="send_query('removed')"> Removed
+ <li onclick="send_query('discard')"> Discard
+ </menu>
+ </details>
+ <button id="piece_button" onclick="toggle_counters()"><img src="/images/earth-america.svg"></button>
+ <details id="demolish_menu" class="hide">
+ <summary><img src="/images/dig-dug.svg"></summary>
+ <menu>
+ <li id="demolish_fort" onclick="send_action('demolish_fort')"> Demolish fort
+ <li id="demolish_stockade" onclick="send_action('demolish_stockade')"> Demolish stockade
+ <li id="demolish_fieldworks" onclick="send_action('demolish_fieldworks')"> Demolish fieldworks
+ </menu>
+ </details>
</div>
- <div id="prompt"></div>
- <div id="actions"></div>
</header>
<aside>
@@ -110,7 +109,7 @@
<div id="log"></div>
</aside>
-<main>
+<main data-max-zoom="2" onclick="hide_popup_menu()">
<div id="mapwrap">
<div id="map">
<div id="events">
diff --git a/play.js b/play.js
index 45904b3..882fece 100644
--- a/play.js
+++ b/play.js
@@ -701,37 +701,68 @@ function on_blur_card(evt) {
// CARD MENU
-const card_action_menu = [
- 'play_event',
- 'activate_force',
- 'activate_individually',
- 'construct_stockades',
- 'construct_forts',
- 'discard',
-]
+var card_action_menu = Array.from(document.getElementById("popup").querySelectorAll("li[data-action]")).map(e => e.dataset.action)
+
+function is_popup_menu_action(menu_id, target_id) {
+ let menu = document.getElementById(menu_id)
+ for (let item of menu.querySelectorAll("li")) {
+ let action = item.dataset.action
+ if (action)
+ return true
+ }
+ return false
+}
+
+function show_popup_menu(evt, menu_id, target_id, title) {
+ let menu = document.getElementById(menu_id)
+
+ let show = false
+ for (let item of menu.querySelectorAll("li")) {
+ let action = item.dataset.action
+ if (action) {
+ if (is_action(action, target_id)) {
+ show = true
+ item.classList.add("action")
+ item.classList.remove("disabled")
+ item.onclick = function () {
+ send_action(action, target_id)
+ hide_popup_menu()
+ evt.stopPropagation()
+ }
+ } else {
+ item.classList.remove("action")
+ item.classList.add("disabled")
+ item.onclick = null
+ }
+ }
+ }
+
+ if (show) {
+ menu.onmouseleave = hide_popup_menu
+ menu.style.display = "block"
+ if (title) {
+ let item = menu.querySelector("li.title")
+ if (item) {
+ item.onclick = hide_popup_menu
+ item.textContent = title
+ }
+ }
-let current_popup_card = 0
+ let w = menu.clientWidth
+ let h = menu.clientHeight
+ let x = Math.max(5, Math.min(evt.clientX - w / 2, window.innerWidth - w - 5))
+ let y = Math.max(5, Math.min(evt.clientY - 12, window.innerHeight - h - 40))
+ menu.style.left = x + "px"
+ menu.style.top = y + "px"
-function show_popup_menu(evt, list) {
- document.querySelectorAll("#popup div").forEach(e => e.classList.remove('enabled'))
- for (let item of list) {
- let e = document.getElementById("menu_" + item)
- e.classList.add('enabled')
+ return true
}
- let popup = document.getElementById("popup")
- popup.style.display = 'block'
- popup.style.left = (evt.clientX-50) + "px"
- popup.style.top = (evt.clientY-12) + "px"
- cards[current_popup_card].element.classList.add("selected")
+
+ return false
}
function hide_popup_menu() {
- let popup = document.getElementById("popup")
- popup.style.display = 'none'
- if (current_popup_card) {
- cards[current_popup_card].element.classList.remove("selected")
- current_popup_card = 0
- }
+ document.getElementById("popup").style.display = "none"
}
function is_card_enabled(card) {
@@ -744,20 +775,17 @@ function is_card_enabled(card) {
return false
}
-function is_card_action(action, card) {
+function is_action(action, card) {
return view.actions && view.actions[action] && view.actions[action].includes(card)
}
function on_click_card(evt) {
let card = evt.target.card
- if (is_card_action('card', card)) {
+ if (is_action('card', card)) {
send_action('card', card)
} else {
- let menu = card_action_menu.filter(a => is_card_action(a, card))
- if (menu.length > 0) {
- current_popup_card = card
- show_popup_menu(evt, menu)
- }
+ show_popup_menu(evt, "popup", card, cards[card].name)
+ evt.stopPropagation()
}
}