diff options
-rw-r--r-- | about.html | 9 | ||||
-rw-r--r-- | play.css | 100 | ||||
-rw-r--r-- | play.html | 68 | ||||
-rw-r--r-- | play.js | 53 |
4 files changed, 151 insertions, 79 deletions
@@ -3,15 +3,10 @@ Crusader Rex is a wargame of the 3rd Crusade. One player plays the Christian Franks, the other, the Muslim Saracens. The objective of the game is to control important Victory Cities such as Jerusalem, Acre, Damascus, and Antioch. -<br clear="left"> - <p> Designer: Jerry Taylor and Tom Dalgliesh. - -<p> -Copyright © 2005-2011 -<a href="https://columbiagames.com/cgi-bin/query/cfg/zoom.cfg?product_id=3151">Columbia Games</a> -and Jerry Taylor. +<br> Copyright © 2005-2011 <a href="https://columbiagames.com/cgi-bin/query/cfg/zoom.cfg?product_id=3151">Columbia Games</a> and Jerry Taylor. +<br> Programming © 2021 Tor Andersson. <ul> <li><a href="/crusader-rex/info/rules.html">Rulebook</a> @@ -42,12 +42,20 @@ body.Saracens header.your_turn { background-color: lightgreen; } } .hand { - margin: 25px; + margin: 0 auto; display: flex; flex-wrap: wrap; justify-content: center; min-height: 348px; gap: 16px; + min-width: 750px; + padding: 24px; +} + +@media (max-width: 800px) { + .hand { + min-width: 1275px; + } } .card { @@ -81,35 +89,46 @@ body.Saracens header.your_turn { background-color: lightgreen; } filter: grayscale(100%) contrast(70%) brightness(120%); } + .role_info { - overflow: clip; /* clip dropshadow from filter:grayscale() stacking context */ - padding-top: 16px; + overflow: clip; + transition: height 100ms, padding 100ms; + height: 84px; + padding: 12px 0; } .role_info .card { width: 168px; height: 261px; border-radius: 9px; - margin: 0 auto 16px auto; + margin: 0 auto; } -.role_info .card:not(:hover) { - margin: 0 auto; - height: 96px; - border-bottom-right-radius: 0; - border-bottom-left-radius: 0; +.role:hover .role_info { + height: 261px; +} + +@media (max-height: 650px) { + .role:not(:hover) .role_info { display: none; } +} + +@media (max-height: 800px) { + #turn_info { display: none; } + .role_info { height: 60px; padding: 8px 0; } } /* MAP */ -#mapwrap { - background-color: #224467; - box-shadow: 0px 1px 10px rgba(0,0,0,0.5); +#padmap { + margin: 0 auto; width: 1275px; height: 2475px; + padding: 0 24px; } #map { + margin: 0; + box-shadow: 0px 1px 10px rgba(0,0,0,0.5); width: 1275px; height: 2475px; background-color: #224467; @@ -179,13 +198,14 @@ body.shift .block.known:hover { z-index: 100; } -#battle .block { position: relative; } #map .block { position: absolute; z-index: 2; } #map .block.highlight { z-index: 3; } #map .block.selected { z-index: 4; } #map .block.known { z-index: 5; } #map .block.known:hover { z-index: 6; } +#battle .block { position: relative; } + .block { background-repeat: no-repeat; border-radius: 6px; @@ -272,33 +292,12 @@ body.shift .block.known:hover { transition-timing-function: ease; } -/* LANDSCAPE MAP */ - -@media (min-width: 2000px) { - #mapwrap:not(.fit) { - box-shadow: 1px 0px 10px rgba(0,0,0,0.5); - height: 1275px; - width: 2475px; - margin-bottom: 40px; - margin-top: 30px; - } - #mapwrap:not(.fit) #map { - transform: translateY(1275px) rotate(-90deg); - transform-origin: 0 0; - } - body.shift #mapwrap:not(.fit) #map .block.known:hover { - transform: rotate(90deg) scale(2) !important; - } - #mapwrap:not(.fit) #map .block { transform: rotate(90deg); } - #mapwrap:not(.fit) #map .block.r1 { transform: rotate(0deg); } - #mapwrap:not(.fit) #map .block.r2 { transform: rotate(-90deg); } - #mapwrap:not(.fit) #map .block.r3 { transform: rotate(-180deg); } -} - /* BATTLE BOARD */ #battle { background-color: tan; + left: calc(90px + max(0px, calc(50% - (1275px + 48px) / 2))); + top: 320px; } #battle_message { background-color: gainsboro; @@ -350,6 +349,35 @@ body.shift .block.known:hover { #FC.c3, #EC.c3 { background-image: url('castle_3.svg'); width: 300px; } #FC.c4, #EC.c4 { background-image: url('castle_4.svg'); width: 380px; } +/* LANDSCAPE MAP */ + +@media (min-width: 2000px) { + #battle { + top: 745px; + left: calc(500px + max(0px, calc(50% - 2475px / 2))); + } + .hand { + width: 2475px; + } + #padmap { + height: 1275px; + width: 2475px; + padding: 24px 0; + overflow: clip; + } + #map { + transform: translateY(1275px) rotate(-90deg); + transform-origin: 0 0; + } + body.shift #padmap #map > .block.known:hover { + transform: rotate(90deg) scale(2) !important; + } + #blocks > .block { transform: rotate(90deg); } + #blocks > .block.r1 { transform: rotate(0deg); } + #blocks > .block.r2 { transform: rotate(-90deg); } + #blocks > .block.r3 { transform: rotate(-180deg); } +} + /* CARD AND BLOCK IMAGES */ .card_back{background-image:url('cards/card_back.jpg')} @@ -1,53 +1,39 @@ <!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=cover"> +<meta name="theme-color" content="#444"> <meta charset="UTF-8"> <title>CRUSADER REX</title> <link rel="icon" href="Cross_of_the_Knights_Templar.svg"> <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="/common/columbia.css"> <link rel="stylesheet" href="play.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> <body> -<div id="battle"> -<div id="battle_header"></div> -<div id="ER"></div> -<div id="EC"></div> -<div id="EF"></div> -<div id="FF"></div> -<div id="FC"></div> -<div id="FR"></div> -<div id="battle_message"></div> -</div> - <header> <div id="toolbar"> - <div class="menu"> - <div class="menu_title"><img src="/images/cog.svg"></div> - <div class="menu_popup"> - <div class="menu_item" onclick="set_spread_layout()">Spread blocks</div> - <div class="menu_item" onclick="set_stack_layout()">Stack blocks</div> - <div class="menu_separator"></div> - <a class="menu_item" href="info/notes.html" target="_blank">Notes</a> - <a class="menu_item" href="info/rules.html" target="_blank">Rules</a> - <a class="menu_item" href="info/cards.html" target="_blank">Cards</a> - <a class="menu_item" href="info/blocks.html" target="_blank">Blocks</a> - <div class="resign menu_separator"></div> - <div class="resign menu_item" onclick="confirm_resign()">Resign</div> - </div> - </div> - <div class="icon_button" onclick="toggle_blocks()"><img src="/images/earth-africa-europe.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> + <details> + <summary><img src="/images/cog.svg"></summary> + <menu> + <li onclick="set_spread_layout()">Spread blocks + <li onclick="set_stack_layout()">Stack blocks + <li class="separator"> + <li><a href="info/notes.html" target="_blank">Notes</a> + <li><a href="info/rules.html" target="_blank">Rules</a> + <li><a href="info/cards.html" target="_blank">Cards</a> + <li><a href="info/blocks.html" target="_blank">Blocks</a> + <li class="resign separator"> + <li class="resign" onclick="confirm_resign()">Resign + </menu> + </details> + <div class="icon_button" onclick="toggle_blocks()"><img src="/images/earth-africa-europe.svg"></div> </div> - <div id="prompt"></div> - <div id="actions"></div> </header> <aside> @@ -73,10 +59,22 @@ <div id="log"></div> </aside> -<main> +<main data-min-zoom="1" data-max-zoom="2" data-map-width="1323" data-map-height="1323"> -<div id="mapwrap"> +<div id="battle"> +<div id="battle_header"></div> +<div id="ER"></div> +<div id="EC"></div> +<div id="EF"></div> +<div id="FF"></div> +<div id="FC"></div> +<div id="FR"></div> +<div id="battle_message"></div> +</div> + +<div id="padmap"> <div id="map"> + <svg id="svgmap" width="1275px" height="2475px" viewBox="0 0 1275 2475"> <path id="sea" d="M30 1201v1170l2-1c1 0 4-1 5-3 2-1 4-2 5-2 2 0 5-1 7-2 3-2 7-4 11-6 3-2 7-4 8-6 1-1 3-2 3-2 2 0 47-23 54-27 4-2 10-6 14-8 7-3 13-7 27-19 4-3 5-4 5-8l1-4h5c4 0 7-1 12-5 6-4 27-24 41-41 7-8 20-21 23-24 1-1 4-3 5-6l6-6c1-1 3-3 4-5 2-3 3-4 10-12 3-3 6-7 6-9 1-1 2-3 3-4 2-1 5-5 7-9 2-3 4-6 5-6 2 0 5-6 5-9 0-2 2-6 5-10s5-7 5-8 0-1 1-1 1-1 2-3c1-4 3-9 8-14 4-5 7-12 7-14 0-1 2-6 4-10 3-4 5-9 6-10 0-1 1-4 3-5 1-2 2-4 2-5 0 0 1-3 3-5 2-3 3-5 3-10 0-6 1-9 4-14 2-3 3-7 3-8 0-3 4-20 6-22 2-3 4-11 4-17 0-1 0-3 1-3 0 0 2-2 2-5 1-2 3-7 4-9 1-3 2-9 3-15 1-11 1-10 0-18 0-5 0-7 1-9s2-5 2-7c1-3 1-5 2-7 0-1 1-4 1-6v-8c4-22 4-23 3-26-1-2-1-4 0-6s1-8 1-13 1-9 1-10v-5c-1-3-1-8-1-12v-10-36c0-8-1-21-2-23 0-1-1-5-1-10 0-14-1-27-2-35-1-3-1-8-1-11s-2-10-5-17c-1-1-1-2 0-3 1-2 1-2 0-3 0-1-1-2 0-2 0-1 0-2-1-3 0-1 0-4-1-7 0-3-1-6-2-9-1-2-2-4-1-4 0-1-1-2-2-2-1-2-1-2 1-3s2-1 3-8c0-5 0-8-2-11-1-2-1-7-1-11-1-5-1-8-3-12-4-6-3-10 0-13 5-4 18-4 26 0l5 3 3-2c1-2 4-3 6-4 3-1 10-9 15-16 2-3 2-3 1-12-2-13-4-18-9-16-2 0-3 0-2-3 0-2-1-4-3-7-2-4-2-5-3-16 0-22-1-28-2-29s-1-2 0-3c2-1-1-9-3-12-2-1-2-2-1-5 0-4 2-7 8-9 9-5 10-5 10-6s1-3 3-5c1-2 2-5 2-6-1-1-1-2 0-3 1 0 1-2 1-2-1-2 0-2 3-2 2 0 4-1 6-3 3-3 4-9 3-10s0-2 1-3c4-3 3-5 0-16-2-5-3-6-6-8-2-1-6-2-8-2-5 0-5-2-1-2 6-2 7-2 8-4 0-2 1-5 2-8 0-3 1-6 2-7s1-3 1-3c-1-1 0-2 0-3 1 0 1-3 1-6v-13c0-4-1-8-1-9-1-2-1-3 1-4 2-2 2-2 1-5 0-2-1-4 0-4 0-1 1-3 2-5 1-3 1-4-1-5-1-1-1-1 2-3 2-2 3-3 3-4s1-2 3-2c4-2 12-10 16-16 2-2 3-4 4-4 0 0 1-1 2-3 1-1 2-4 4-6s2-3 2-6c-1-2-1-5-1-6s0-3-1-4-1-1 1-3c4-3 6-11 4-14-1-2-1-2 1-4 1-2 1-2 0-6-1-2-2-5-1-6 0 0 0-2-1-2-1-2 0-2 3-4l4-3-2-6c-1-3-2-7-3-7-2-1 1-4 4-4s7-4 7-8c0-1-1-4-2-5-2-3-3-6-2-7 1 0 1-1 1-2s2-6 5-11c4-7 4-9 4-13-1-11-12-33-16-33-2 0-7-3-7-4s5-4 8-5c1 0 7 0 12-1s10-1 11-2c3-2 6-1 7 1 1 3 3 4 3 2 0-3 3-5 7-6 7-2 11-4 13-9 1-2 2-4 2-5v-7c-1-4 0-6 1-7 1 0 2-2 1-4 0-2 0-3 3-4 1 0 3-2 3-3 1-1 2-2 5-2 5-1 8-5 6-8-1-2-6-4-11-4-1 0-3-1-4-1-2-2-1-13 0-16 1-1 2-5 2-9 1-8 1-9-2-12-2-2-4-4-5-4 0 0-2-1-2-3-2-2-3-3-6-4-6-1-7-1-7-3 0-1-1-3-2-5-1-3-2-5-2-7 0-1-1-3-2-4-1-3-1-5 3-7 3-3 6-9 4-11 0-1-1-3 0-4 0-1-1-2-3-4-3-3-3-3-2-4 1-2 1-2-2-3-4-3-4-4 1-8 3-2 3-3 3-6-1-4-1-4 4-6 4-3 5-3 8-2 7 1 14-2 15-6v-5c1-1 0-4 0-7-2-3-2-5-1-5 0-1 1-3 1-4 0-3 0-3 3-5 2 0 5-1 7-1 1 0 3-1 5-2 0-1 2-2 3-2l4-2c1-2 3-3 4-3 0 0 2-1 3-3 1-1 5-3 7-4 4-2 4-3 4-6 0-1-1-3-2-4-2-1-4-3-5-4-1-2-4-3-5-4-5-1-3-2 4-2 6 0 13-1 14-3 1-1 11-5 16-6 2-1 4-2 4-3 0-2 5-4 10-3 3 0 4 0 9-5 3-3 6-6 6-7 0-2 13-13 15-14 2 0 5-1 8-2l5-2v-6c0-5-1-7-4-14-2-4-6-10-8-12-5-6-28-25-36-28-2-1-6-5-9-8-4-3-7-6-8-7-4-1-8-6-11-12-2-5-3-7-7-9-2-2-5-3-5-3-1 0-9-5-10-6-5-5-19-15-22-16-1-1-2-2-2-3l-5-5c-7-5-9-9-9-15-1-4-2-7-5-9 0-1-1-2-1-4s0-3-1-3-1-2-2-4c0-3 0-4 4-8 2-2 4-5 4-5 0-2-12-14-15-16-4-2-5-6-3-9s1-5-3-7c-3-1-4-4-2-5 1-1 1-2 1-3s1-3 3-4c2-2 3-3 3-5 0-1 0-4 2-6 2-3 3-5 1-8s0-5 5-8c5-2 9-6 9-8 0-4-20-18-30-22-8-3-10-6-10-12-1-6-1-7-6-13-2-3-4-6-4-8 0-1-2-5-6-9-7-9-8-11-7-15 0-3 0-3-3-4-1-1-6-2-11-2-11-2-10-2-27-9-4-2-8-3-11-3s-10-1-15-2c-5 0-10-1-11-1-7 0-15 2-19 4s-8 2-9-1c0-1 0-3 1-4 2-3 1-6-1-8-1-1-6-2-13-3-14-2-15-2-13-5 1-2 1-3 0-4s-2-1-6 1c-2 1-4 2-5 2 0-1 4-4 11-8 5-2 7-3 7-5 0-1 1-2 3-3 1 0 2-1 2-3s0-3 1-4c1 0 1-1 1-3s-1-3-4-5c-2-2-5-3-6-4-4-1-5-3-2-7 1-2 3-3 7-4 5-1 5-1 8-7 1-3 3-6 5-7 1-1 3-4 3-7 1-3 3-7 3-8 1-1 1-3 1-4-1-3-11-13-17-16-3-2-7-5-10-8-2-2-5-4-7-4-1 0-2-1-3-2s-2-2-4-3l-3-1 7-2c3 0 9-1 12-2 7-1 12-3 18-7 5-4 7-8 7-15 0-5 1-7 10-14 1-1 2-3 2-4 0-3 5-14 9-18s5-6 4-9c0-2 0-3 4-5 6-2 6-4-1-9-6-4-9-7-14-13-2-1-5-4-7-6-3-2-7-5-8-7-2-1-6-3-9-4-2-1-5-2-6-3-2-1-13-6-15-6s-11-4-11-5c-1-1-9-5-18-10-18-8-30-15-35-18-2-2-12-5-31-10-7-3-12-7-12-11 0-2 1-4 5-7 4-4 6-7 7-10l2-5 9-5c10-4 12-6 12-12s1-7 8-10c10-5 11-7 11-12-1-4-1-5 4-9 4-5 9-8 21-12 4-1 11-4 15-7 9-4 10-5 11-9 2-8 8-13 18-16 8-2 11-6 12-13v-5H30v1171z"/> </svg> @@ -111,6 +111,46 @@ let ui = { present: new Set(), } +function remember_position(e) { + if (e.classList.contains("show")) { + let rect = e.getBoundingClientRect() + e.my_parent = true + e.my_x = rect.x + e.my_y = rect.y + } else { + e.my_parent = false + e.my_x = 0 + e.my_y = 0 + } +} + +function animate_position(e) { + if (e.parentElement) { + if (e.my_parent) { + let rect = e.getBoundingClientRect() + let dx = e.my_x - rect.x + let dy = e.my_y - rect.y + if (dx !== 0 || dy !== 0) { + e.animate( + [ + { transform: `translate(${dx}px, ${dy}px)`, }, + { transform: "translate(0, 0)", }, + ], + { duration: 250, easing: "ease" } + ) + } + } else { + e.animate( + [ + { opacity: 0 }, + { opacity: 1 } + ], + { duration: 250, easing: "ease" } + ) + } + } +} + function on_focus_space_tip(x) { ui.towns[x].classList.add("tip") } @@ -869,6 +909,9 @@ function on_update() { document.getElementById("frank_vp").textContent = view.f_vp document.getElementById("saracen_vp").textContent = view.s_vp + for (let c = 1; c <= 27; ++c) + remember_position(ui.cards[c]) + update_cards() update_map() @@ -877,11 +920,19 @@ function on_update() { document.getElementById("battle_message").textContent = view.battle.flash if (view.flash_next) start_flash() - document.getElementById("battle").classList.add("show") + if (!document.getElementById("battle").classList.contains("show")) { + document.getElementById("battle").classList.add("show") + document.getElementById("battle").scrollIntoView({ + block:"center", inline:"center", behavior:"smooth" + }) + } update_battle() } else { document.getElementById("battle").classList.remove("show") } + + for (let c = 1; c <= 27; ++c) + animate_position(ui.cards[c]) } build_map() |