Maze Generator
Un labyrinthe se creuse sous vos yeux, case par case, par l'algorithme du retour sur trace ; terminé, il laisse place à un nouveau deux secondes plus tard.
Mis à jour le
Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. SVG comprend 30 effets, dont 3 gratuits. Découvrir la catégorie →
3 exemples d'usage



Comment ça marche
La zone est découpée en cases de 12 px, centrées, toutes fermées par quatre murs. L'algorithme part de la case en haut à gauche et garde une pile de son chemin : à chaque étape, il choisit au hasard une voisine jamais visitée, abat le mur qui les sépare et avance ; s'il n'en reste aucune, il dépile et recule. Quand la pile est vide, toutes les cases ont été visitées et il existe exactement un chemin entre deux cases quelconques : c'est un labyrinthe dit « parfait ».
Le rythme est de 300 étapes par seconde, compté en temps écoulé (plafonné à 50 ms par image), donc identique à 60 et à 120 Hz. Il faut environ deux étapes par case : une zone de 800 × 300 px (66 × 24 cases) se creuse en une dizaine de secondes. La case en cours est peinte en rose #d946ef, les cases déjà creusées en violet transparent, les murs en #6366f1. Une fois fini, le dessin reste affiché PAUSE millisecondes (2 000 par défaut), puis une nouvelle grille repart de zéro.
Les murs sont regroupés dans un seul tracé, et les cases creusées dans un seul remplissage, ce qui garde chaque image légère. La taille vient de la zone affichée, multipliée par devicePixelRatio, et les traits sont décalés d'un demi-pixel pour rester nets ; un ResizeObserver relance un labyrinthe adapté quand la zone change de taille, et rien ne démarre tant qu'elle mesure moins d'une case (onglet ou accordéon fermé). Un IntersectionObserver arrête la boucle hors écran. Chaque racine a son propre labyrinthe, lancé une seule fois (data-mzg-ready) même si le script est collé deux fois.
Accessibilité
- Libellé :
role="img"etaria-labelsur le canvas. En fond décoratif ou en indicateur accompagné d'un texte, passez-le enaria-hidden="true". - Mouvement réduit : sous
prefers-reduced-motion: reduce, le labyrinthe est creusé d'un coup et affiché terminé, sans case rose et sans renouvellement. - Pause : l'animation se renouvelle sans fin. Pour le critère WCAG 2.2.2, un bouton qui bascule l'attribut
hiddende la racine l'arrête ; elle reprend à la même étape. - Pas un jeu : le labyrinthe ne se parcourt pas, ni à la souris ni au clavier. Le présenter comme un jeu à résoudre serait trompeur.
- Clavier : aucun élément interactif, aucun focus à gérer.
Compatibilité navigateur
Canvas 2D et environ 5,6 Ko de JavaScript, sans dépendance. ResizeObserver : Chrome 64, Firefox 69, Safari 13.1 ; IntersectionObserver : Chrome 51, Firefox 55, Safari 12.1 (données MDN). Mesuré dans Chromium 151, Firefox 153 et WebKit 26.5 : aucune erreur même quand la zone est masquée au chargement, rendu à densité 2, deux labyrinthes indépendants, labyrinthe terminé en mouvement réduit, aucune image calculée hors écran.
Sans ResizeObserver, un nouveau labyrinthe n'est relancé qu'au redimensionnement de la fenêtre ; sans IntersectionObserver, il continue de se creuser hors écran. Sans JavaScript, la zone garde le fond de la racine.
Le code
Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :
<div class="fx-0617-root">
<canvas class="mzg-canvas" role="img" aria-label="Labyrinthe en train d'être creusé case par case"></canvas>
</div>
Paiement unique, sans abonnement — le code est à toi pour toujours
Personnaliser
Options passées à l'API ou attributs data-* :
| Option / propriété | Défaut | Effet |
|---|---|---|
Taille des cases (JS — CELL) |
12 px | 8 px donne un labyrinthe fin et long à creuser, 20 px de larges couloirs lisibles en vignette. |
Vitesse (JS — STEPS_PER_S) |
300 étapes par seconde | 60 pour suivre chaque mouvement de la case rose (pédagogie), 1 500 pour un remplissage quasi instantané. |
Pause entre deux labyrinthes (JS — PAUSE) |
2000 ms | Infinity garde le labyrinthe terminé à l'écran sans en relancer un autre. |
Murs (JS — WALL) |
#6366f1 | Toute couleur CSS ; le trait fait 1 px à toutes les densités d'écran. |
Cases creusées (JS — VISITED) |
rgba(99, 102, 241, 0.2) | transparent ne montre que les murs, une opacité de 0.4 fait mieux ressortir le chemin parcouru. |
Case en cours (JS — HEAD) |
#d946ef | Couleur du curseur qui creuse ; elle disparaît quand le labyrinthe est fini. |
Palette entière (CSS — filter sur la racine) |
aucun | hue-rotate(150deg) fait passer violet et rose à l'orange et au vert sans modifier le script. |
Fond et hauteur (CSS — background et --mzg-height) |
#0a0a0f, 300px | Le canvas est transparent ; la hauteur accepte toute valeur fixe ou 100% dans un parent de hauteur connue. |
FAQ
newMaze() (par exemple grid[0].walls[3] = false;), mais la solution n'est ni calculée ni affichée.PAUSE à Infinity. Le dernier labyrinthe reste à l'écran et la boucle continue simplement de le redessiner. Un changement de taille de la zone en relance tout de même un nouveau.