333 lines
No EOL
9.8 KiB
HTML
333 lines
No EOL
9.8 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="fr">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Tuto Riichi</title>
|
|
<link rel="stylesheet" href="/frontend/css/style.css">
|
|
<link rel="stylesheet" href="/frontend/css/speech-bubble.css">
|
|
<link rel="stylesheet" href="/frontend/css/hand.css">
|
|
<style>
|
|
#menu {
|
|
position: relative;
|
|
z-index: 10;
|
|
}
|
|
|
|
#mascotte {
|
|
position: fixed;
|
|
bottom: 0px;
|
|
right: 160px;
|
|
z-index: 999;
|
|
transform: scaleX(-1);
|
|
cursor: pointer;
|
|
}
|
|
|
|
#mascotte img {
|
|
width: 250px;
|
|
height: auto;
|
|
display: block;
|
|
}
|
|
|
|
.speech-bubble {
|
|
position: fixed;
|
|
bottom: 320px;
|
|
right: 170px;
|
|
z-index: 998;
|
|
display: none;
|
|
}
|
|
|
|
.speech-bubble.visible {
|
|
display: flex;
|
|
}
|
|
|
|
#tiles-display {
|
|
padding: 20px;
|
|
max-width: 900px;
|
|
margin: 20px auto;
|
|
display: grid;
|
|
grid-template-columns: 100px 1fr;
|
|
gap: 30px;
|
|
align-items: start;
|
|
}
|
|
|
|
.section-title {
|
|
grid-column: 1 / -1;
|
|
color: #ffffff;
|
|
font-size: 1.5rem;
|
|
margin: 20px 0 10px 0;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.hands-container {
|
|
grid-column: 1 / -1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 30px;
|
|
justify-content: flex-start;
|
|
}
|
|
|
|
.hands-container .hand-display {
|
|
grid-column: auto;
|
|
margin-bottom: 0;
|
|
width: 100%;
|
|
}
|
|
|
|
.tiles-family {
|
|
margin-bottom: 0;
|
|
grid-column: 1 / -1;
|
|
display: grid;
|
|
grid-template-columns: 100px 1fr;
|
|
gap: 30px;
|
|
align-items: start;
|
|
}
|
|
|
|
.tiles-family h3 {
|
|
color: #ffffff;
|
|
margin: 0;
|
|
font-size: 1.2rem;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.tiles-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(9, minmax(0, 1fr));
|
|
gap: 3px;
|
|
}
|
|
|
|
.tile-item {
|
|
padding: 0;
|
|
text-align: center;
|
|
border-radius: 4px;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
}
|
|
|
|
.tiles-numbers {
|
|
grid-column: 2;
|
|
display: grid;
|
|
grid-template-columns: repeat(9, minmax(0, 1fr));
|
|
gap: 3px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.tiles-numbers div {
|
|
text-align: center;
|
|
font-weight: bold;
|
|
color: #ffffff;
|
|
padding: 5px 0;
|
|
min-height: 50px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div id="menu"></div>
|
|
<div id="tile-container"></div>
|
|
<div id="tiles-display"></div>
|
|
<div class="speech-bubble">
|
|
<div class="speech-text" id="speech-text"></div>
|
|
</div>
|
|
<div id="mascotte"></div>
|
|
|
|
<script src="/frontend/js/fr/texts.js"></script>
|
|
<script src="/frontend/js/hand.js"></script>
|
|
<script>
|
|
// Charger le menu
|
|
fetch('/components/menu.html')
|
|
.then(r => r.text())
|
|
.then(html => document.getElementById('menu').innerHTML = html);
|
|
|
|
// Afficher la mascotte
|
|
const mascolteEl = document.getElementById('mascotte');
|
|
mascolteEl.innerHTML = '<img src="/img/tilineau/speaking.png" alt="Tilineau">';
|
|
|
|
// Afficher le texte de bienvenue
|
|
document.getElementById('speech-text').innerHTML = texts.riichi.chap2;
|
|
|
|
// Toggle bulle de dialogue au clic sur la mascotte
|
|
const speechBubble = document.querySelector('.speech-bubble');
|
|
mascolteEl.addEventListener('click', () => {
|
|
speechBubble.classList.toggle('visible');
|
|
if (speechBubble.classList.contains('visible')) {
|
|
mascolteEl.innerHTML = '<img class="explaining" src="/img/tilineau/speaking.png" alt="Tilineau">';
|
|
} else {
|
|
mascolteEl.innerHTML = '<img src="/img/tilineau/speaking.png" alt="Tilineau">';
|
|
}
|
|
});
|
|
|
|
// Créer le titre de section
|
|
const tilesDisplay = document.getElementById('tiles-display');
|
|
const title = document.createElement('div');
|
|
title.className = 'section-title';
|
|
title.textContent = 'Exemples de mains';
|
|
tilesDisplay.appendChild(title);
|
|
|
|
// Créer le conteneur des mains
|
|
const handsContainer = document.createElement('div');
|
|
handsContainer.className = 'hands-container';
|
|
tilesDisplay.appendChild(handsContainer);
|
|
|
|
// Créer et afficher trois mains aléatoires
|
|
for (let i = 0; i < 3; i++) {
|
|
const hand = new Hand({
|
|
label: `Main ${i + 1}`,
|
|
position: 'top-label',
|
|
tilt: 'none',
|
|
containerId: 'tiles-display'
|
|
});
|
|
|
|
// Modifier temporairement le containerId pour ajouter à handsContainer
|
|
hand.containerId = null;
|
|
|
|
fetch(hand.apiUrl)
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
const handDiv = document.createElement('div');
|
|
handDiv.className = `hand-display ${hand.position} tilt-${hand.tilt}`;
|
|
|
|
const label = document.createElement('div');
|
|
label.className = 'hand-label';
|
|
label.textContent = `Main ${i + 1}`;
|
|
handDiv.appendChild(label);
|
|
|
|
const container = document.createElement('div');
|
|
container.className = 'hand-container';
|
|
|
|
const handTiles = document.createElement('div');
|
|
handTiles.className = 'hand-tiles';
|
|
|
|
data.hand.forEach(tile => {
|
|
const tileDiv = document.createElement('div');
|
|
tileDiv.className = 'hand-tile-item';
|
|
tileDiv.innerHTML = tile.svg;
|
|
handTiles.appendChild(tileDiv);
|
|
});
|
|
|
|
container.appendChild(handTiles);
|
|
handDiv.appendChild(container);
|
|
handsContainer.appendChild(handDiv);
|
|
})
|
|
.catch(error => console.error('Erreur:', error));
|
|
}
|
|
|
|
// Créer le titre pour la main interactive
|
|
const interactiveTitle = document.createElement('div');
|
|
interactiveTitle.className = 'section-title';
|
|
interactiveTitle.textContent = 'Main interactive';
|
|
tilesDisplay.appendChild(interactiveTitle);
|
|
|
|
// Créer et afficher la main interactive avec une tuile piochée
|
|
fetch('/api/hand_with_draw')
|
|
.then(r => r.json())
|
|
.then(data => {
|
|
const handDiv = document.createElement('div');
|
|
handDiv.className = 'hand-display top-label tilt-none';
|
|
handDiv.id = 'interactive-hand';
|
|
|
|
const label = document.createElement('div');
|
|
label.className = 'hand-label';
|
|
label.textContent = 'Votre main';
|
|
handDiv.appendChild(label);
|
|
|
|
// Conteneur qui gère l'affichage avec flex (gère auto le draw si présent)
|
|
const container = document.createElement('div');
|
|
container.className = 'hand-container';
|
|
|
|
// Créer le grid des 13 tuiles
|
|
const handTiles = document.createElement('div');
|
|
handTiles.className = 'hand-tiles';
|
|
handTiles.id = 'interactive-tiles';
|
|
|
|
data.hand.forEach(tile => {
|
|
const tileDiv = document.createElement('div');
|
|
tileDiv.className = 'hand-tile-item';
|
|
tileDiv.innerHTML = tile.svg;
|
|
tileDiv.dataset.tileId = tile.id;
|
|
tileDiv.style.cursor = 'pointer';
|
|
tileDiv.addEventListener('click', () => discardTile(tile.id, tileDiv));
|
|
handTiles.appendChild(tileDiv);
|
|
});
|
|
|
|
container.appendChild(handTiles);
|
|
|
|
const drawTileDiv = document.createElement('div');
|
|
drawTileDiv.className = 'hand-tile-item draw-tile';
|
|
drawTileDiv.innerHTML = data.draw.svg;
|
|
drawTileDiv.dataset.tileId = data.draw.id;
|
|
drawTileDiv.style.cursor = 'pointer';
|
|
drawTileDiv.addEventListener('click', () => discardTile(data.draw.id, drawTileDiv));
|
|
container.appendChild(drawTileDiv);
|
|
|
|
handDiv.appendChild(container);
|
|
tilesDisplay.appendChild(handDiv);
|
|
})
|
|
.catch(error => console.error('Erreur:', error));
|
|
|
|
// Fonction pour défausser une tuile
|
|
async function discardTile(tileId, tileElement) {
|
|
try {
|
|
const response = await fetch('/api/discard', {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ tile_id: tileId })
|
|
});
|
|
|
|
if (!response.ok) {
|
|
console.error('Erreur lors de la défausse');
|
|
return;
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
// Ajouter une animation de suppression
|
|
tileElement.style.opacity = '0';
|
|
tileElement.style.transition = 'opacity 0.3s ease';
|
|
|
|
setTimeout(() => {
|
|
// Mettre à jour la main interactive avec la nouvelle main
|
|
updateInteractiveHand(data.hand, data.draw);
|
|
}, 300);
|
|
} catch (error) {
|
|
console.error('Erreur:', error);
|
|
}
|
|
}
|
|
|
|
// Fonction pour mettre à jour la main interactive
|
|
function updateInteractiveHand(handData, drawData) {
|
|
const handTiles = document.getElementById('interactive-tiles');
|
|
handTiles.innerHTML = '';
|
|
|
|
handData.forEach(tile => {
|
|
const tileDiv = document.createElement('div');
|
|
tileDiv.className = 'hand-tile-item';
|
|
tileDiv.innerHTML = tile.svg;
|
|
tileDiv.dataset.tileId = tile.id;
|
|
tileDiv.style.cursor = 'pointer';
|
|
tileDiv.addEventListener('click', () => discardTile(tile.id, tileDiv));
|
|
handTiles.appendChild(tileDiv);
|
|
});
|
|
|
|
// Mettre à jour le draw
|
|
const container = handTiles.parentElement;
|
|
const oldDrawTile = container.querySelector('.draw-tile');
|
|
if (oldDrawTile) {
|
|
oldDrawTile.remove();
|
|
}
|
|
|
|
if (drawData) {
|
|
const drawTileDiv = document.createElement('div');
|
|
drawTileDiv.className = 'hand-tile-item draw-tile';
|
|
drawTileDiv.innerHTML = drawData.svg;
|
|
drawTileDiv.dataset.tileId = drawData.id;
|
|
drawTileDiv.style.cursor = 'pointer';
|
|
drawTileDiv.addEventListener('click', () => discardTile(drawData.id, drawTileDiv));
|
|
container.appendChild(drawTileDiv);
|
|
}
|
|
}
|
|
</script>
|
|
</body>
|
|
</html> |