add winner display
authorGeoffrey Allott <geoffrey@allott.email>
Sun, 14 Mar 2021 22:15:57 +0000 (22:15 +0000)
committerGeoffrey Allott <geoffrey@allott.email>
Sun, 14 Mar 2021 22:15:57 +0000 (22:15 +0000)
site/modules/card.js
site/modules/poker.js
site/modules/random.js [new file with mode: 0644]
site/modules/whist.js
site/modules/winner.js [new file with mode: 0644]
site/modules/words.js
site/style.css
site/style/poker.css
site/style/winner.css [new file with mode: 0644]

index cceadbf5b8e7608f371d52c9751bb073806d2bc9..6fef6b26d1a1dfa9c6dbcff4a4d4eb90586dc590 100644 (file)
@@ -33,3 +33,58 @@ export function card_href(card) {
 export function suit_href(suit) {
     return "img/suit-" + short_suit(suit) + ".svg";
 }
+
+export const FIFTY_TWO_CARD_DECK = [
+    {suit: "Clubs", rank: "Two"},
+    {suit: "Clubs", rank: "Three"},
+    {suit: "Clubs", rank: "Four"},
+    {suit: "Clubs", rank: "Five"},
+    {suit: "Clubs", rank: "Six"},
+    {suit: "Clubs", rank: "Seven"},
+    {suit: "Clubs", rank: "Eight"},
+    {suit: "Clubs", rank: "Nine"},
+    {suit: "Clubs", rank: "Ten"},
+    {suit: "Clubs", rank: "Jack"},
+    {suit: "Clubs", rank: "Queen"},
+    {suit: "Clubs", rank: "King"},
+    {suit: "Clubs", rank: "Ace"},
+    {suit: "Diamonds", rank: "Two"},
+    {suit: "Diamonds", rank: "Three"},
+    {suit: "Diamonds", rank: "Four"},
+    {suit: "Diamonds", rank: "Five"},
+    {suit: "Diamonds", rank: "Six"},
+    {suit: "Diamonds", rank: "Seven"},
+    {suit: "Diamonds", rank: "Eight"},
+    {suit: "Diamonds", rank: "Nine"},
+    {suit: "Diamonds", rank: "Ten"},
+    {suit: "Diamonds", rank: "Jack"},
+    {suit: "Diamonds", rank: "Queen"},
+    {suit: "Diamonds", rank: "King"},
+    {suit: "Diamonds", rank: "Ace"},
+    {suit: "Hearts", rank: "Two"},
+    {suit: "Hearts", rank: "Three"},
+    {suit: "Hearts", rank: "Four"},
+    {suit: "Hearts", rank: "Five"},
+    {suit: "Hearts", rank: "Six"},
+    {suit: "Hearts", rank: "Seven"},
+    {suit: "Hearts", rank: "Eight"},
+    {suit: "Hearts", rank: "Nine"},
+    {suit: "Hearts", rank: "Ten"},
+    {suit: "Hearts", rank: "Jack"},
+    {suit: "Hearts", rank: "Queen"},
+    {suit: "Hearts", rank: "King"},
+    {suit: "Hearts", rank: "Ace"},
+    {suit: "Spades", rank: "Two"},
+    {suit: "Spades", rank: "Three"},
+    {suit: "Spades", rank: "Four"},
+    {suit: "Spades", rank: "Five"},
+    {suit: "Spades", rank: "Six"},
+    {suit: "Spades", rank: "Seven"},
+    {suit: "Spades", rank: "Eight"},
+    {suit: "Spades", rank: "Nine"},
+    {suit: "Spades", rank: "Ten"},
+    {suit: "Spades", rank: "Jack"},
+    {suit: "Spades", rank: "Queen"},
+    {suit: "Spades", rank: "King"},
+    {suit: "Spades", rank: "Ace"},
+];
index 7696e26c78786af4ca3a63915321f501ba8ccb5a..b1c6d52fc7b871b7c016445050800445b3330918 100644 (file)
@@ -1,6 +1,7 @@
 const svgns = "http://www.w3.org/2000/svg";
 
 import { card_href, suit_href } from "./card.js";
+import { CongratulateWinner } from "./winner.js";
 
 export class TexasHoldEm {
     constructor(container, summary, actions, username, send) {
@@ -68,7 +69,7 @@ export class TexasHoldEm {
         const fold_control_label = document.createElementNS(svgns, "text");
         const fold_control_text = document.createTextNode("Fold");
         fold_control_label.append(fold_control_text);
-        fold_control_label.setAttribute("x", "325");
+        fold_control_label.setAttribute("x", "342.5");
         fold_control_label.setAttribute("y", "470");
         fold_control_label.classList.add("fold-control-label");
         this.svg.append(fold_control_label);
@@ -86,7 +87,7 @@ export class TexasHoldEm {
         const call_control_label = document.createElementNS(svgns, "text");
         this.call_control_text = document.createTextNode("Call");
         call_control_label.append(this.call_control_text);
-        call_control_label.setAttribute("x", "385");
+        call_control_label.setAttribute("x", "402.5");
         call_control_label.setAttribute("y", "470");
         call_control_label.classList.add("call-control-label");
         this.svg.append(call_control_label);
@@ -109,7 +110,7 @@ export class TexasHoldEm {
         const bet_control_label = document.createElementNS(svgns, "text");
         const bet_control_text = document.createTextNode("Bet");
         bet_control_label.append(bet_control_text);
-        bet_control_label.setAttribute("x", "445");
+        bet_control_label.setAttribute("x", "462.5");
         bet_control_label.setAttribute("y", "470");
         bet_control_label.classList.add("bet-control-label");
         this.svg.append(bet_control_label);
@@ -389,7 +390,7 @@ export class TexasHoldEm {
                 this.redraw_players();
                 break;
             case "WinGame":
-                console.log(this);
+                new CongratulateWinner(this.svg, user_action.username);
                 break;
             default:
                 console.error("Unhandled action for knock-out whist", user_action);
diff --git a/site/modules/random.js b/site/modules/random.js
new file mode 100644 (file)
index 0000000..9e9b4ac
--- /dev/null
@@ -0,0 +1,3 @@
+export function random_int(max) {
+    return Math.floor(Math.random() * max);
+}
index ab7eab8de2fa0b8bd9231680380daa7695c01ad0..424b56a309c6426fd4ca8fab6c79c72fe1df775d 100644 (file)
@@ -1,6 +1,7 @@
 const svgns = "http://www.w3.org/2000/svg";
 
 import { card_href, suit_href } from "./card.js";
+import { CongratulateWinner } from "./winner.js";
 
 export class KnockOutWhist {
     constructor(container, summary, actions, username, send) {
@@ -296,9 +297,9 @@ export class KnockOutWhist {
                 this.redraw_players();
                 break;
             case "WinGame":
-                console.log(this);
                 this.trumps = null;
                 this.redraw_trumps();
+                new CongratulateWinner(this.svg, user_action.username);
                 break;
             default:
                 console.error("Unhandled action for knock-out whist", user_action);
diff --git a/site/modules/winner.js b/site/modules/winner.js
new file mode 100644 (file)
index 0000000..80f4013
--- /dev/null
@@ -0,0 +1,74 @@
+const svgns = "http://www.w3.org/2000/svg";
+
+import { card_href, FIFTY_TWO_CARD_DECK } from "./card.js";
+import { random_int } from "./random.js";
+
+export class CongratulateWinner {
+    constructor(svg, username) {
+        this.svg = svg;
+        this.username = username;
+        this.card_images = [];
+        this.deck = [...FIFTY_TWO_CARD_DECK];
+
+        this.timestep = 10;
+        this.new_card_interval = 100;
+        this.card_drop_speed = 1;
+        this.show_winner_time = 1000;
+
+        this.frame = this.random_drop;
+        this.schedule_frame(0);
+    }
+
+    schedule_frame(time) {
+        this.frame(time);
+        setTimeout(() => this.schedule_frame(time + this.timestep), this.timestep);
+    }
+
+    show_winner() {
+        this.winner_banner = document.createElementNS(svgns, "text");
+        this.winner_banner.classList.add("winner-banner");
+        this.winner_banner.setAttribute("x", "250");
+        this.winner_banner.setAttribute("y", "210");
+        const winner_banner_text = document.createTextNode("Winner");
+        this.winner_banner.append(winner_banner_text);
+        this.svg.append(this.winner_banner);
+
+        this.winner_name = document.createElementNS(svgns, "text");
+        this.winner_name.classList.add("winner-name");
+        this.winner_name.setAttribute("x", "250");
+        this.winner_name.setAttribute("y", "270");
+        const winner_name_text = document.createTextNode(this.username);
+        this.winner_name.append(winner_name_text);
+        this.svg.append(this.winner_name);
+    }
+
+    card_image(card) {
+        const image = document.createElementNS(svgns, "image");
+        image.setAttribute("width", "45");
+        image.setAttribute("height", "70");
+        image.setAttribute("x", random_int(500 - 45));
+        image.setAttribute("y", "-70");
+        image.setAttribute("href", card_href(card));
+        this.svg.append(image);
+        return image;
+    }
+
+    random_drop(time) {
+        if (time >= this.show_winner_time && this.winner_banner === undefined) {
+            this.show_winner();
+        }
+        for (let i = 0; i < this.card_images.length; i++) {
+            const card_time = time - this.new_card_interval * i;
+            const image = this.card_images[i];
+            image.setAttribute("y", -70 + card_time * this.card_drop_speed);
+        }
+        const total_cards = Math.min(52, Math.floor(time / this.new_card_interval) + 1);
+        const new_cards = total_cards - this.card_images.length;
+        for (let i = 0; i < new_cards; i++) {
+            const index = random_int(this.deck.length);
+            const [card] = this.deck.splice(index, 1);
+            const image = this.card_image(card);
+            this.card_images.push(image);
+        }
+    }
+}
index 080e01bef367b02cffac84dc56aaaf7cbad671d7..95d03fa99ade1f7972094173c2f1ed280c66460c 100644 (file)
@@ -1,3 +1,5 @@
+import { random_int } from "./random.js";
+
 const adjectives = [
     "Amazing",
     "Based",
@@ -56,10 +58,6 @@ const nouns = [
     "Zeitgeist",
 ];
 
-function random_int(max) {
-    return Math.floor(Math.random() * max);
-}
-
 export function random_title() {
     return adjectives[random_int(26)] + " " + nouns[random_int(26)];
 }
index e3f71c0a179fbf8d81d3a37ffb22445cd23cdc8f..80656cfabe421720deeaaf2c738faa61cf7a2487 100644 (file)
@@ -4,6 +4,7 @@
 @import url("style/chatroom.css");
 @import url("style/poker.css");
 @import url("style/whist.css");
+@import url("style/winner.css");
 
 html, body {
     width: 100%;
index 00ce239a4941b88108838db1bea3ac67645c4869..045f36dd685d4c35b2354b19a254f15df3af3f6d 100644 (file)
@@ -24,4 +24,5 @@
 
 .fold-control-label, .call-control-label, .bet-control-label {
     pointer-events: none;
+    text-anchor: middle;
 }
diff --git a/site/style/winner.css b/site/style/winner.css
new file mode 100644 (file)
index 0000000..92b5d0c
--- /dev/null
@@ -0,0 +1,16 @@
+@keyframes grow {
+    from { fill: rgba(0, 0, 0, 0); }
+    to { fill: rgba(0, 0, 0, 1); }
+}
+
+.winner-banner {
+    font-size: 4vw;
+    animation: grow 1s;
+    text-anchor: middle;
+}
+
+.winner-name {
+    font-size: 8vw;
+    animation: grow 1s;
+    text-anchor: middle;
+}