SVG✨ Premium

Recursive Circles

Un cercle SVG qui contient trois cercles, qui en contiennent chacun trois, sur quatre niveaux ; une respiration descend du plus grand aux plus petits.

CSSJSRecursive

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

Exposition « Infinis emboîtés » d'un centre de sciences — la figure à droite du titre — Recursive Circles exemple 1

① Exposition « Infinis emboîtés » d'un centre de sciences — la figure à droite du titre

QuandLa page de l'exposition s'ouvre : la figure à cinq niveaux occupe la moitié droite, déborde un peu du bord, et sa respiration descend sans fin vers les plus petits cercles.
PourquoiUne exposition sur les fractales a besoin d'une image qui en soit une : chaque cercle contient la même figure en plus petit, et la vague qui la parcourt montre l'emboîtement.
Réglagesdata-depth="5" data-branches="3", racine de 326 px avec --rcc-height: 326px, --rcc-bg: transparent, --rcc-stroke: 1.6px, décalée de 34 px hors du bord droit.
Parrainage d'une épicerie coopérative — la figure grandit avec le curseur « niveaux » — Recursive Circles exemple 2

② Parrainage d'une épicerie coopérative — la figure grandit avec le curseur « niveaux »

QuandLe visiteur fait glisser le curseur de 0 à 4 : la figure passe d'un cercle à 4, 13, 40 puis 121, et le total de membres s'affiche à côté.
PourquoiLa règle « chacun en fait entrer trois » devient visible : chaque nouveau niveau ajoute trois cercles dans chaque cercle du niveau précédent.
RéglagesLe curseur change data-depth sur la racine ; data-colors="#14532d,#15803d,#65a30d,#ca8a04,#c2410c", --rcc-bg: #f7f5ec, --rcc-stroke: 1.8px. Tant qu'on n'y touche pas, la scène fait monter les niveaux toute seule.
Éditeur de motifs textiles — petite figure dans la notification « Préparation du PDF » — Recursive Circles exemple 3

③ Éditeur de motifs textiles — petite figure dans la notification « Préparation du PDF »

QuandOn clique sur « Exporter en PDF » : une notification sombre apparaît en bas de l'écran, avec une figure de 46 px qui respire tant que le fichier se prépare.
PourquoiDans un outil de création de motifs, un indicateur qui est lui-même un motif répété paraît naturel ; avec deux niveaux seulement, il reste net à cette taille.
Réglagesdata-depth="2", data-colors="#f3efe9,#e0a46a,#d0705a", racine de 46 px (--rcc-height: 46px), --rcc-speed: 1.6s, --rcc-step: .18s, --rcc-stroke: 1.2px. L'affichage de la notification est géré par la scène.

Comment ça marche

La figure est construite par une fonction récursive, grow(). Elle trace un cercle, puis place à l'intérieur data-branches cercles enfants (3 par défaut) tangents entre eux et au bord du parent. Leur rayon vient d'une formule exacte : r × sin(π/n) / (1 + sin(π/n)), soit 46 % du parent pour trois enfants, 50 % pour deux. La fonction s'appelle ensuite sur chaque enfant, en tournant d'un demi-pas à chaque niveau, jusqu'à data-depth (4 par défaut). Total : 1 + 3 + 9 + 27 + 81 = 121 cercles.

Le dessin se fait dans un repère fixe, viewBox="-112 -112 224 224", centré sur 0 : la figure est toujours au milieu de la zone et s'adapte à sa plus petite dimension, sans calcul de position. Chaque niveau a sa couleur (indigo, violet, magenta, cyan, vert, puis on recommence) et son épaisseur de trait, un peu plus fine à chaque génération (calculée en CSS à partir du niveau) et toujours mesurée en pixels d'écran grâce à vector-effect: non-scaling-stroke.

L'animation rccBreath fait passer chaque cercle de 95 % à 100 % de sa taille et de 45 % à 100 % d'opacité en 3 secondes. Le niveau sert de retard : 0,25 s de plus par génération, donc la vague part du grand cercle et descend vers les plus petits. Les délais sont négatifs (- 100 × durée) : rien ne saute au chargement. Un MutationObserver surveille data-depth, data-branches et data-colors : changer l'un de ces attributs redessine la figure, sans autre appel.

Accessibilité

  • Figure décorative : le SVG porte aria-hidden="true". Si la figure illustre une donnée (comme le nombre de membres d'un réseau), écrivez cette donnée en texte à côté.
  • Mouvement réduit : sous prefers-reduced-motion: reduce, l'animation est retirée ; tous les cercles restent à pleine taille et pleine opacité, la figure complète reste lisible.
  • Rien à activer : aucun élément focusable, la figure ne réagit ni à la souris ni au toucher. Les changements de profondeur passent par l'attribut, que votre propre contrôle (curseur, boutons) peut piloter.
  • Grande profondeur : au-delà de 5 niveaux avec 3 branches, les derniers cercles font moins d'un pixel dans une zone de 300 px. Ils n'apportent rien à la lecture et alourdissent la page.

Compatibilité navigateur

SVG, transform-box: fill-box (Chrome 64, Firefox 55, Safari 11) et max() pour l'épaisseur du trait (Chrome 79, Firefox 75, Safari 11.1), versions relevées dans les données MDN. Mesuré dans Chromium 151, Firefox 153 et WebKit 26.5 : 121 cercles par copie, centre de la figure au centre exact de la zone, deux copies indépendantes.

Chrome 79+✓ Complet (mesuré)
Firefox 75+✓ Complet (mesuré)
Safari 11.1+✓ Complet (mesuré sur WebKit)
Edge 79+✓ Complet (moteur de Chrome)
Safari iOS 11.3+✓ Non vérifié sur appareil
Chrome Android 79+✓ Complet (mesuré à 390 px, tactile)

Sans JavaScript, le SVG reste vide. Dans un navigateur sans max(), le trait garde l'épaisseur par défaut du SVG (1 px) et la figure reste juste.

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :

index.html — structure
<div class="fx-0611-root" data-depth="4" data-branches="3">
  <svg class="rcc-svg" viewBox="-112 -112 224 224" aria-hidden="true"></svg>
</div>

Paiement unique, sans abonnement — le code est à toi pour toujours

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
data-depth (racine) 4 Nombre de générations sous le premier cercle (0 à 6). Modifiable à tout moment : la figure se redessine.
data-branches (racine) 3 Enfants par cercle (2 à 8). 2 donne des paires qui alternent horizontal et vertical, 4 une rosace en croix, 6 une couronne.
data-colors (racine) #6366f1, #8b5cf6, #d946ef, #06b6d4, #22c55e Couleurs des niveaux, séparées par des virgules ; la liste recommence si la profondeur la dépasse.
--rcc-stroke 1.5px Épaisseur du trait du premier cercle ; chaque niveau en perd 15 %, sans descendre sous 0,6 px.
--rcc-speed 3s Durée d'une respiration complète.
--rcc-step 0.25s Retard d'un niveau sur le précédent. 0 fait respirer toute la figure ensemble.
--rcc-height / --rcc-bg 300px / #0a0a0f Hauteur et fond de la zone. La figure prend la plus petite des deux dimensions, centrée.

FAQ

Oui : la même fonction se rappelle sur chaque enfant jusqu'à la profondeur demandée. Mettez data-depth="1" puis "2" pour voir chaque génération reproduire la précédente à l'intérieur de chaque cercle.
Oui, en changeant l'attribut : root.setAttribute('data-depth', 3). L'effet observe cet attribut et redessine aussitôt. La même chose vaut pour data-branches et data-colors.
Leur trait perd 15 % de l'épaisseur de départ à chaque niveau (jamais moins de 0,6 px) : un trait plus fin paraît plus pâle. La respiration, décalée d'un niveau à l'autre, les fait aussi descendre à 45 % d'opacité à des moments différents. En mouvement réduit, tous les niveaux sont à pleine opacité.