Files
vitrine-pixels/8x32 PI/mes_animations.py
T
bachandClaude Opus 5.5 2d4b0d5a5f 8x32 PI : interface web, matrice verticale, compatibilité Raspbian 11
- Interface web (serveur_web.py, Flask, gabarits dans web/) : dépôt de GIF,
  PNG animés et séquences de PNG, aperçus animés, ordre de lecture,
  activer / désactiver, corbeille, « jouer maintenant » et « suivante ».
  Service systemd vitrine-web, activé par installer.sh.
- Lecteur : réagit aux demandes de la page web (post-it dans
  /run/vitrine-pixels), écrit l'animation en cours, éteint la matrice
  proprement sur SIGTERM.
- Matrice posée debout : réglage ROTATION (90 = image 8 × 32) dans
  matrice.py ; images couchées tournées automatiquement ; exemples,
  animations codées, aperçus et page web adaptés au format vertical.
- Compatibilité Raspbian 11 Bullseye : partition /boot, Pillow 8.1, Flask 1.1.
- Doc : nouveau guide INTERFACE_WEB.md ; README, GUIDE_KRITA, MODE_VITRINE,
  CODER_EN_PYTHON mis à jour (format 8 × 32, adresses Wi-Fi / câble du Pi).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 16:08:18 +02:00

189 lines
6.6 KiB
Python

"""
=============================================================================
MES ANIMATIONS — dessiner avec du code (en Python)
Workshop « Vitrine pixels »
=============================================================================
Krita, c'est pour DESSINER les animations image par image.
Ce fichier, c'est pour les CALCULER : hasard, mouvements continus,
arc-en-ciel… des choses très longues à dessiner à la main.
Ce sont les mêmes animations que dans matrice_8x32.ino (Arduino),
traduites en Python : comparez les deux fichiers, ligne à ligne !
Lancer :
python3 mes_animations.py --simulateur (sur l'ordinateur)
sudo ~/vitrine-env/bin/python mes_animations.py (sur le Pi)
Transformer la playlist en GIF, pour que le lecteur la joue avec les
dessins de l'équipe Krita (la playlist est alors jouée une seule fois) :
python3 mes_animations.py --enregistrer animations/10_code.gif
PYTHON EN 6 RÈGLES (pour qui connaît l'Arduino)
-----------------------------------------------
1. Pas de point-virgule en fin de ligne, pas d'accolades { }.
2. Ce sont les ESPACES en début de ligne (l'indentation) qui disent ce
qui est « dans » une boucle ou une fonction. 4 espaces par niveau.
3. Pas de type à déclarer : x = 3 au lieu de int x = 3;
4. Une fonction : def nom(): au lieu de void nom() {
5. Une boucle : for x in range(32): (x va de 0 à 31)
au lieu de for (int x = 0; x < 32; x++) {
6. Un commentaire commence par # au lieu de //
LES OUTILS DE DESSIN (définis dans matrice.py)
----------------------------------------------
pixel(x, y, couleur) colore un pixel (x de 0 à 31, y de 0 à 7)
lire_pixel(x, y) renvoie la couleur d'un pixel
effacer() éteint tout (dans la toile)
effacer(couleur) remplit tout d'une couleur
assombrir(25) assombrit tout de 25 % (traînées)
montrer() AFFICHE la toile (sinon rien n'apparaît !)
attendre(100) attend 100 millisecondes
Couleurs : ROUGE, ORANGE, JAUNE, VERT, CYAN, BLEU, VIOLET, MAGENTA, ROSE,
BLANC, NOIR, ou (rouge, vert, bleu) de 0 à 255,
ou teinte(t) avec t de 0 à 255 pour faire le tour de l'arc-en-ciel.
"""
import random # pour le hasard
import sys # pour lire les options de la ligne de commande
# « from matrice import * » = importer TOUS les outils du moteur, pour
# écrire pixel(...) au lieu de matrice.pixel(...).
from matrice import *
# =============================================================================
# LES ANIMATIONS
# =============================================================================
# À VOUS DE JOUER : copiez une animation, renommez-la, modifiez-la,
# et ajoutez son nom dans la PLAYLIST tout en bas.
# --- Animation 1 : arc-en-ciel qui défile ---
def anim_arc_en_ciel():
for temps in range(256):
for x in range(LARGEUR):
for y in range(HAUTEUR):
# La teinte dépend de la position et du temps qui passe.
pixel(x, y, teinte((x + y) * 8 + temps * 2))
montrer()
attendre(20)
# --- Animation 2 : la pluie ---
def anim_pluie():
for image in range(200):
assombrir(25) # les gouttes laissent une traînée qui s'estompe
# Faire descendre toute l'image d'une ligne, en partant du bas
# (range(7, 0, -1) compte à rebours : 7, 6, 5… 1).
for y in range(HAUTEUR - 1, 0, -1):
for x in range(LARGEUR):
pixel(x, y, lire_pixel(x, y - 1))
# La ligne du haut s'éteint, puis 3 nouvelles gouttes au hasard.
for x in range(LARGEUR):
pixel(x, 0, NOIR)
for n in range(3):
pixel(random.randrange(LARGEUR), 0, (0, 120, 255))
montrer()
attendre(60)
# --- Animation 3 : un dessin en pixel art qui défile ---
# Une lettre par pixel, « . » = éteint. Toutes les lignes de même longueur,
# pas plus de 8 pixels de large ni de haut (le petit côté de la matrice).
DESSIN = [
".RR..RR.",
"RBBRRRRR",
"RBRRRRRR",
"RRRRRRRR",
".RRRRRR.",
"..RRRR..",
"...RR...",
]
# Un « dictionnaire » associe chaque lettre à une couleur.
COULEUR_DE_LETTRE = {
"R": ROUGE, "O": ORANGE, "J": JAUNE, "V": VERT, "C": CYAN,
"B": BLANC, "L": BLEU, "M": MAGENTA, "P": ROSE,
}
def dessiner_dessin(depart_x, depart_y):
for y, ligne in enumerate(DESSIN): # enumerate donne le numéro ET la ligne
for x, lettre in enumerate(ligne):
if lettre in COULEUR_DE_LETTRE:
pixel(depart_x + x, depart_y + y, COULEUR_DE_LETTRE[lettre])
def anim_dessin_qui_defile():
largeur_dessin = len(DESSIN[0]) # len = longueur de la ligne
hauteur_dessin = len(DESSIN) # = nombre de lignes
if HAUTEUR > LARGEUR:
# Matrice DEBOUT : le dessin monte du bas vers le haut.
x = (LARGEUR - largeur_dessin) // 2 # centré
for y in range(HAUTEUR, -hauteur_dessin - 1, -1):
effacer()
dessiner_dessin(x, y)
montrer()
attendre(70)
else:
# Matrice COUCHÉE : le dessin passe de droite à gauche.
y = (HAUTEUR - hauteur_dessin) // 2
for x in range(LARGEUR, -largeur_dessin - 1, -1):
effacer()
dessiner_dessin(x, y)
montrer()
attendre(70)
# --- Animation 4 : étincelles ---
def anim_etincelles():
for image in range(300):
assombrir(8)
pixel(random.randrange(LARGEUR), random.randrange(HAUTEUR),
teinte(random.randrange(256), saturation=200))
montrer()
attendre(15)
# --- Exemple : votre première animation ---
def anim_ma_premiere():
for x in range(LARGEUR):
effacer()
pixel(x, HAUTEUR // 2 - 1, JAUNE) # deux points au milieu de la hauteur
pixel(x, HAUTEUR // 2, JAUNE)
montrer()
attendre(50)
# =============================================================================
# LA PLAYLIST
# =============================================================================
# Mettez # devant une ligne pour sauter une animation.
def playlist():
anim_arc_en_ciel()
anim_pluie()
anim_dessin_qui_defile()
anim_etincelles()
# anim_ma_premiere()
if __name__ == "__main__":
demarrer()
try:
while True: # en boucle, comme loop() sur l'Arduino
playlist()
if "--enregistrer" in sys.argv:
break # en enregistrement, un seul tour suffit
except KeyboardInterrupt:
print("\nArrêt demandé.")
finally:
eteindre()