Add tooltip error allegedly stolen codepen.io

This commit is contained in:
Laurent
2024-10-30 17:52:52 +01:00
parent 1c82b6f69a
commit 30337d9abc
2 changed files with 164 additions and 23 deletions

View File

@@ -1,30 +1,23 @@
import {scoreStore} from "../stores/scoreStore";
export class Game { export class Game {
public name : string; public playerName : string;
public result : number; public result : number;
public state : GameState; public state : GameState;
private readonly range : number; private readonly range : number;
constructor() { constructor() {
this.name = ""; this.playerName = "";
this.result = -1; this.result = -1;
this.state = GameState.Unplayed; this.state = GameState.Unplayed;
this.range = 100 this.range = 100
} }
public async play() { public play() {
this.result = this.getRandomNumber(); this.result = this.getRandomNumber();
await scoreStore.add(this.name, this.result)
} }
public hasBeenPlayed() : boolean { public playerExists() : boolean{
return this.state == GameState.Played; return false;
}
public isRunning() : boolean {
return this.state == GameState.Running;
} }
private getRandomNumber() : number{ private getRandomNumber() : number{

View File

@@ -1,18 +1,56 @@
<script> <script>
import bomb from '$lib/assets/bomb.svg'; import bomb from '$lib/assets/bomb.svg';
import {Game, GameState} from "$lib/models/game.ts"; import {Game, GameState} from "$lib/models/game.ts";
import {scoreStore} from "$lib/stores/scoreStore.ts";
let scores;
let game = new Game(); let game = new Game();
$: isRunning = game.state === GameState.Running; $: isRunning = game.state === GameState.Running;
$: hasBeenPlayed = game.state === GameState.Played; $: hasBeenPlayed = game.state === GameState.Played;
let timer;
const debounce = inputValue => {
clearTimeout(timer);
timer = setTimeout(() => {
try{
validate(inputValue)
clearError();
game.playerName = inputValue;
} catch (e){
displayError(e.message)
}
}, 150);
}
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("Ce joueur existe déjà");
})
}
async function roll(){ async function roll(){
game.state = GameState.Running;
await game.play() try{
await new Promise(r => setTimeout(r, 3000)); validate(game.playerName)
game.state = GameState.Played; game.state = GameState.Running;
game.play()
await scoreStore.add(game.playerName, game.result)
await new Promise(r => setTimeout(r, 3000));
game.state = GameState.Played;
} catch (e){
displayError(e.message)
}
}
function displayError(message){
window.$(".player").attr('tooltip', message)
}
function clearError(){
window.$('.player').removeAttr('tooltip');
} }
</script> </script>
@@ -27,15 +65,23 @@
<div class="info">Massacre en cours...</div> <div class="info">Massacre en cours...</div>
</div> </div>
{/if} {/if}
{#if !isRunning && !hasBeenPlayed} {#if !isRunning && !hasBeenPlayed}
<h1>Evaluez vos chances de survie</h1>
<div class="player">
<input class="name" placeholder="Nom de la victime..." bind:value={game.name}/>
<img class="roll" src={bomb} on:click={roll} alt="Bomb"/> <h1>Evaluez vos chances de survie</h1>
<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)}
/>
</div> </div>
<img class="roll" src={bomb} on:click={roll} alt="Bomb"/>
{/if} {/if}
{#if hasBeenPlayed} {#if hasBeenPlayed}
@@ -80,7 +126,7 @@
text-align: left; text-align: left;
margin: 1.5vh; margin: 0 1.5vh 1.5vh 1.5vh;
padding-left: 30px; padding-left: 30px;
padding-right: 30px; padding-right: 30px;
@@ -113,4 +159,106 @@
to{transform: rotate(360deg)} 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 */
font-size: .9em; /* opinion 3 */
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 */
font-family: Helvetica, sans-serif;
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);
}
}
@keyframes tooltips-horz {
to {
opacity: .9;
transform: translate(0, -50%);
}
}
/* 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> </style>