diff options
-rw-r--r-- | web/static/index.html | 15 | ||||
-rw-r--r-- | web/static/style.css | 472 | ||||
-rw-r--r-- | web/web_scoreboard.c | 22 |
3 files changed, 262 insertions, 247 deletions
diff --git a/web/static/index.html b/web/static/index.html index bf7a890..e195e0b 100644 --- a/web/static/index.html +++ b/web/static/index.html @@ -10,6 +10,13 @@ </head> <body> <div id="main"> + <div id="titlebar"> + <div>dartboat™</div> + <div class="input first"><span>delay</span><input id="delay" data-opt="delay" maxlength="4" value=""></div> + <div class="input"><span>stdev</span><input id="stdev" data-opt="stdev" maxlength="4" value=""></div> + <div class="button" id="flip-controls-button">→</div> + <div class="button" data-modal="help-modal">?</div> + </div> <div id="info"> <div id="oi">oi!</div> <div id="p1-info"> @@ -65,20 +72,12 @@ </div> </div> </div> - <div id="settings-bar"> - <div>dartboat™</div> - <div class="input first"><span>delay</span><input id="delay" data-opt="delay" maxlength="4" value=""></div> - <div class="input"><span>stdev</span><input id="stdev" data-opt="stdev" maxlength="4" value=""></div> - <div class="button" id="flip-controls-button">→</div> - <div class="button" data-modal="help-modal">?</div> - </div> <div id="visits"></div> </div> <div id="help-modal" class="modal"> <div class="modal-content"> <h2>dartboat</h2> <p>dartboat uses an internal representation of a specification dartboard. Darts are thrown following a normal distribution, with the resultant coordinates used to calculate the segments in which they land. The idea is that this provides a more realistic opponent than picking points at random.</p> - <p> <h2>Settings</h2> <p><em>stdev</em> — the standard deviation of the bot's throws in millimetres. A value of 24 translates to a three-dart average of roughly 35. A value of 13 would be a 65 average, and a value of 8 a 95 average.</p> <p><em>delay</em> — milliseconds it takes the bot to throw each dart.</p> diff --git a/web/static/style.css b/web/static/style.css index 52ef6ef..9591dc8 100644 --- a/web/static/style.css +++ b/web/static/style.css @@ -11,8 +11,9 @@ body { padding: 0; } -div#main { +#main { background-color: #111; + font-size: clamp(1.5vh, 2.5vw, 2vh); height: 100vh; width: 100vw; @@ -21,160 +22,131 @@ div#main { display: grid; grid-template-columns: 80vh 1fr; grid-template-rows: min-content min-content minmax(0, 3fr); - grid-template-areas: 'settings-bar settings-bar' 'info visits' 'controls visits'; - grid-gap: 2px; -} - -div#main.controls-on-right { - grid-template-columns: 1fr 80vh; - grid-template-areas: 'settings-bar settings-bar' 'visits info' 'visits controls'; -} - -div#controls { - grid-area: controls; - - font-size: clamp(1.5vh, 2.5vw, 2vh); - - display: grid; - grid-template-columns: repeat(3, 1fr); - grid-template-rows: minmax(5em, auto); - grid-auto-rows: 1fr; + grid-template-areas: 'titlebar titlebar' 'info visits' 'controls visits'; gap: 2px; } -div#controls .keypad { - display: none; +@media (max-aspect-ratio: 8/5) { + #main { + width: min(80vh, 100vw); + grid-template-columns: 1fr; + grid-template-rows: min-content min-content minmax(0, 2fr) minmax(0, 3fr); + grid-template-areas: 'titlebar' 'info' 'visits' 'controls'; + } } -div#controls .keypad.visible { - display: contents; +#main.controls-on-right { + grid-template-columns: 1fr 80vh; + grid-template-areas: 'titlebar titlebar' 'visits info' 'visits controls'; } -div#controls #keypad-select_mode .key { - grid-column: 1 / -1; +/* titlebar */ - padding-left: 0.4rem; - - justify-content: left; -} - -div#controls #keypad-dartboard #dartboard-container { - grid-column: 1 / -1; +#titlebar { + grid-area: titlebar; background-color: #1a1a1a; + font-size: 1.5em; - min-width: 0; - min-height: 0; padding: 0.4rem; display: flex; align-items: center; - justify-content: center; + justify-content: left; + gap: 0.4rem; } -div#controls #keypad-dartboard #dartboard { - font-family: 'Inter'; - height: 100%; +#titlebar div.input.first { + margin-left: auto; } -div#oi { - visibility: hidden; - - background-color: #640016; - font-size: 3em; - height: 1.2em; - width: 3ch; - - outline: #111 solid 2px; - - position: absolute; - left: 50%; - right: 50%; - top: 50%; - bottom: 50%; - transform: translate(-50%, -50%); +#titlebar div.input { + background-color: #222; display: flex; + flex-wrap: wrap; align-items: center; justify-content: center; } -div#oi.visible { - visibility: visible; +#titlebar span { + padding: 0 0.4rem; } -div#info { - position: relative; - - font-size: clamp(1.5vh, 2.5vw, 2vh); +#titlebar input { + color: #eee; + background-color: #3d2466; + font-family: inherit; + font-size: 1em; + text-align: right; - display: grid; - grid-template-columns: repeat(2, 1fr); + width: 4ch; + padding: 0 0.4rem; + border: 0; } -div#p1-info, div#p2-info { - background-color: #222; - font-size: 1.5em; - - padding: 0.4rem; +#titlebar div.button { + background-color: #3d2466; + font-weight: 700; - flex-direction: column; - display: flex; - align-items: center; + padding: 0 0.4em; } -div#p1-info { - margin-right: 1px; -} +@media (hover: hover) and (pointer: fine) { + #titlebar input:hover { + background-color: #5c3699; + } -div#p2-info { - margin-left: 1px; + #titlebar div.button:hover { + background-color: #5c3699; + } } -div#p1-info.active, div#p2-info.active { - background-color: #304010; +#titlebar input:focus { + color: #fff; + background-color: #6e41b8; + outline: #7eab1e solid 2px; } -div#p1-info-inner, div#p2-info-inner { - display: contents; - visibility: hidden; +#titlebar div.button:active { + color: #fff; + background-color: #6e41b8; } -div#p1-info-inner.visible, div#p2-info-inner.visible { - visibility: visible; -} +@media (max-aspect-ratio: 9/20) { + #titlebar div.input { + display: flex; + flex-direction: column; + } -div#p1-rem, div#p2-rem { - font-size: 3em; - font-weight: bold; -} + #titlebar span { + padding: 0 0.4rem; + } -div#p1-name, div#p2-name { - color: #ccc; + #titlebar .button { + font-size: 2em; + } } -div#p1-sugg, div#p2-sugg { - color: #aaa; - font-size: 0.8em; +@media (max-aspect-ratio: 8/5) { + #titlebar #flip-controls-button { + display: none; + } } -div#p1-name:after, div#p2-name:after, -div#p1-rem:after, div#p2-rem:after, -div#p1-sugg:after, div#p2-sugg:after { - content: '\200b'; -} +/* controls */ -div#p1-avg, div#p2-avg { - font-size: 0.8em; - align-self: left; - width: 100%; -} +#controls { + grid-area: controls; -div#p1-avg:before, div#p2-avg:before { - content: 'avg: '; + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: minmax(5em, auto); + grid-auto-rows: 1fr; + gap: 2px; } -div#prompt { +#controls #prompt { grid-column: 1 / span 3; background-color: #222; @@ -184,11 +156,11 @@ div#prompt { justify-content: center; } -div#prompt.active { +#controls #prompt.active { background-color: #311d52; } -div#prompt-msg-l, div#prompt-input, div#prompt-msg-r { +#controls #prompt-msg-l, #controls #prompt-input, #controls #prompt-msg-r { font-size: 1.5em; white-space: pre-line; @@ -196,23 +168,60 @@ div#prompt-msg-l, div#prompt-input, div#prompt-msg-r { align-items: center; } -div#prompt-msg-l, div#prompt-msg-r { +#controls #prompt-msg-l, #prompt-msg-r { flex: 1; color: #ccc; padding: 0 0.4rem; } -div#prompt-msg-r { +#controls #prompt-msg-r { text-align: right; } -div#prompt-input { +#controls #prompt-input { text-align: center; font-size: 3em; width: 4ch; } -div.key { +#controls .keypad { + display: none; +} + +#controls .keypad.visible { + display: contents; +} + +#controls #keypad-select_mode .key { + grid-column: 1 / -1; + + padding-left: 0.4rem; + + justify-content: left; +} + +#controls #keypad-dartboard #dartboard-container { + grid-column: 1 / -1; + + background-color: #1a1a1a; + + min-width: 0; + min-height: 0; + padding: 0.4rem; + + display: flex; + align-items: center; + justify-content: center; +} + +#controls #keypad-dartboard #dartboard { + font-family: 'Inter'; + height: 100%; + + filter: drop-shadow(0 0 0.4rem #111); +} + +#controls .key { color: #ccc; background-color: #282828; font-size: 1.5em; @@ -223,140 +232,154 @@ div.key { } @media (hover: hover) and (pointer: fine) { - div.key:hover { + #controls .key:hover { background-color: #304010; } } -div.key:active { +#controls .key:active { color: #fff; background-color: #384810; } -div.key.active { +#controls .key.active { color: #eee; background-color: #3d2466; } @media (hover: hover) and (pointer: fine) { - div.key.active:hover { + #controls .key.active:hover { background-color: #5c3699; } } -div.key.active:active { +#controls .key.active:active { color: #fff; background-color: #6e41b8; } -div.key span.keyboard-val { +#controls .key span.keyboard-val { display: contents; color: #aaa; } -div.key.num { +#controls .key.num { font-size: 2.5em; font-weight: 700; } -div.key#key-submit { +#controls .key#key-submit { grid-row-end: span 2; } -div#settings-bar { - grid-area: settings-bar; +/* player info */ - background-color: #1a1a1a; - font-size: clamp(1.5vh, 2.5vw, 2vh); +#info { + position: relative; - padding: 0.4rem; + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 2px; +} + +#info #oi { + visibility: hidden; + + background-color: #640016; + font-size: 3em; + height: 1.2em; + width: 3ch; + + outline: #111 solid 2px; + + position: absolute; + left: 50%; + right: 50%; + top: 50%; + bottom: 50%; + transform: translate(-50%, -50%); display: flex; align-items: center; - justify-content: left; - gap: 0.4rem; -} - -div#settings-bar div { - font-size: 1.5em; + justify-content: center; } -div#settings-bar div.input.first { - margin-left: auto; +#info #oi.visible { + visibility: visible; } -div#settings-bar div.input { +#info #p1-info, #info #p2-info { background-color: #222; + font-size: 1.5em; + padding: 0.4rem; + + flex-direction: column; display: flex; - flex-wrap: wrap; align-items: center; - justify-content: center; } -div#settings-bar span { - padding: 0 0.4rem; +#info #p1-info.active, #info #p2-info.active { + background-color: #304010; } -div#settings-bar input { - color: #eee; - background-color: #3d2466; - font-family: inherit; - font-size: 1em; - text-align: right; +#info #p1-info-inner, #info #p2-info-inner { + display: contents; + visibility: hidden; +} - width: 4ch; - padding: 0 0.4rem; - border: 0; +#info #p1-info-inner.visible, #info #p2-info-inner.visible { + visibility: visible; } -div#settings-bar div.button { - background-color: #3d2466; - font-weight: 700; +#info #p1-rem, #info #p2-rem { + font-size: 3em; + font-weight: bold; +} - padding: 0 0.4em; +#info #p1-name, #info #p2-name { + color: #ccc; } -@media (hover: hover) and (pointer: fine) { - div#settings-bar input:hover { - background-color: #5c3699; - } +#info #p1-sugg, #info #p2-sugg { + color: #aaa; + font-size: 0.8em; +} - div#settings-bar div.button:hover { - background-color: #5c3699; - } +#info #p1-name:after, #info #p2-name:after, +#info #p1-rem:after, #info #p2-rem:after, +#info #p1-sugg:after, #info #p2-sugg:after { + content: '\200b'; } -div#settings-bar input:focus { - color: #fff; - background-color: #6e41b8; - outline: #7eab1e solid 2px; +#info #p1-avg, #info #p2-avg { + font-size: 0.8em; + width: 100%; } -div#settings-bar div.button:active { - color: #fff; - background-color: #6e41b8; +#info #p1-avg:before, #info #p2-avg:before { + content: 'avg: '; } -div#visits { +/* visits */ + +#visits { grid-area: visits; background-color: #111; - font-size: clamp(1.5vh, 2.5vw, 2vh); + font-size: 2em; overflow: auto; scrollbar-gutter: stable both-edges; padding: 0.4rem; display: grid; - grid-template-columns: repeat(5, min(calc(calc(100% - 4ch) / 5), 10ch)) min-content; + grid-template-columns: repeat(5, min(calc(calc(100% - 2ch) / 5), 5ch)) min-content; grid-auto-rows: min-content; - grid-row-gap: 0.3em; + row-gap: 0.2em; } -div#visits div { - font-size: 2em; - +#visits > * { min-width: 0; display: flex; @@ -364,27 +387,58 @@ div#visits div { justify-content: center; } -div#visits .visit-col1 { grid-column: 1; } -div#visits .visit-col2 { grid-column: 2; } -div#visits .visit-col3 { color: #555; grid-column: 3; } -div#visits .visit-col6 { color: #555; grid-column: 6; } -div#visits .p0 { color: #e00018; } -div#visits .p20 { color: #e06000; } -div#visits .p40 { color: #e09800; } -div#visits .p60 { color: #e0e018; } -div#visits .p100 { color: #78c018; } -div#visits .p140 { color: #20e018; } -div#visits .p180 { color: #20e018; font-weight: bold; } -div#visits .visit-col6 { color: #555; justify-content: left; white-space: nowrap; font-size: 1.5em; } -div#visits .visit-col6:not(:empty):before { content: '\2003'; } -div#visits .visit-name1 { grid-column: 1 / span 2; } -div#visits .visit-name2 { grid-column: 4 / span 2; } -div#visits .visit-name1, div#visits .visit-name2 { +#visits .p0 { color: #e00018; } +#visits .p20 { color: #e06000; } +#visits .p40 { color: #e09800; } +#visits .p60 { color: #e0e018; } +#visits .p100 { color: #78c018; } +#visits .p140 { color: #20e018; } +#visits .p180 { color: #20e018; font-weight: bold; } +#visits .visit-p1-name { grid-column: 1 / span 2; } +#visits .visit-p2-name { grid-column: 4 / span 2; } +#visits .visit-p1-pts { grid-column: 1; } +#visits .visit-p1-rem { grid-column: 2; } +#visits .visit-n { grid-column: 3; } +#visits .visit-p2-rem { grid-column: 4; } +#visits .visit-p2-pts { grid-column: 5; } +#visits .visit-p2-darts { grid-column: 6; } +#visits .visit-p1-name, #visits .visit-p2-name { color: #555; border-bottom: 2px solid #555; - display: flex; +} +#visits .visit-n { + color: #555; +} +#visits .visit-p2-darts { + color: #555; + font-size: 0.75em; + justify-content: left; + white-space: nowrap; +} +#visits .visit-p2-darts:not(:empty):before { + content: '\2003'; } +@media (max-aspect-ratio: 8/5) { + #visits { + grid-template-columns: 1ch 1fr repeat(5, min(calc(calc(100% - 2ch) / 5), 5ch)) 1fr 1ch; + } + #visits .visit-p1-name, #visits .visit-p2-name { + display: none; + } + #visits .visit-p1-pts { grid-column: 3; } + #visits .visit-p1-rem { grid-column: 4; } + #visits .visit-n { grid-column: 5; } + #visits .visit-p2-rem { grid-column: 6; } + #visits .visit-p2-pts { grid-column: 7; } + #visits .visit-p2-darts { grid-column: 9; } + #visits .visit-p2-darts:not(:empty):before { + content: '…\2003'; + } +} + +/* modals */ + .modal { background-color: #000a; @@ -426,48 +480,10 @@ div#visits .visit-name1, div#visits .visit-name2 { margin-top: 1em; } -a { +.modal-content a { color: #7eab1e; } -a:hover { +.modal-content a:hover { color: #a8e428; } - -@media (max-aspect-ratio: 9/20) { - div#settings-bar div.input { - display: flex; - flex-direction: column; - } - - div#settings-bar span { - padding: 0 0.4rem; - } - - div#settings-bar .button { - font-size: 3em; - } -} - -@media (max-aspect-ratio: 1.6) { - div#main { - width: min(80vh, 100vw); - grid-template-columns: 1fr; - grid-template-rows: min-content min-content minmax(0, 2fr) minmax(0, 3fr); - grid-template-areas: 'settings-bar' 'info' 'visits' 'controls'; - } - - #flip-controls-button { - display: none; - } - - div#visits { - grid-template-columns: 2ch 1fr repeat(5, min(calc(calc(100% - 4ch) / 5), 10ch)) 1fr 2ch; - } - div#visits .visit-col1 { grid-column: 3; } - div#visits .visit-col2 { grid-column: 4; } - div#visits .visit-col3 { grid-column: 5; } - div#visits .visit-col6 { grid-column: 9; justify-content: left; } - div#visits .visit-col6:not(:empty):before { content: '…\2003'; } - div#visits .visit-name1, div#visits .visit-name2 { display: none; } -} diff --git a/web/web_scoreboard.c b/web/web_scoreboard.c index 8746cc9..8626443 100644 --- a/web/web_scoreboard.c +++ b/web/web_scoreboard.c @@ -177,18 +177,18 @@ void draw_visits() struct dom_elem **elemv = malloc(6 * (n_visits + 1) * sizeof(*elemv)); int elemc = 0; - elemv[elemc++] = create_div(state->legs[0]->name, "visit-name1"); + elemv[elemc++] = create_div(state->legs[0]->name, "visit-p1-name"); if (state->mode != M_P) elemv[elemc++] = create_div(state->legs[1]->name, - "visit-name2"); + "visit-p2-name"); char buf[32], buf2[32]; snprintf(buf, sizeof(buf), "%d", state->legs[0]->start); - elemv[elemc++] = create_div(buf, "visit-col2"); - elemv[elemc++] = create_div("0", "visit-col3"); + elemv[elemc++] = create_div(buf, "visit-p1-rem"); + elemv[elemc++] = create_div("0", "visit-n"); if (state->mode != M_P) { snprintf(buf, sizeof(buf), "%d", state->legs[1]->start); - elemv[elemc++] = create_div(buf, "visit-col4"); + elemv[elemc++] = create_div(buf, "visit-p2-rem"); } for (int i = 0; i < n_visits; ++i) { @@ -196,25 +196,25 @@ void draw_visits() snprintf(buf, sizeof(buf), "%d", v->points); snprintf(buf2, sizeof(buf2), "%s %s", - "visit-col1", points_class(v->points)); + "visit-p1-pts", points_class(v->points)); elemv[elemc++] = create_div(buf, buf2); snprintf(buf, sizeof(buf), "%d", v->rem); - elemv[elemc++] = create_div(buf, "visit-col2"); + elemv[elemc++] = create_div(buf, "visit-p1-rem"); snprintf(buf, sizeof(buf), "%d", i + 1); - elemv[elemc++] = create_div(buf, "visit-col3"); + elemv[elemc++] = create_div(buf, "visit-n"); if (i >= state->legs[1]->n_visits) continue; v = state->legs[1]->visits + i; snprintf(buf, sizeof(buf), "%d", v->rem); - elemv[elemc++] = create_div(buf, "visit-col4"); + elemv[elemc++] = create_div(buf, "visit-p2-rem"); snprintf(buf, sizeof(buf), "%d", v->points); snprintf(buf2, sizeof(buf2), "%s %s", - "visit-col5", points_class(v->points)); + "visit-p2-pts", points_class(v->points)); elemv[elemc++] = create_div(buf, buf2); if (v->n_darts) { @@ -225,7 +225,7 @@ void draw_visits() j == 0 ? "%s" : "-%s", n); free(n); } - elemv[elemc++] = create_div(buf, "visit-col6"); + elemv[elemc++] = create_div(buf, "visit-p2-darts"); } } |