summaryrefslogtreecommitdiff
path: root/server/web/game
diff options
context:
space:
mode:
Diffstat (limited to 'server/web/game')
-rw-r--r--server/web/game/game.js83
-rw-r--r--server/web/game/index.html82
-rw-r--r--server/web/game/style.css56
3 files changed, 140 insertions, 81 deletions
diff --git a/server/web/game/game.js b/server/web/game/game.js
index 4b0024c..78e5547 100644
--- a/server/web/game/game.js
+++ b/server/web/game/game.js
@@ -1,63 +1,60 @@
"use strict";
const showGame = (g) => {
- const tmpl = document.querySelector("template#tmpl");
- const disp = document.querySelector("#game");
- const clone = document.importNode(tmpl.content, true);
- doDistance(clone, g.Distance.Value);
- doActions(clone, g.Actions);
- disp.replaceChildren(clone);
+ const tmpl = document.querySelector("template#tmpl");
+ const disp = document.querySelector("#game");
+ const clone = document.importNode(tmpl.content, true);
+ doDistance(clone, g.Distance.Value);
+ doActions(clone, g.Actions);
+ disp.replaceChildren(clone);
};
const doDistance = (clone, value) => {
- clone.querySelector(".distance").setAttribute("data-value", value);
- [...clone.querySelectorAll(".distance .sakura")].map((n, i) => {
- if (i < value) {
- n.checked = true;
- } else {
- n.checked = false;
- }
- });
+ clone.querySelector("#distance").setAttribute("data-value", value);
+ [...clone.querySelectorAll("#distance .content .sakura")].map((n, i) => {
+ n.checked = i < value;
+ });
+ clone.querySelector("#distance .pool-value").innerText = value
};
const doActions = (g, actions) => {
- const actionList = g.querySelector(".actions");
- const actionTemplate = actionList.querySelector(".action").cloneNode(true);
- if (actions) {
- actionList.replaceChildren(
- ...actions.map((a, i) => {
- const newAction = actionTemplate.cloneNode(true);
- newAction.setAttribute("data-index", i);
- newAction.querySelector(".description").innerText = a.Description;
- return newAction;
- }),
- );
- } else {
- actionList.replaceChildren()
- }
+ const actionList = g.querySelector(".actions");
+ const actionTemplate = actionList.querySelector(".action").cloneNode(true);
+ if (actions) {
+ actionList.replaceChildren(
+ ...actions.map((a, i) => {
+ const newAction = actionTemplate.cloneNode(true);
+ newAction.setAttribute("data-index", i);
+ newAction.querySelector(".description").innerText = a.Description;
+ return newAction;
+ }),
+ );
+ } else {
+ actionList.replaceChildren()
+ }
};
const doAction = (idx) => {
- window.socket.send(String(idx))
+ window.socket.send(String(idx))
}
const connect = (gameId) => {
- const connection = new WebSocket(`/api/game/${gameId}/connect`);
- window.socket = connection;
- connection.addEventListener("message", (ev) => {
- const game = JSON.parse(ev.data);
- console.debug(game);
- showGame(game);
- document.querySelector("#game-json").innerText = JSON.stringify(
- ev.data,
- null,
- 2,
- );
- });
+ const connection = new WebSocket(`/api/game/${gameId}/connect`);
+ window.socket = connection;
+ connection.addEventListener("message", (ev) => {
+ const game = JSON.parse(ev.data);
+ console.debug(game);
+ showGame(game);
+ document.querySelector("#game-json").innerText = JSON.stringify(
+ ev.data,
+ null,
+ 2,
+ );
+ });
};
const init = () => {
- const id = window.location.hash.slice(1);
- connect(id);
+ const id = window.location.hash.slice(1);
+ connect(id);
};
init();
diff --git a/server/web/game/index.html b/server/web/game/index.html
index f4f6593..04e85d2 100644
--- a/server/web/game/index.html
+++ b/server/web/game/index.html
@@ -1,45 +1,51 @@
<!doctype html>
<html lang="en">
- <head>
- <meta charset="UTF-8" />
- <meta
+<head>
+ <meta charset="UTF-8"/>
+ <meta
name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"
- />
- <meta http-equiv="X-UA-Compatible" content="ie=edge" />
- <title>sakura | game</title>
- <link rel="stylesheet" type="text/css" href="/style.css" />
- <link rel="stylesheet" type="text/css" href="/game/style.css" />
- </head>
- <body>
- <header>
- <details>
- <summary>Game state</summary>
- <code id="game-json"></code>
- </details>
- </header>
- <main id="game"></main>
+ />
+ <meta http-equiv="X-UA-Compatible" content="ie=edge"/>
+ <title>sakura | game</title>
+ <link rel="stylesheet" type="text/css" href="/style.css"/>
+ <link rel="stylesheet" type="text/css" href="/game/style.css"/>
+</head>
+<body>
+<header>
+ <details>
+ <summary>Game state</summary>
+ <code id="game-json"></code>
+ </details>
+</header>
+<main id="game"></main>
- <template id="tmpl">
- <div class="distance">
- <input type="checkbox" class="sakura" />
- <input type="checkbox" class="sakura" />
- <input type="checkbox" class="sakura" />
- <input type="checkbox" class="sakura" />
- <input type="checkbox" class="sakura" />
- <input type="checkbox" class="sakura" />
- <input type="checkbox" class="sakura" />
- <input type="checkbox" class="sakura" />
- <input type="checkbox" class="sakura" />
- <input type="checkbox" class="sakura" />
- </div>
- <ul class="actions">
- <li class="action" data-index="">
- <button type="button" class="description" onclick="window.socket.send(closest('.action').getAttribute('data-index'))">Do</button>
- </li>
- </s>
- </template>
+<template id="tmpl">
+ <div id="distance">
+ <div class="content">
+ <input type="checkbox" class="sakura" style="animation-delay: 0.7s"/>
+ <input type="checkbox" class="sakura" style="animation-delay: 1.4s"/>
+ <input type="checkbox" class="sakura" style="animation-delay: 2.1s"/>
+ <input type="checkbox" class="sakura" style="animation-delay: 2.8s"/>
+ <input type="checkbox" class="sakura" style="animation-delay: 3.5s"/>
+ <input type="checkbox" class="sakura" style="animation-delay: 4.2s"/>
+ <input type="checkbox" class="sakura" style="animation-delay: 4.9s"/>
+ <input type="checkbox" class="sakura" style="animation-delay: 5.6s"/>
+ <input type="checkbox" class="sakura" style="animation-delay: 6.3s"/>
+ <input type="checkbox" class="sakura" style="animation-delay: 7s"/>
+ </div>
+ <label class="label pool-name">Distance</label>
+ <label class="label pool-value">10</label>
+ </div>
+ <ul class="actions">
+ <li class="action" data-index="">
+ <button type="button" class="description"
+ onclick="window.socket.send(closest('.action').getAttribute('data-index'))">Do
+ </button>
+ </li>
+ </ul>
+</template>
- <script src="/game/game.js"></script>
- </body>
+<script src="/game/game.js"></script>
+</body>
</html>
diff --git a/server/web/game/style.css b/server/web/game/style.css
index dd0e421..83f06ad 100644
--- a/server/web/game/style.css
+++ b/server/web/game/style.css
@@ -1,3 +1,59 @@
.hidden {
display: none;
}
+
+#distance {
+
+ & .label {
+ position: relative;
+
+ bottom: 0;
+ margin-bottom: 4px;
+
+ &.pool-name {
+ left: 0;
+ }
+
+ &.pool-value {
+ right: 0;
+ }
+ }
+
+ & .content {
+ display: flex;
+ justify-content: center;
+
+ & input[type=checkbox] {
+ pointer-events: none;
+ -webkit-appearance: none;
+ appearance: none;
+ background-color: transparent;
+ margin: 4px;
+ font-size: 2em;
+
+ @media (prefers-reduced-motion: no-preference) {
+ animation: 5s shake ease-in-out alternate infinite;
+ }
+
+ &::before {
+ color: lightseagreen;
+ content: ""
+ }
+
+ &:checked {
+ &::before {
+ content: "🌸"
+ }
+ }
+ }
+ }
+}
+
+@keyframes shake {
+ from {
+ transform: translateY(0) rotateZ(0deg)
+ }
+ to {
+ transform: translateY(12%) rotateZ(60deg)
+ }
+} \ No newline at end of file