minimal menu
This commit is contained in:
parent
1aee19e63b
commit
014c12efa8
6 changed files with 153 additions and 22 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -1,3 +1,4 @@
|
|||
node_modules/
|
||||
package-lock.json
|
||||
build/
|
||||
__pycache__
|
||||
|
|
@ -2,23 +2,42 @@ from flask import Flask, jsonify, request
|
|||
from flask_cors import CORS
|
||||
|
||||
from game.tile import *
|
||||
from game.error import *
|
||||
|
||||
app = Flask(__name__)
|
||||
CORS(app)
|
||||
|
||||
tiles = tiles = Tile.generateAll()
|
||||
tiles = Tile.generateAll()
|
||||
|
||||
# ============= GET ================
|
||||
@app.route('api/tiles', methods=['GET'])
|
||||
@app.route('/api/tiles', methods=['GET'])
|
||||
def get_all_tiles():
|
||||
"""Récupère toutes les tuiles"""
|
||||
return jsonify(tiles)
|
||||
tiles_data = [
|
||||
{
|
||||
'id': tile.id,
|
||||
'family': str(tile.family),
|
||||
'value': str(tile.value),
|
||||
'svg': tile.get_img()
|
||||
}
|
||||
for tile in tiles
|
||||
]
|
||||
return jsonify({'tiles': tiles_data})
|
||||
|
||||
@app.route('api/tiles/<int:tile_id>', method=['GET'])
|
||||
@app.route('/api/tiles/<int:tile_id>', methods=['GET'])
|
||||
def get_tile(tile_id):
|
||||
if tile_id < 0 or tile_id >= len(tiles):
|
||||
return jsonify({'error': 'Tuile non trouvée'}), 404
|
||||
|
||||
return jsonify({'tile': tiles[tile_id]})
|
||||
tile = tiles[tile_id]
|
||||
return jsonify({
|
||||
'id': tile.id,
|
||||
'family': str(tile.family),
|
||||
'value': str(tile.value),
|
||||
'svg': tile.get_img()
|
||||
})
|
||||
|
||||
# ============== POST ================
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(debug=True, port=5000)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from error import *
|
||||
from value import *
|
||||
from game.error import *
|
||||
from game.value import *
|
||||
|
||||
class Tile:
|
||||
def __init__(self, family, value, id):
|
||||
|
|
@ -52,15 +52,26 @@ class Tile:
|
|||
|
||||
def get_img(self):
|
||||
if self.img == None:
|
||||
self.img = f"""
|
||||
<g class="tile tile-{self.id}" data-tile-id="{self.id}">
|
||||
<image href="svg/{self.img_shadow}" x="2" y="2" width="60" height="80" class="shadow"/>
|
||||
<image href="svg/{self.img_front}" x="0" y="0" width="60" height="80" class="front"/>
|
||||
<image href="svg/{self.img_symbol}" x="12" y="20" width="36" height="40" class="symbol"/>
|
||||
</g>
|
||||
"""
|
||||
shadow = self._load_svg(self.img_shadow, x=4, y=4)
|
||||
front = self._load_svg(self.img_front, x=0, y=0)
|
||||
symbol = self._load_svg(self.img_symbol, x=12, y=20, scale=0.9)
|
||||
|
||||
self.img = f"""<g class="tile tile-{self.id}" data-tile-id="{self.id}">
|
||||
{shadow}
|
||||
{front}
|
||||
{symbol}
|
||||
</g>"""
|
||||
return self.img
|
||||
|
||||
@staticmethod
|
||||
def _load_svg(filename, x=0, y=0, scale=1):
|
||||
try:
|
||||
with open(f'img/Regular/{filename}', 'r', encoding='utf-8') as f:
|
||||
svg_content = f.read()
|
||||
return f'<g transform="translate({x}, {y}) scale({scale})">{svg_content}</g>'
|
||||
except FileNotFoundError:
|
||||
raise InvalidValueError(f"SVG non trouvé: {filename}")
|
||||
|
||||
def __eq__(self, other: Tile):
|
||||
return self.value == other.value and self.family == other.family
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ class Family(Enum):
|
|||
DRAGON = 4
|
||||
|
||||
class Wind(Enum):
|
||||
EAST : 0
|
||||
SOUTH : 1
|
||||
WEST : 2
|
||||
NORTH : 3
|
||||
EAST = 0
|
||||
SOUTH = 1
|
||||
WEST = 2
|
||||
NORTH = 3
|
||||
|
||||
class Dragon(Enum):
|
||||
RED : 0
|
||||
GREEN : 1
|
||||
WHITE : 2
|
||||
RED = 0
|
||||
GREEN = 1
|
||||
WHITE = 2
|
||||
82
components/menu.html
Normal file
82
components/menu.html
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
<nav class="menu">
|
||||
<ul>
|
||||
<li><a href="/">Accueil</a></li>
|
||||
<li class="dropdown">
|
||||
<a href="#">Riichi</a>
|
||||
<ul class="submenu">
|
||||
<li><a href="">Chapitre 1 : Les tuiles</a></li>
|
||||
<li><a href="">Chapitre 2 : La main</a></li>
|
||||
<li><a href="">Chapitre 3 : Les groupes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<style>
|
||||
.menu {
|
||||
background-color: #333;
|
||||
padding: 1rem 0;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.menu ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
gap: 2rem;
|
||||
justify-content: center;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.menu a {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 1.1rem;
|
||||
transition: color 0.3s;
|
||||
display: block;
|
||||
padding: 0.5rem 1rem;
|
||||
}
|
||||
|
||||
.menu a:hover {
|
||||
color: #ffd700;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.submenu {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
background-color: #222;
|
||||
padding: 0;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
|
||||
list-style: none;
|
||||
min-width: 150px;
|
||||
z-index: 1000;
|
||||
flex-direction: column;
|
||||
gap: 0;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
.dropdown:hover .submenu {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.submenu li {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.submenu a {
|
||||
padding: 0.7rem 1.2rem;
|
||||
}
|
||||
|
||||
.submenu a:hover {
|
||||
background-color: #333;
|
||||
}
|
||||
</style>
|
||||
18
index.html
18
index.html
|
|
@ -0,0 +1,18 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Tuto Riichi</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="menu"></div>
|
||||
|
||||
<script>
|
||||
// Charger le menu
|
||||
fetch('components/menu.html')
|
||||
.then(r => r.text())
|
||||
.then(html => document.getElementById('menu').innerHTML = html);
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue