Merge pull request #1 from naaturel/alternative-style

Alternative style
This commit is contained in:
naturel
2024-11-06 10:41:14 +01:00
committed by GitHub
26 changed files with 601 additions and 139 deletions

View File

@@ -2,6 +2,8 @@ package be.naaturel.unluckiest.entities;
import jakarta.persistence.*;
import java.math.BigDecimal;
@Entity(name = "Score")
public class ScoreEntity {
@@ -13,6 +15,6 @@ public class ScoreEntity {
public String owner;
@Column
public int value;
public float value;
}

View File

@@ -3,9 +3,9 @@ package be.naaturel.unluckiest.models;
public class Score {
private String owner;
private int value;
private float value;
public Score(String owner, int value){
public Score(String owner, float value){
this.owner = owner;
this.value = value;
}
@@ -14,7 +14,7 @@ public class Score {
return this.owner;
}
public int getValue(){
public float getValue(){
return this.value;
}

View File

@@ -1,2 +1,2 @@
VITE_CLIENT_API_URL=http://127.0.0.1:5000/api
VITE_SERVER_API_URL=http://127.0.0.1:5000/api
VITE_CLIENT_API_URL=http://127.0.0.1:5000
VITE_SERVER_API_URL=http://127.0.0.1:5000

2
front/.gitignore vendored
View File

@@ -132,3 +132,5 @@ dist
/.svelte-kit/
/.svelte-kit/
/.svelte-kit/
/.idea/
/.idea/

View File

@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -42,7 +42,7 @@ declare module '$env/static/private' {
export const DB_USER: string;
export const DriverData: string;
export const EDITOR: string;
export const EFC_10388: string;
export const EFC_9404: string;
export const ffmpeg: string;
export const FPS_BROWSER_APP_PROFILE_STRING: string;
export const FPS_BROWSER_USER_PROFILE_STRING: string;
@@ -150,7 +150,7 @@ declare module '$env/dynamic/private' {
DB_USER: string;
DriverData: string;
EDITOR: string;
EFC_10388: string;
EFC_9404: string;
ffmpeg: string;
FPS_BROWSER_APP_PROFILE_STRING: string;
FPS_BROWSER_USER_PROFILE_STRING: string;

View File

@@ -18,10 +18,10 @@ export const options = {
root,
service_worker: false,
templates: {
app: ({ head, body, assets, nonce, env }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<title>Unluckiest</title>\n\n\t\t<link rel=\"stylesheet\"\n\t\t\t href=\"https://fonts.googleapis.com/css?family=Afacad+Flux\">\n\t\t<style>\n\t\t\tbody {\n\t\t\t\tfont-family: 'Afacad Flux', serif;\n\t\t\t\tfont-size: 48px;\n\t\t\t}\n\t\t</style>\n\n\t\t<meta charset=\"utf-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n\n\t\t<link rel=\"stylesheet\" href=\"" + assets + "/style/app.css\" />\n\t\t<link rel=\"stylesheet\" href=\"" + assets + "/style/menu.css\" />\n\n\t\t<link rel=\"icon\" href=\"" + assets + "/favicon.png\" />\n\n\t\t" + head + "\n\t</head>\n\t<body data-sveltekit-preload-data=\"hover\">\n\t\t<div style=\"display: contents\">" + body + "</div>\n\t</body>\n</html>\n",
app: ({ head, body, assets, nonce, env }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<title>Unluckiest</title>\n\n\t\t<link rel=\"stylesheet\"\n\t\t\t href=\"https://fonts.googleapis.com/css?family=Afacad+Flux\">\n\t\t<style>\n\t\t\tbody {\n\t\t\t\tfont-family: 'Afacad Flux', serif;\n\t\t\t\tfont-size: 48px;\n\t\t\t}\n\t\t</style>\n\n\t\t<meta charset=\"utf-8\" />\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\" />\n\n\t\t<link rel=\"stylesheet\" href=\"" + assets + "/style/app.css\" />\n\t\t<link rel=\"stylesheet\" href=\"" + assets + "/style/menu2.css\" />\n\n\t\t<link rel=\"icon\" href=\"" + assets + "/favicon.png\" />\n\n\t\t<script src=\"https://code.jquery.com/jquery-3.6.0.min.js\"></script>\n\t\t<script src=\"https://code.jquery.com/ui/1.12.1/jquery-ui.min.js\"></script>\n\n\t\t" + head + "\n\t</head>\n\n\t<body data-sveltekit-preload-data=\"hover\">\n\n\t\t<div style=\"display: contents\">" + body + "</div>\n\n\t</body>\n</html>\n",
error: ({ status, message }) => "<!doctype html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<title>" + message + "</title>\n\n\t\t<style>\n\t\t\tbody {\n\t\t\t\t--bg: white;\n\t\t\t\t--fg: #222;\n\t\t\t\t--divider: #ccc;\n\t\t\t\tbackground: var(--bg);\n\t\t\t\tcolor: var(--fg);\n\t\t\t\tfont-family:\n\t\t\t\t\tsystem-ui,\n\t\t\t\t\t-apple-system,\n\t\t\t\t\tBlinkMacSystemFont,\n\t\t\t\t\t'Segoe UI',\n\t\t\t\t\tRoboto,\n\t\t\t\t\tOxygen,\n\t\t\t\t\tUbuntu,\n\t\t\t\t\tCantarell,\n\t\t\t\t\t'Open Sans',\n\t\t\t\t\t'Helvetica Neue',\n\t\t\t\t\tsans-serif;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tjustify-content: center;\n\t\t\t\theight: 100vh;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t.error {\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t\tmax-width: 32rem;\n\t\t\t\tmargin: 0 1rem;\n\t\t\t}\n\n\t\t\t.status {\n\t\t\t\tfont-weight: 200;\n\t\t\t\tfont-size: 3rem;\n\t\t\t\tline-height: 1;\n\t\t\t\tposition: relative;\n\t\t\t\ttop: -0.05rem;\n\t\t\t}\n\n\t\t\t.message {\n\t\t\t\tborder-left: 1px solid var(--divider);\n\t\t\t\tpadding: 0 0 0 1rem;\n\t\t\t\tmargin: 0 0 0 1rem;\n\t\t\t\tmin-height: 2.5rem;\n\t\t\t\tdisplay: flex;\n\t\t\t\talign-items: center;\n\t\t\t}\n\n\t\t\t.message h1 {\n\t\t\t\tfont-weight: 400;\n\t\t\t\tfont-size: 1em;\n\t\t\t\tmargin: 0;\n\t\t\t}\n\n\t\t\t@media (prefers-color-scheme: dark) {\n\t\t\t\tbody {\n\t\t\t\t\t--bg: #222;\n\t\t\t\t\t--fg: #ddd;\n\t\t\t\t\t--divider: #666;\n\t\t\t\t}\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"error\">\n\t\t\t<span class=\"status\">" + status + "</span>\n\t\t\t<div class=\"message\">\n\t\t\t\t<h1>" + message + "</h1>\n\t\t\t</div>\n\t\t</div>\n\t</body>\n</html>\n"
},
version_hash: "3iwm3b"
version_hash: "feblej"
};
export async function get_hooks() {

1
front/src/app.d.ts vendored
View File

@@ -1,5 +1,6 @@
// See https://kit.svelte.dev/docs/types#app
// for information about these interfaces
declare global {
namespace App {
// interface Error {}

View File

@@ -13,16 +13,22 @@
</style>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<link rel="stylesheet" href="%sveltekit.assets%/style/app.css" />
<link rel="stylesheet" href="%sveltekit.assets%/style/menu.css" />
<link rel="stylesheet" href="%sveltekit.assets%/style/menu2.css" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M48 80a48 48 0 1 1 96 0A48 48 0 1 1 48 80zM0 224c0-17.7 14.3-32 32-32l64 0c17.7 0 32 14.3 32 32l0 224 32 0c17.7 0 32 14.3 32 32s-14.3 32-32 32L32 512c-17.7 0-32-14.3-32-32s14.3-32 32-32l32 0 0-192-32 0c-17.7 0-32-14.3-32-32z"/></svg>

After

Width:  |  Height:  |  Size: 455 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M438.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-160-160c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L338.8 224 32 224c-17.7 0-32 14.3-32 32s14.3 32 32 32l306.7 0L233.4 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l160-160z"/></svg>

After

Width:  |  Height:  |  Size: 452 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M48.7 125.8l53.2 31.9c7.8 4.7 17.8 2 22.2-5.9L201.6 12.1c3-5.4-.9-12.1-7.1-12.1c-1.6 0-3.2 .5-4.6 1.4L47.9 98.8c-9.6 6.6-9.2 20.9 .8 26.9zM16 171.7l0 123.5c0 8 10.4 11 14.7 4.4l60-92c5-7.6 2.6-17.8-5.2-22.5L40.2 158C29.6 151.6 16 159.3 16 171.7zM310.4 12.1l77.6 139.6c4.4 7.9 14.5 10.6 22.2 5.9l53.2-31.9c10-6 10.4-20.3 .8-26.9L322.1 1.4c-1.4-.9-3-1.4-4.6-1.4c-6.2 0-10.1 6.7-7.1 12.1zM496 171.7c0-12.4-13.6-20.1-24.2-13.7l-45.3 27.2c-7.8 4.7-10.1 14.9-5.2 22.5l60 92c4.3 6.7 14.7 3.6 14.7-4.4l0-123.5zm-49.3 246L286.1 436.6c-8.1 .9-14.1 7.8-14.1 15.9l0 52.8c0 3.7 3 6.8 6.8 6.8c.8 0 1.6-.1 2.4-.4l172.7-64c6.1-2.2 10.1-8 10.1-14.5c0-9.3-8.1-16.5-17.3-15.4zM233.2 512c3.7 0 6.8-3 6.8-6.8l0-52.6c0-8.1-6.1-14.9-14.1-15.9l-160.6-19c-9.2-1.1-17.3 6.1-17.3 15.4c0 6.5 4 12.3 10.1 14.5l172.7 64c.8 .3 1.6 .4 2.4 .4zM41.7 382.9l170.9 20.2c7.8 .9 13.4-7.5 9.5-14.3l-85.7-150c-5.9-10.4-20.7-10.8-27.3-.8L30.2 358.2c-6.5 9.9-.3 23.3 11.5 24.7zm439.6-24.8L402.9 238.1c-6.5-10-21.4-9.6-27.3 .8L290.2 388.5c-3.9 6.8 1.6 15.2 9.5 14.3l170.1-20c11.8-1.4 18-14.7 11.5-24.6zm-216.9 11l78.4-137.2c6.1-10.7-1.6-23.9-13.9-23.9l-145.7 0c-12.3 0-20 13.3-13.9 23.9l78.4 137.2c3.7 6.4 13 6.4 16.7 0zM174.4 176l163.2 0c12.2 0 19.9-13.1 14-23.8l-80-144c-2.8-5.1-8.2-8.2-14-8.2l-3.2 0c-5.8 0-11.2 3.2-14 8.2l-80 144c-5.9 10.7 1.8 23.8 14 23.8z"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M40 48C26.7 48 16 58.7 16 72l0 48c0 13.3 10.7 24 24 24l48 0c13.3 0 24-10.7 24-24l0-48c0-13.3-10.7-24-24-24L40 48zM192 64c-17.7 0-32 14.3-32 32s14.3 32 32 32l288 0c17.7 0 32-14.3 32-32s-14.3-32-32-32L192 64zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32l288 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-288 0zm0 160c-17.7 0-32 14.3-32 32s14.3 32 32 32l288 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-288 0zM16 232l0 48c0 13.3 10.7 24 24 24l48 0c13.3 0 24-10.7 24-24l0-48c0-13.3-10.7-24-24-24l-48 0c-13.3 0-24 10.7-24 24zM40 368c-13.3 0-24 10.7-24 24l0 48c0 13.3 10.7 24 24 24l48 0c13.3 0 24-10.7 24-24l0-48c0-13.3-10.7-24-24-24l-48 0z"/></svg>

After

Width:  |  Height:  |  Size: 849 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M9.4 278.6c-12.5-12.5-12.5-32.8 0-45.3l128-128c9.2-9.2 22.9-11.9 34.9-6.9s19.8 16.6 19.8 29.6l0 256c0 12.9-7.8 24.6-19.8 29.6s-25.7 2.2-34.9-6.9l-128-128z"/></svg>

After

Width:  |  Height:  |  Size: 385 B

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><!--!Font Awesome Free 6.6.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.--><path d="M246.6 278.6c12.5-12.5 12.5-32.8 0-45.3l-128-128c-9.2-9.2-22.9-11.9-34.9-6.9s-19.8 16.6-19.8 29.6l0 256c0 12.9 7.8 24.6 19.8 29.6s25.7 2.2 34.9-6.9l128-128z"/></svg>

After

Width:  |  Height:  |  Size: 387 B

View File

@@ -12,9 +12,13 @@
{/if}
{#each scores as score, i}
{#if i <= 100}
<li class="item">
<div class="name"><img src="" alt=""/> {score.owner} </div><div class="score"> {score.value} pts.</div>
<div class="position">{i+1}</div>
<div class="name"> {score.owner} </div>
<div class="score"> {score.value}%</div>
</li>
{/if}
{/each}
</ul>
@@ -26,7 +30,7 @@
display: flex;
flex-direction: column;
width: 60vw;
width: 75vw;
height: 65vh;
padding: 0 2vw 2vw 2vw;
@@ -38,40 +42,57 @@
display: none;
}
li
.item
{
display: flex;
justify-content: space-around;
padding: 1.25vh;
margin: 1.5vh;
border: 2px solid #A1674A;
background-color: #fcdcab;
border: 3px solid #4b0611;
border-radius: 10px;
background-color: #f1ecec;
box-shadow: 0 0 10px #343232;
box-shadow: 5px 5px #4b0611;
outline: none;
}
li:hover
.item:hover
{
background-color: #dd3328;
transform: scale(1.075);
background-color: #F5F5F5;
}
.position, .name, .score
{
flex-basis: 0;
}
.name, .score
{
color: black;
margin-left: 3vh;
padding-left: 7px;
border-left: 1px solid #A1674A;
}
.position
{
flex-grow: 5;
margin-right: 10px;
text-align: center;
}
.name
{
word-break: break-word;
flex-grow: 100;
border-right: 1px solid #A1674A;
}
.score
{
flex-grow: 20;
flex-grow: 10;
text-align: center;
}
@media screen and (min-width: 601px) {
.leaderboard { width: 55vw; }
}
</style>

View File

@@ -0,0 +1,10 @@
<h1 class="page-title">
<slot></slot>
</h1>
<style>
.page-title
{
width: 75vw;
}
</style>

View File

@@ -0,0 +1,47 @@
<script>
import logo from '$lib/assets/logo.svg'
</script>
<div class="splash" >
<img class="footer-logo" src={logo} alt="Splashscreen">
</div>
<style>
.splash
{
display: flex;
justify-content: center;
align-items: center;
position: absolute;
z-index: 2;
width: 100vw;
height: 100vh;
background-color: #4b0611;
animation: fadeout 2.5s forwards;
}
.footer-logo
{
width: auto;
height: 25%;
}
@keyframes fadeout {
0%, 45% { opacity: 1; }
100% {
opacity: 0;
display: none;
}
}
@keyframes slide {
0% { translate: 0; }
100% {
translate: 100%;
display: none;
}
}
</style>

View File

@@ -0,0 +1,41 @@
export class Game {
public playerName : string;
public result : number;
public state : GameState;
private readonly range : number;
constructor() {
this.playerName = "";
this.result = -1;
this.state = GameState.Unplayed;
this.range = 100
}
public play() {
this.result = this.getRandomNumber();
}
public playerExists() : boolean{
return false;
}
private getRandomNumber() : number{
let unit = Math.floor(Math.random() * (this.range + 1));
if(unit === 100){
let modifier = Math.floor(Math.random() * (this.range + 1));
return unit*modifier;
}
let dec = Math.floor(Math.random() * (this.range));
return unit + (dec/100);
}
}
export enum GameState {
Unplayed,
Running,
Played,
}

View File

@@ -5,7 +5,7 @@ import {getLeaderboard, submitScore} from "./requests";
let scores : Score[] = []
function sort(scores : Score[]){
if(scores.length >= 2) scores.sort((s1 : Score, s2 : Score) => s1.value - s2.value)
if(scores.length >= 2) scores.sort((s1 : Score, s2 : Score) => s2.value - s1.value)
return scores;
}

View File

@@ -1,33 +1,59 @@
<script>
import github_mark from '$lib/assets/github-mark-white.svg';
import twitter_mark from '$lib/assets/twitter-mark-white.svg';
import leaderboard from '$lib/assets/leaderboard.svg';
import dice from '$lib/assets/dice.svg';
import about from '$lib/assets/about.svg';
import logo from '$lib/assets/logo.svg'
import arrow from '$lib/assets/arrow.svg'
import {onMount} from "svelte";
import SplashScreen from "$lib/components/SplashScreen.svelte";
import PageTitle from "$lib/components/PageTitle.svelte";
onMount(async () => {
const jQuery = await import('jquery');
const $ = jQuery.default;
window.$ = $;
window.jQuery = $;
window.$(".menu-collapsed").click(function () {
window.$(this).toggleClass("menu-expanded");
window.$(".expander").click(function () {
window.$(".menu").toggleClass("menu-collapsed menu-expanded");
});
});
</script>
<div class="menu-collapsed">
<div class="burger"></div>
<nav>
<SplashScreen/>
<div class="menu menu-collapsed">
<a href="/">Leaderboard</a>
<a href="/play">Play</a>
<a href="/about">About</a>
<a class="expander">
<img class="item-hint" src={arrow}
height="30"
width="30"
alt="arrow">
</a>
<a href="/" class="menu-item">
<img class="item-hint" src={leaderboard}
height="30"
width="30"
alt="leaderboard">
<div class="item-title">Revue nécrologique</div>
</a>
<a href="/play" class="menu-item">
<img class="item-hint" src={dice}
height="30"
width="30"
alt="dice">
<div class="item-title">Tenter sa chance</div>
</a>
<a href="/about" class="menu-item">
<img class="item-hint" src={about}
height="30"
width="30"
alt="about"
>
<div class="item-title">A propos</div>
</a>
</nav>
</div>
<div class="container">
@@ -35,7 +61,10 @@
</div>
<footer>
<a href="https://github.com/naaturel">
<img class="footer-logo" src="{logo}" alt="Logo">
<!--<a href="https://github.com/naaturel">
<img
src={github_mark}
height="30"
@@ -49,5 +78,5 @@
height="30"
width="30"
alt="Twitter mark"/>
</a>
</a>-->
</footer>

View File

@@ -2,6 +2,7 @@
import LeaderBoard from "$lib/components/LeaderBoard.svelte";
import {scoreStore} from "$lib/stores/scoreStore.ts";
import {onMount} from "svelte";
import PageTitle from "$lib/components/PageTitle.svelte";
let { data } = $props()
@@ -12,5 +13,5 @@
</script>
<PageTitle>Qui va y passer ?</PageTitle>
<LeaderBoard bind:scores={$scoreStore}></LeaderBoard>

View File

@@ -1 +1,49 @@
<p>It was revealed to me in a dream</p>
<script>
import PageTitle from "$lib/components/PageTitle.svelte";
</script>
<PageTitle>A propos</PageTitle>
<div class="container">
<div class="section">
<h2>Design</h2>
<p>Arwen Hirsoux</p>
</div>
<hr/>
<div class="section">
<h2>Développement</h2>
<p>Laurent Crema</p>
</div>
</div>
<style>
hr
{
width: 75%;
}
.container
{
border-radius: 7px;
background: rgb(252, 220, 171, 0.85);
width: 85%;
height: fit-content;
padding: 25px;
}
.section
{
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
</style>

View File

@@ -1,61 +1,98 @@
<script>
import {onMount} from "svelte";
import bomb from '$lib/assets/bomb.svg';
import {Game, GameState} from "$lib/models/game.ts";
import {scoreStore} from "$lib/stores/scoreStore.ts";
import PageTitle from "$lib/components/PageTitle.svelte";
let scores;
let game = new Game();
let playerName = undefined;
let range = 100;
let result = 0;
$: isRunning = game.state === GameState.Running;
$: hasBeenPlayed = game.state === GameState.Played;
onMount(async () => {
const jQuery = await import('jquery');
const $ = jQuery.default;
let timer;
window.$ = $;
window.jQuery = $;
});
const debounce = inputValue => {
clearTimeout(timer);
timer = setTimeout(() => {
try{
validate(inputValue)
game.playerName = inputValue;
} catch (e){
displayError(e.message)
}
}, 150);
}
async function roll(){
toggleLoading();
result = Math.floor(Math.random() * (range + 1));
try{
validate(game.playerName)
game.state = GameState.Running;
game.play()
await scoreStore.add(game.playerName, game.result)
await new Promise(r => setTimeout(r, 3000));
toggleLoading();
window.$(".result").text(`Result : ${result}/${range}`)
await scoreStore.add(playerName, result)
game.state = GameState.Played;
} catch (e){
displayError(e.message)
}
}
function toggleLoading(){
window.$(".loader").toggleClass("disabled");
window.$(".player").toggleClass("disabled");
function validate(data){
if(!data) throw new Error("Veuillez indiquer votre nom.");
$scoreStore.forEach(v => {
if(v.owner && v.owner.toLowerCase() === data.toLowerCase()) throw new Error("Cette personne a déjà été évaluée.");
})
}
function displayError(message){
window.$(".player").attr('tooltip', message)
setTimeout(() => {
clearError();
}, 3000)
}
function clearError(){
window.$('.player').removeAttr('tooltip');
}
</script>
<PageTitle>Évaluez vos chances de survie</PageTitle>
<div class="container">
<div class="loader disabled">
{#if isRunning}
<div class="loader">
<svg class="circular-loader" viewBox="0 0 30 30">
<circle class="loader-path" cx="15" cy="15" r="5" fill="none" stroke="#f1ecec" stroke-width="0.7" />
<circle class="loader-path" cx="15" cy="15" r="5" fill="none" stroke="#4b0611" stroke-width="0.7" />
</svg>
<div class="info">Rolling a random numbers within range 0-{range}...</div>
<div class="info">Massacre en cours...</div>
</div>
{/if}
{#if !isRunning && !hasBeenPlayed}
<div class="player"
tooltip=""
flow="up">
<input class="name" placeholder="Nom de la victime..."
bind:value={game.playerName}
on:input={({ target: { value } }) => debounce(value)}
on:blur={({ target: { value } }) => debounce(value)}
/>
<img class="roll" src={bomb} on:click={roll} alt="Bomb"/>
</div>
<div class="player">
<input class="name" placeholder="Your name" bind:value={playerName}/>
<button on:click={roll}>Let's roll !</button>
<div class="result"></div>
</div>
{/if}
{#if hasBeenPlayed}
<div class="result">Vous avez {game.result}% de chance de mourir</div>
{/if}
</div>
<style>
.container, .player
.container
{
display: flex;
flex-direction: column;
@@ -64,9 +101,13 @@
text-align: center;
}
.disabled
.player
{
display: none;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.player
@@ -74,13 +115,45 @@
gap: 2vh;
}
.name, .roll
{
min-width: 210px;
width: 22vmax;
}
.name
{
width: 17vw;
color: #424242;
background-color: #fcdcab;
height: 6vh;
border: 2px solid #A1674A;
min-height: 50px;
border: 3px solid #4b0611;
border-radius: 10px;
box-shadow: 0 0 10px #343232;
box-shadow: 5px 5px #4b0611;
text-align: left;
margin: 0 1.5vh 1.5vh 1.5vh;
padding-left: 30px;
padding-right: 30px;
outline: none;
}
.result
{
font-size: 24px;
}
.result
{
border-radius: 7px;
background: rgb(252, 220, 171, 0.6);
width: 85%;
height: fit-content;
padding: 25px;
}
.circular-loader
@@ -96,19 +169,7 @@
height: 25vh;
}
button
{
background-color: #f1ecec;
color: black;
width: 18vw;
height: 15vh;
border-radius: 10px;
border: 2px solid #A1674A;
box-shadow: 0 0 10px #343232;
}
.name:hover, button:hover{
.name:hover, .roll:hover{
transform: scale(1.1);
}
@@ -116,4 +177,98 @@
to{transform: rotate(360deg)}
}
/*=============TOOLTIP=============*/
/* START TOOLTIP STYLES */
[tooltip] {
position: relative; /* opinion 1 */
}
/* Applies to all tooltips */
[tooltip]::before,
[tooltip]::after {
text-transform: none; /* opinion 2 */
line-height: 1;
user-select: none;
pointer-events: none;
position: absolute;
display: none;
opacity: 0;
}
[tooltip]::before {
content: '';
border: 5px solid transparent; /* opinion 4 */
z-index: 1001; /* absurdity 1 */
}
[tooltip]::after {
content: attr(tooltip); /* magic! */
/* most of the rest of this is opinion */
text-align: center;
/*
Let the content set the size of the tooltips
but this will also keep them from being obnoxious
*/
min-width: 3em;
max-width: 21em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 1ch 1.5ch;
border-radius: .3ch;
box-shadow: 0 1em 2em -.5em rgba(0, 0, 0, 0.35);
background: #333;
color: #fff;
z-index: 1000; /* absurdity 2 */
}
/* Make the tooltips respond to hover */
[tooltip]::before,
[tooltip]::after {
display: block;
}
/* don't show empty tooltips */
[tooltip='']::before,
[tooltip='']::after {
display: none !important;
}
/* FLOW: UP */
[tooltip]:not([flow])::before,
[tooltip][flow^="up"]::before {
bottom: 100%;
border-bottom-width: 0;
border-top-color: #333;
}
[tooltip]:not([flow])::after,
[tooltip][flow^="up"]::after {
bottom: calc(100% + 5px);
}
[tooltip]:not([flow])::before,
[tooltip]:not([flow])::after,
[tooltip][flow^="up"]::before,
[tooltip][flow^="up"]::after {
left: 50%;
transform: translate(-50%, -.5em);
}
/* KEYFRAMES */
@keyframes tooltips-vert {
to {
opacity: .9;
transform: translate(-50%, 0);
}
}
/* FX All The Things */
[tooltip]:not([flow])::before,
[tooltip]:not([flow])::after,
[tooltip][flow^="up"]::before,
[tooltip][flow^="up"]::after {
animation: tooltips-vert 300ms ease-out forwards;
}
</style>

View File

@@ -1,11 +1,34 @@
:root
@media screen and (min-width: 601px) {
:root {
--font-size : 18px;
}
}
@media screen and (max-width: 600px) {
:root {
--font-size : 15px;
}
}
/* For debugging purposes
* {
outline: 1px solid #2600ff;
}
*/
*
{
--font-size : 1.25vmax;
color: #4b0611;
}
*,
*::before,
*::after {
box-sizing: border-box;
}
*
{
color: #F5F5F5;
text-decoration: none;
font-size: var(--font-size, 1vw);
transition: 0.3s;
@@ -13,7 +36,17 @@
h1
{
font-size: calc(var(--font-size, 1vw) * 2.5);
font-size: calc(var(--font-size, 1vw) * 2.15);
text-align: center;
}
html, body
{
height: 100%;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
html
@@ -35,8 +68,6 @@ body
align-items: center;
justify-content: center;
height: 98vh;
}
.container
@@ -58,7 +89,7 @@ hr {
}
nav
/*nav
{
display: flex;
flex-direction: column;
@@ -81,7 +112,7 @@ nav a
.nav_delimiter
{
margin-bottom: 5vh;
}
}*/
form
{
@@ -92,19 +123,7 @@ form
margin-bottom: 10vh;
}
input
{
color: #424242;
font-size: 2.5vh;
width: 20vw;
height: 4.5vh;
padding: 1vh;
margin: 1.5vh;
text-align: center;
}
.bordered
{
@@ -118,13 +137,18 @@ footer
align-items: center;
position: absolute;
bottom: 0.25vh;
margin-bottom: 0.25vh;
bottom: 0;
width: 100vw;
height: 5vh;
height: 10vh;
}
footer a {
margin-right: 2vh;
}
.footer-logo {
height: 100%;
margin-right: 10px;
margin-bottom: 10px;
}

View File

@@ -0,0 +1,78 @@
.menu-collapsed, .menu-expanded {
position: fixed;
top: 0;
left: 0;
margin: 0;
padding: 0;
height: 100vh;
z-index: 9999;
list-style-type: none;
background: rgb(252, 220, 171, 0.85);
overflow: hidden;
transition: width .3s;
}
.menu-collapsed .menu-item{
display: none;
}
.menu-expanded, .menu-collapsed {
display: flex;
flex-direction: column;
align-items: start;
}
.menu-expanded {
width: 300px;
}
.expander, .menu-item {
display: flex;
flex-direction: row;
align-items: center;
margin: 15px 30px 0 5px;
border-radius: 5px;
height: fit-content;
width: 250px;
}
.expander, .menu-item {
text-decoration: none;
margin: 15px 5px 5px 5px;
padding: 5px;
}
.item-title {
margin-left: 5%;
color: #4b0611;
}
.menu-item:hover {
background: #dd3328;
}
.menu-item .item-hint:hover {
transition: 0.3s;
transform: rotate(360deg);
}
.menu-expanded .expander .item-hint {
transform: rotate(180deg);
}
@media screen and (max-width: 600px) {
.menu-collapsed {
width: 45px
}
.item-hint {
width: 20px;
height: 20px;
}
}
@media screen and (min-width: 601px) {
.menu-collapsed {
width: 60px;
}
}