﻿{"id":597,"date":"2026-02-14T21:39:52","date_gmt":"2026-02-14T20:39:52","guid":{"rendered":"https:\/\/lmspro.fr\/apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique\/"},"modified":"2026-02-15T13:34:18","modified_gmt":"2026-02-15T12:34:18","slug":"apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique","status":"publish","type":"post","link":"https:\/\/lmspro.fr\/en\/apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique\/","title":{"rendered":"Learn how to generate abstract and geometric wallpapers"},"content":{"rendered":"<article class=\"lms-video-card\"><div class=\"lms-content\"><div class=\"lms-meta\"><span class=\"lms-pill lms-pill--provider\">YouTube<\/span><span class=\"lms-pill lms-pill--muted\">VJ Loop Neon<\/span><span class=\"lms-pill lms-pill--muted\">Abstract background video<\/span><span class=\"lms-pill lms-pill--muted\">Abstract Background Video loop<\/span><span class=\"lms-pill lms-pill--muted\">Abstract Background<\/span><\/div><div class=\"lms-media\"><iframe class=\"lms-iframe\" src=\"https:\/\/www.youtube-nocookie.com\/embed\/4WQTqOR55vk?rel=0\" allowfullscreen><\/iframe><\/div><\/div><\/article>\n<h2>Apprendre \u00e0 g\u00e9n\u00e9rer des fonds d&rsquo;\u00e9cran abstrait et g\u00e9om\u00e9trique<\/h2>\n<p class=\"wpa-text\">Plongez dans l&rsquo;univers fascinant du design g\u00e9n\u00e9ratif pour cr\u00e9er des fonds d&rsquo;\u00e9cran anim\u00e9s aux formes abstraites et g\u00e9om\u00e9triques. D\u00e9couvrez comment ma\u00eetriser les effets n\u00e9on sur fond sombre pour obtenir des animations infinies captivantes gr\u00e2ce \u00e0 5 tutoriels progressifs adapt\u00e9s aux d\u00e9butants.<\/p>\n<div class=\"article-meta\">\n<p><strong>Module :<\/strong> Module 6 : Module Bonus<\/p>\n<p><strong>Niveau :<\/strong> D\u00e9butant<\/p>\n<p><strong>Dur\u00e9e :<\/strong> 20 minutes<\/p>\n<p><strong>Pr\u00e9requis :<\/strong> Aucun<\/p>\n<\/div>\n<h2>Objectifs p\u00e9dagogiques<\/h2>\n<ul>\n<li>Comprendre les principes de base des animations CSS et JavaScript pour cr\u00e9er des effets visuels<\/li>\n<li>Ma\u00eetriser les techniques de g\u00e9n\u00e9ration de formes g\u00e9om\u00e9triques avec p5.js<\/li>\n<li>Appliquer les effets n\u00e9on et glow sur fond sombre pour un rendu moderne<\/li>\n<li>Cr\u00e9er des boucles d&rsquo;animation infinies fluides et optimis\u00e9es<\/li>\n<li>D\u00e9velopper des compositions abstraites harmonieuses avec des couleurs lumineuses<\/li>\n<\/ul>\n<div class=\"wpa-accordion wpa-accordion-flush\" id=\"accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique\">\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-1\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">01<\/span> Fondamentaux des animations CSS avec effets n\u00e9on<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-1\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Comprendre les propri\u00e9t\u00e9s CSS pour les effets lumineux<\/h4>\n<p>Les effets n\u00e9on reposent principalement sur la propri\u00e9t\u00e9 CSS <code>box-shadow<\/code> combin\u00e9e \u00e0 des transitions fluides. Pour cr\u00e9er un effet lumineux convaincant, nous utilisons plusieurs ombres empil\u00e9es avec des rayons de flou diff\u00e9rents. La premi\u00e8re ombre, plus petite et intense, simule la lumi\u00e8re directe, tandis que les ombres plus larges cr\u00e9ent le halo lumineux caract\u00e9ristique du n\u00e9on. La propri\u00e9t\u00e9 <code>filter: blur()<\/code> peut \u00e9galement \u00eatre utilis\u00e9e pour adoucir les contours et renforcer l&rsquo;illusion de lumi\u00e8re diffuse.<\/p>\n<h4>Animation et keyframes pour un rendu dynamique<\/h4>\n<p>Les animations CSS permettent de faire varier l&rsquo;intensit\u00e9 lumineuse dans le temps gr\u00e2ce aux <code>@keyframes<\/code>. En modifiant progressivement l&rsquo;opacit\u00e9, la taille des ombres ou m\u00eame la couleur, nous obtenons des effets de pulsation tr\u00e8s r\u00e9alistes. La fonction <code>ease-in-out<\/code> assure des transitions naturelles, \u00e9vitant les \u00e0-coups visuels. Pour des animations infinies, nous utilisons <code>animation-iteration-count: infinite<\/code> coupl\u00e9 \u00e0 <code>animation-direction: alternate<\/code> pour cr\u00e9er un mouvement de va-et-vient hypnotique.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : L&rsquo;effet n\u00e9on n\u00e9cessite un fond sombre pour r\u00e9v\u00e9ler toute sa puissance visuelle. Utilisez toujours des couleurs satur\u00e9es (cyan, magenta, jaune \u00e9lectrique) sur des fonds noirs ou tr\u00e8s fonc\u00e9s.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">Les effets n\u00e9on en CSS reposent sur la superposition d&rsquo;ombres color\u00e9es de diff\u00e9rentes tailles, anim\u00e9es en boucle pour simuler la pulsation caract\u00e9ristique de la lumi\u00e8re \u00e9lectrique.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : Cr\u00e9er un cercle n\u00e9on pulsant<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">R\u00e9alisez un cercle qui pulse avec un effet n\u00e9on cyan sur fond noir en utilisant les propri\u00e9t\u00e9s CSS box-shadow et animation.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-1\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"css\">CSS<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Cercle N\u00e9on Pulsant&lt;\/title&gt;\n    &lt;link rel=\"stylesheet\" href=\"style.css\"&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div class=\"container\"&gt;\n        &lt;div class=\"neon-circle\"&gt;&lt;\/div&gt;\n    &lt;\/div&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"css\">body {\n    margin: 0;\n    padding: 0;\n    background: #0a0a0a;\n    min-height: 100vh;\n    overflow: hidden;\n}\n\n.container {\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    min-height: 100vh;\n}\n\n.neon-circle {\n    width: 200px;\n    height: 200px;\n    border-radius: 50%;\n    background: rgba(0, 255, 255, 0.1);\n    border: 2px solid #00ffff;\n    box-shadow: \n        0 0 10px #00ffff,\n        0 0 20px #00ffff,\n        0 0 40px #00ffff,\n        0 0 80px #00ffff,\n        inset 0 0 10px rgba(0, 255, 255, 0.2);\n    animation: neonPulse 2s ease-in-out infinite alternate;\n}\n\n@keyframes neonPulse {\n    0% {\n        box-shadow: \n            0 0 10px #00ffff,\n            0 0 20px #00ffff,\n            0 0 40px #00ffff,\n            0 0 80px #00ffff,\n            inset 0 0 10px rgba(0, 255, 255, 0.2);\n    }\n    100% {\n        box-shadow: \n            0 0 20px #00ffff,\n            0 0 40px #00ffff,\n            0 0 80px #00ffff,\n            0 0 160px #00ffff,\n            inset 0 0 20px rgba(0, 255, 255, 0.4);\n        transform: scale(1.05);\n    }\n}<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-1\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"css\">CSS<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"css\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-2\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">02<\/span> G\u00e9n\u00e9ration de formes g\u00e9om\u00e9triques avec p5.js<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-2\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Introduction \u00e0 p5.js pour le design g\u00e9n\u00e9ratif<\/h4>\n<p>P5.js est une biblioth\u00e8que JavaScript con\u00e7ue pour rendre la programmation cr\u00e9ative accessible aux designers. Bas\u00e9e sur Processing, elle permet de cr\u00e9er des animations et des visualisations interactives directement dans le navigateur. Pour d\u00e9buter, nous utilisons deux fonctions essentielles : <code>setup()<\/code> qui s&rsquo;ex\u00e9cute une seule fois au lancement, et <code>draw()<\/code> qui se r\u00e9p\u00e8te en boucle pour cr\u00e9er l&rsquo;animation. La fonction <code>createCanvas()<\/code> d\u00e9finit l&rsquo;espace de travail, tandis que <code>background()<\/code> efface l&rsquo;\u00e9cran \u00e0 chaque frame pour \u00e9viter les superpositions non d\u00e9sir\u00e9es.<\/p>\n<h4>Cr\u00e9ation de formes g\u00e9om\u00e9triques dynamiques<\/h4>\n<p>Les formes g\u00e9om\u00e9triques de base comme les cercles, rectangles et triangles peuvent \u00eatre anim\u00e9es en modifiant leurs param\u00e8tres dans le temps. L&rsquo;utilisation de fonctions trigonom\u00e9triques comme <code>sin()<\/code> et <code>cos()<\/code> permet de cr\u00e9er des mouvements fluides et naturels. En combinant plusieurs formes avec des d\u00e9calages de phase, nous obtenons des compositions complexes et harmonieuses. La fonction <code>translate()<\/code> d\u00e9place le syst\u00e8me de coordonn\u00e9es, permettant de faire tourner ou d\u00e9placer facilement des groupes d&rsquo;\u00e9l\u00e9ments autour d&rsquo;un point central.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : P5.js utilise un syst\u00e8me de coordonn\u00e9es o\u00f9 (0,0) se trouve en haut \u00e0 gauche. Pour centrer des \u00e9l\u00e9ments, utilisez width\/2 et height\/2 comme coordonn\u00e9es de r\u00e9f\u00e9rence.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">P5.js utilise une structure simple avec setup() pour l&rsquo;initialisation et draw() pour l&rsquo;animation en boucle, permettant de cr\u00e9er facilement des formes g\u00e9om\u00e9triques anim\u00e9es.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : Triangles g\u00e9om\u00e9triques en rotation<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">Cr\u00e9ez plusieurs triangles color\u00e9s qui tournent autour du centre de l&rsquo;\u00e9cran avec des vitesses diff\u00e9rentes pour un effet g\u00e9om\u00e9trique hypnotisant.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-2\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS (p5.js)<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Triangles G\u00e9om\u00e9triques&lt;\/title&gt;\n    &lt;script src=\"https:\/\/cdn.jsdelivr.net\/npm\/p5@1\/lib\/p5.min.js\"&gt;&lt;\/script&gt;\n    &lt;style&gt;\n        body { margin: 0; padding: 0; background: #0a0a0a; }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;script src=\"sketch.js\"&gt;&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">let angle = 0;\nlet triangles = [];\n\nfunction setup() {\n    createCanvas(windowWidth, windowHeight);\n    \n    \/\/ Cr\u00e9er plusieurs triangles avec diff\u00e9rentes propri\u00e9t\u00e9s\n    for (let i = 0; i < 6; i++) {\n        triangles.push({\n            radius: 50 + i * 30,\n            speed: 0.01 + i * 0.005,\n            size: 40 + i * 10,\n            color: [\n                random(100, 255), \/\/ R\n                random(100, 255), \/\/ G  \n                random(100, 255)  \/\/ B\n            ],\n            offset: i * PI \/ 3\n        });\n    }\n}\n\nfunction draw() {\n    background(10, 10, 15, 50); \/\/ Trail effect\n    \n    translate(width \/ 2, height \/ 2);\n    \n    for (let triangle of triangles) {\n        push();\n        \n        \/\/ Position du triangle en rotation\n        let x = cos(angle * triangle.speed + triangle.offset) * triangle.radius;\n        let y = sin(angle * triangle.speed + triangle.offset) * triangle.radius;\n        \n        translate(x, y);\n        rotate(angle * triangle.speed * 2);\n        \n        \/\/ Style du triangle avec effet glow\n        fill(triangle.color[0], triangle.color[1], triangle.color[2], 150);\n        stroke(triangle.color[0], triangle.color[1], triangle.color[2]);\n        strokeWeight(2);\n        \n        \/\/ Dessiner le triangle\n        beginShape();\n        for (let i = 0; i < 3; i++) {\n            let triX = cos(i * TWO_PI \/ 3) * triangle.size;\n            let triY = sin(i * TWO_PI \/ 3) * triangle.size;\n            vertex(triX, triY);\n        }\n        endShape(CLOSE);\n        \n        pop();\n    }\n    \n    angle += 0.02;\n}\n\nfunction windowResized() {\n    resizeCanvas(windowWidth, windowHeight);\n}<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-2\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS (p5.js)<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-3\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">03<\/span> Patterns abstraits et fractales simples<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-3\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Comprendre les patterns r\u00e9p\u00e9titifs<\/h4>\n<p>Les patterns abstraits reposent sur la r\u00e9p\u00e9tition d'\u00e9l\u00e9ments simples selon des r\u00e8gles math\u00e9matiques pr\u00e9cises. En programmation cr\u00e9ative, nous utilisons des boucles imbriqu\u00e9es pour g\u00e9n\u00e9rer des grilles d'\u00e9l\u00e9ments o\u00f9 chaque position influence les propri\u00e9t\u00e9s visuelles : couleur, taille, rotation ou transparence. La fonction <code>map()<\/code> de p5.js est particuli\u00e8rement utile pour convertir la position d'un \u00e9l\u00e9ment en param\u00e8tres visuels, cr\u00e9ant ainsi des d\u00e9grad\u00e9s et des transitions harmonieuses \u00e0 travers la composition.<\/p>\n<h4>Introduction aux fractales g\u00e9om\u00e9triques<\/h4>\n<p>Les fractales sont des formes qui se r\u00e9p\u00e8tent \u00e0 diff\u00e9rentes \u00e9chelles, cr\u00e9ant des motifs complexes \u00e0 partir de r\u00e8gles simples. L'arbre fractal en est un exemple parfait : chaque branche se divise en branches plus petites selon un angle et un ratio de taille constants. En programmation, nous utilisons la r\u00e9cursion (une fonction qui s'appelle elle-m\u00eame) pour g\u00e9n\u00e9rer ces structures. Les param\u00e8tres comme l'angle de branchement, le facteur de r\u00e9duction et le nombre d'it\u00e9rations contr\u00f4lent l'apparence finale de la fractale.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : Les fractales peuvent rapidement devenir tr\u00e8s complexes et ralentir l'animation. Limitez le nombre d'it\u00e9rations (g\u00e9n\u00e9ralement 5-8 niveaux) pour maintenir une performance fluide.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">Les patterns abstraits utilisent des boucles et des fonctions math\u00e9matiques pour cr\u00e9er des r\u00e9p\u00e9titions harmonieuses, tandis que les fractales emploient la r\u00e9cursion pour g\u00e9n\u00e9rer des formes auto-similaires \u00e0 diff\u00e9rentes \u00e9chelles.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : Arbre fractal lumineux<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">Cr\u00e9ez un arbre fractal qui pousse du bas de l'\u00e9cran avec des branches lumineuses qui changent de couleur selon leur niveau de profondeur.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-3\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS (p5.js)<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Arbre Fractal Lumineux&lt;\/title&gt;\n    &lt;script src=\"https:\/\/cdn.jsdelivr.net\/npm\/p5@1\/lib\/p5.min.js\"&gt;&lt;\/script&gt;\n    &lt;style&gt;\n        body { margin: 0; padding: 0; background: #050510; }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;script src=\"sketch.js\"&gt;&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">let angle = 0;\n\nfunction setup() {\n    createCanvas(windowWidth, windowHeight);\n}\n\nfunction draw() {\n    background(5, 5, 16);\n    \n    \/\/ Positionnement au bas du centre de l'\u00e9cran\n    translate(width \/ 2, height);\n    \n    \/\/ Angle dynamique bas\u00e9 sur le temps\n    let branchAngle = map(sin(angle), -1, 1, PI\/6, PI\/4);\n    \n    \/\/ Dessiner l'arbre fractal\n    drawBranch(100, 0, branchAngle);\n    \n    angle += 0.01;\n}\n\nfunction drawBranch(len, depth, branchAngle) {\n    \/\/ Limiter la profondeur pour les performances\n    if (depth > 7 || len < 4) {\n        return;\n    }\n    \n    \/\/ Couleur bas\u00e9e sur la profondeur\n    let hue = map(depth, 0, 7, 180, 300); \/\/ Cyan vers magenta\n    let brightness = map(len, 4, 100, 100, 255);\n    \n    stroke(brightness, brightness * 0.8, 255);\n    strokeWeight(map(len, 4, 100, 1, 4));\n    \n    \/\/ Effet glow pour les branches principales\n    if (depth < 3) {\n        drawingContext.shadowColor = `rgb(${brightness}, ${brightness * 0.8}, 255)`;\n        drawingContext.shadowBlur = map(len, 4, 100, 5, 15);\n    } else {\n        drawingContext.shadowBlur = 0;\n    }\n    \n    \/\/ Dessiner la branche\n    line(0, 0, 0, -len);\n    \n    \/\/ Se d\u00e9placer au bout de la branche\n    translate(0, -len);\n    \n    \/\/ Branche droite\n    push();\n    rotate(branchAngle);\n    drawBranch(len * 0.75, depth + 1, branchAngle);\n    pop();\n    \n    \/\/ Branche gauche  \n    push();\n    rotate(-branchAngle);\n    drawBranch(len * 0.75, depth + 1, branchAngle);\n    pop();\n    \n    \/\/ Branche centrale (parfois)\n    if (depth < 4 &#038;&#038; random() < 0.3) {\n        push();\n        rotate(random(-0.2, 0.2));\n        drawBranch(len * 0.6, depth + 2, branchAngle);\n        pop();\n    }\n}\n\nfunction windowResized() {\n    resizeCanvas(windowWidth, windowHeight);\n}<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-3\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS (p5.js)<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-4\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">04<\/span> Optimisation des animations infinies<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-4\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Gestion de la performance et fluidit\u00e9<\/h4>\n<p>Pour maintenir une animation fluide, il est crucial de contr\u00f4ler le nombre d'\u00e9l\u00e9ments dessin\u00e9s \u00e0 chaque frame. L'utilisation de <code>frameRate()<\/code> permet de limiter le nombre d'images par seconde si n\u00e9cessaire, mais il est pr\u00e9f\u00e9rable d'optimiser le code lui-m\u00eame. \u00c9vitez les calculs complexes dans la boucle <code>draw()<\/code> en pr\u00e9-calculant les valeurs dans <code>setup()<\/code> ou en utilisant des tableaux de lookup. La fonction <code>requestAnimationFrame()<\/code> int\u00e9gr\u00e9e \u00e0 p5.js synchronise l'animation avec le taux de rafra\u00eechissement de l'\u00e9cran pour un rendu optimal.<\/p>\n<h4>Techniques de boucle parfaite<\/h4>\n<p>Une boucle d'animation parfaite red\u00e9marre imperceptiblement \u00e0 la fin de son cycle. Pour y parvenir, utilisez des fonctions p\u00e9riodiques comme <code>sin()<\/code> et <code>cos()<\/code> avec des phases calcul\u00e9es pour que les valeurs initiales et finales co\u00efncident. Le modulo (%) est \u00e9galement utile pour cr\u00e9er des cycles r\u00e9p\u00e9titifs sur les positions ou les couleurs. Planifiez votre animation sur une dur\u00e9e fixe (par exemple 10 secondes) et utilisez <code>millis() % duration<\/code> pour obtenir une position normalis\u00e9e dans le cycle.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : Testez toujours vos animations sur diff\u00e9rents appareils. Ce qui fonctionne \u00e0 60 FPS sur un ordinateur puissant peut ramer sur un smartphone. Impl\u00e9mentez des niveaux de d\u00e9tail adaptatifs si n\u00e9cessaire.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">L'optimisation repose sur la limitation des calculs par frame et l'utilisation de fonctions math\u00e9matiques p\u00e9riodiques pour cr\u00e9er des boucles parfaites et fluides.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : Vagues sinuso\u00efdales optimis\u00e9es<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">Cr\u00e9ez un syst\u00e8me de vagues color\u00e9es qui se d\u00e9placent de mani\u00e8re fluide et se r\u00e9p\u00e8tent parfaitement en boucle, avec un syst\u00e8me d'optimisation de performance.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-4\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS (p5.js)<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;Vagues Sinuso\u00efdales Optimis\u00e9es&lt;\/title&gt;\n    &lt;script src=\"https:\/\/cdn.jsdelivr.net\/npm\/p5@1\/lib\/p5.min.js\"&gt;&lt;\/script&gt;\n    &lt;style&gt;\n        body { margin: 0; padding: 0; background: #0a0a15; }\n        #fps { position: fixed; top: 10px; left: 10px; color: #fff; font-family: monospace; }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div id=\"fps\"&gt;FPS: --&lt;\/div&gt;\n    &lt;script src=\"sketch.js\"&gt;&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">let waves = [];\nlet time = 0;\nlet cycleDuration = 8000; \/\/ 8 secondes pour un cycle complet\nlet stepSize = 4; \/\/ Optimisation: r\u00e9duire le nombre de points\nlet lastFrameTime = 0;\nlet fpsCounter = 0;\nlet lastFpsUpdate = 0;\n\nfunction setup() {\n    createCanvas(windowWidth, windowHeight);\n    \n    \/\/ Pr\u00e9-calculer les propri\u00e9t\u00e9s des vagues\n    for (let i = 0; i < 5; i++) {\n        waves.push({\n            amplitude: random(30, 80),\n            frequency: random(0.01, 0.03),\n            speed: random(0.001, 0.005),\n            yOffset: height * (0.2 + i * 0.15),\n            color: {\n                r: random(50, 255),\n                g: random(100, 255), \n                b: random(150, 255)\n            },\n            phase: random(TWO_PI) \/\/ Phase initiale al\u00e9atoire\n        });\n    }\n    \n    \/\/ Optimisation: limiter le framerate si n\u00e9cessaire\n    frameRate(60);\n}\n\nfunction draw() {\n    background(10, 10, 21, 180); \/\/ Trail effect l\u00e9ger\n    \n    \/\/ Calculer le temps normalis\u00e9 pour une boucle parfaite\n    let currentTime = millis();\n    let normalizedTime = (currentTime % cycleDuration) \/ cycleDuration;\n    time = normalizedTime * TWO_PI; \/\/ Convertir en radians\n    \n    \/\/ Dessiner chaque vague\n    for (let wave of waves) {\n        drawWave(wave);\n    }\n    \n    \/\/ Monitoring des performances\n    updateFPS();\n}\n\nfunction drawWave(wave) {\n    stroke(wave.color.r, wave.color.g, wave.color.b, 180);\n    strokeWeight(2);\n    fill(wave.color.r, wave.color.g, wave.color.b, 30);\n    \n    \/\/ Effet glow pour les vagues principales\n    drawingContext.shadowColor = `rgba(${wave.color.r}, ${wave.color.g}, ${wave.color.b}, 0.5)`;\n    drawingContext.shadowBlur = 10;\n    \n    beginShape();\n    vertex(0, height); \/\/ Point de d\u00e9part au bas de l'\u00e9cran\n    \n    \/\/ G\u00e9n\u00e9rer les points de la vague avec optimisation\n    for (let x = 0; x <= width; x += stepSize) {\n        let y = wave.yOffset + \n                sin((x * wave.frequency) + (time * wave.speed * cycleDuration) + wave.phase) * wave.amplitude +\n                cos((x * wave.frequency * 0.7) + (time * wave.speed * 1.3 * cycleDuration)) * wave.amplitude * 0.3;\n        vertex(x, y);\n    }\n    \n    vertex(width, height); \/\/ Point final au bas de l'\u00e9cran\n    endShape(CLOSE);\n    \n    \/\/ R\u00e9initialiser l'effet glow\n    drawingContext.shadowBlur = 0;\n}\n\nfunction updateFPS() {\n    fpsCounter++;\n    let currentTime = millis();\n    \n    if (currentTime - lastFpsUpdate > 1000) {\n        document.getElementById('fps').textContent = `FPS: ${fpsCounter}`;\n        fpsCounter = 0;\n        lastFpsUpdate = currentTime;\n    }\n}\n\nfunction windowResized() {\n    resizeCanvas(windowWidth, windowHeight);\n    \n    \/\/ Recalculer les offsets Y des vagues\n    for (let i = 0; i < waves.length; i++) {\n        waves[i].yOffset = height * (0.2 + i * 0.15);\n    }\n}<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-4\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS (p5.js)<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"wpa-accordion-item\">\n<button class=\"wpa-accordion-header\" data-wpa-target=\"#accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-5\" aria-expanded=\"false\"><span class=\"wpa-accordion-title\"><span class=\"wpa-accordion-number\">05<\/span> Composition finale et export pour \u00e9conomiseur d'\u00e9cran<\/span><span class=\"wpa-accordion-icon\"><\/span><\/button><\/p>\n<div id=\"accordion-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique-item-5\" class=\"wpa-accordion-body\">\n<div class=\"wpa-accordion-content\">\n<h4>Assemblage des \u00e9l\u00e9ments visuels<\/h4>\n<p>La composition finale d'un fond d'\u00e9cran abstrait n\u00e9cessite une approche en couches pour cr\u00e9er de la profondeur visuelle. Commencez par un arri\u00e8re-plan d\u00e9grad\u00e9 subtil, ajoutez ensuite les \u00e9l\u00e9ments g\u00e9om\u00e9triques principaux (cercles, polygones), puis les d\u00e9tails comme les fractales ou patterns. Chaque couche doit avoir sa propre vitesse d'animation pour cr\u00e9er un effet de parallaxe naturel. L'utilisation de modes de fusion comme <code>blendMode(SCREEN)<\/code> ou <code>blendMode(ADD)<\/code> permet de cr\u00e9er des interactions lumineuses entre les couches, renfor\u00e7ant l'effet n\u00e9on recherch\u00e9.<\/p>\n<h4>Adaptation responsive et formats d'export<\/h4>\n<p>Un bon \u00e9conomiseur d'\u00e9cran doit s'adapter \u00e0 toutes les tailles d'\u00e9cran, des smartphones aux \u00e9crans ultra-larges. Utilisez <code>windowResized()<\/code> pour recalculer les positions et tailles relatives lorsque la fen\u00eatre change de dimensions. Pour l'export, consid\u00e9rez la conversion en vid\u00e9o MP4 pour une compatibilit\u00e9 maximale : utilisez <code>saveFrames()<\/code> pour capturer une s\u00e9quence d'images, puis assemblez-les avec un outil externe. Alternativement, votre sketch p5.js peut fonctionner directement dans un navigateur web comme \u00e9conomiseur d'\u00e9cran HTML5.<\/p>\n<div class=\"info-box\">\n<p><strong>Point cl\u00e9<\/strong> : Pour un \u00e9conomiseur d'\u00e9cran, privil\u00e9giez les animations lentes et hypnotiques plut\u00f4t que les mouvements brusques. L'objectif est de cr\u00e9er une ambiance relaxante, pas de stimuler l'attention.<\/p>\n<\/div>\n<div class=\"tuto-objectif\" style=\"background: #f5f5f5; border-left: 4px solid #667eea; padding: 16px 20px; margin-top: 24px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #667eea; margin: 0 0 8px 0; font-size: 16px;\">\u00c0 retenir<\/h3>\n<p style=\"margin: 0; color: #333;\">Une composition r\u00e9ussie superpose plusieurs couches d'\u00e9l\u00e9ments anim\u00e9s \u00e0 des vitesses diff\u00e9rentes, avec une adaptation responsive pour tous les formats d'\u00e9cran.<\/p>\n<\/div>\n<div class=\"tuto-exercise\" style=\"background: #fff3e0; border-left: 4px solid #ff9800; padding: 16px 20px; margin-top: 20px; border-radius: 0 8px 8px 0;\">\n<h4 style=\"color: #ff9800; margin: 0 0 8px 0; font-size: 15px;\">\ud83c\udfaf Mini-exercice : \u00c9conomiseur d'\u00e9cran complet<\/h4>\n<p style=\"margin: 0; color: #333; font-size: 14px;\">Cr\u00e9ez un \u00e9conomiseur d'\u00e9cran complet combinant formes g\u00e9om\u00e9triques, effets n\u00e9on, et animations fluides avec syst\u00e8me de couches et adaptation responsive.<\/p>\n<\/div>\n<div class=\"codepen-block\" data-block-id=\"exercise-5\">\n<p class=\"codepen-block-label\">Code de r\u00e9f\u00e9rence :<\/p>\n<div class=\"codepen-header\">\n<div class=\"codepen-tabs\">\n<button class=\"codepen-tab active\" data-tab=\"html\">HTML<\/button><br \/>\n<button class=\"codepen-tab\" data-tab=\"javascript\">JS (p5.js)<\/button>\n<\/div>\n<p><button class=\"codepen-copy-btn\">Copier<\/button>\n<\/div>\n<div class=\"codepen-code-container\">\n<pre class=\"codepen-code active\" data-lang=\"html\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"fr\"&gt;\n&lt;head&gt;\n    &lt;meta charset=\"UTF-8\"&gt;\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"&gt;\n    &lt;title&gt;\u00c9conomiseur d'\u00e9cran N\u00e9on&lt;\/title&gt;\n    &lt;script src=\"https:\/\/cdn.jsdelivr.net\/npm\/p5@1\/lib\/p5.min.js\"&gt;&lt;\/script&gt;\n    &lt;style&gt;\n        body { \n            margin: 0; \n            padding: 0; \n            background: #000; \n            overflow: hidden;\n            cursor: none;\n        }\n        canvas { display: block; }\n        .info {\n            position: fixed;\n            bottom: 20px;\n            right: 20px;\n            color: rgba(255,255,255,0.3);\n            font-family: 'Courier New', monospace;\n            font-size: 12px;\n        }\n    &lt;\/style&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;div class=\"info\"&gt;Appuyez sur Espace pour changer de mode&lt;\/div&gt;\n    &lt;script src=\"sketch.js\"&gt;&lt;\/script&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n<pre class=\"codepen-code\" data-lang=\"javascript\">let time = 0;\nlet particles = [];\nlet geometricShapes = [];\nlet backgroundWaves = [];\nlet currentMode = 0;\nlet modeNames = ['N\u00e9on G\u00e9om\u00e9trique', 'Fractales Cosmiques', 'Vagues Abstraites'];\n\nfunction setup() {\n    createCanvas(windowWidth, windowHeight);\n    colorMode(HSB, 360, 100, 100, 100);\n    \n    initializeElements();\n}\n\nfunction initializeElements() {\n    \/\/ Initialiser les particules de fond\n    particles = [];\n    for (let i = 0; i < 50; i++) {\n        particles.push({\n            x: random(width),\n            y: random(height),\n            speedX: random(-0.5, 0.5),\n            speedY: random(-0.5, 0.5),\n            size: random(1, 3),\n            hue: random(180, 300),\n            alpha: random(20, 60)\n        });\n    }\n    \n    \/\/ Formes g\u00e9om\u00e9triques principales\n    geometricShapes = [];\n    for (let i = 0; i < 8; i++) {\n        geometricShapes.push({\n            x: width * (0.2 + i * 0.1),\n            y: height * 0.5,\n            rotation: 0,\n            rotationSpeed: random(-0.01, 0.01),\n            size: random(40, 120),\n            sides: floor(random(3, 8)),\n            hue: (i * 45) % 360,\n            orbitRadius: random(50, 150),\n            orbitSpeed: random(0.005, 0.015),\n            phase: random(TWO_PI)\n        });\n    }\n    \n    \/\/ Vagues de fond\n    backgroundWaves = [];\n    for (let i = 0; i < 6; i++) {\n        backgroundWaves.push({\n            yOffset: height * (0.1 + i * 0.15),\n            amplitude: random(20, 60),\n            frequency: random(0.005, 0.02),\n            speed: random(0.001, 0.003),\n            hue: (i * 60 + 180) % 360,\n            alpha: random(10, 30)\n        });\n    }\n}\n\nfunction draw() {\n    \/\/ D\u00e9grad\u00e9 de fond dynamique\n    drawBackground();\n    \n    \/\/ Couche 1: Vagues de fond\n    drawBackgroundWaves();\n    \n    \/\/ Couche 2: Particules flottantes\n    drawParticles();\n    \n    \/\/ Couche 3: Formes g\u00e9om\u00e9triques principales\n    drawGeometricShapes();\n    \n    \/\/ Couche 4: Effets de surface\n    drawSurfaceEffects();\n    \n    \/\/ Interface\n    drawModeInfo();\n    \n    time += 0.01;\n}\n\nfunction drawBackground() {\n    \/\/ D\u00e9grad\u00e9 dynamique\n    for (let y = 0; y < height; y += 2) {\n        let inter = map(y, 0, height, 0, 1);\n        let c1 = color(220 + sin(time * 0.5) * 20, 80, 5);\n        let c2 = color(280 + cos(time * 0.3) * 30, 60, 15);\n        let gradientColor = lerpColor(c1, c2, inter);\n        stroke(gradientColor);\n        line(0, y, width, y);\n    }\n}\n\nfunction drawBackgroundWaves() {\n    for (let wave of backgroundWaves) {\n        stroke(wave.hue, 70, 80, wave.alpha);\n        strokeWeight(1);\n        noFill();\n        \n        beginShape();\n        for (let x = 0; x <= width; x += 5) {\n            let y = wave.yOffset + \n                    sin(x * wave.frequency + time * wave.speed) * wave.amplitude +\n                    cos(x * wave.frequency * 0.7 + time * wave.speed * 1.3) * wave.amplitude * 0.5;\n            vertex(x, y);\n        }\n        endShape();\n    }\n}\n\nfunction drawParticles() {\n    for (let particle of particles) {\n        \/\/ Mise \u00e0 jour position\n        particle.x += particle.speedX;\n        particle.y += particle.speedY;\n        \n        \/\/ Rebond sur les bords\n        if (particle.x < 0 || particle.x > width) particle.speedX *= -1;\n        if (particle.y < 0 || particle.y > height) particle.speedY *= -1;\n        \n        \/\/ Affichage\n        fill(particle.hue, 60, 90, particle.alpha);\n        noStroke();\n        ellipse(particle.x, particle.y, particle.size);\n        \n        \/\/ Effet glow\n        drawingContext.shadowColor = `hsla(${particle.hue}, 70%, 70%, 0.3)`;\n        drawingContext.shadowBlur = particle.size * 2;\n        ellipse(particle.x, particle.y, particle.size * 0.5);\n        drawingContext.shadowBlur = 0;\n    }\n}\n\nfunction drawGeometricShapes() {\n    for (let shape of geometricShapes) {\n        push();\n        \n        \/\/ Position orbitale\n        let orbitX = shape.x + cos(time * shape.orbitSpeed + shape.phase) * shape.orbitRadius;\n        let orbitY = shape.y + sin(time * shape.orbitSpeed + shape.phase) * shape.orbitRadius * 0.6;\n        \n        translate(orbitX, orbitY);\n        rotate(shape.rotation + time * shape.rotationSpeed);\n        \n        \/\/ Style n\u00e9on\n        stroke(shape.hue, 80, 100, 70);\n        strokeWeight(2);\n        fill(shape.hue, 60, 100, 15);\n        \n        \/\/ Effet glow multiple\n        drawingContext.shadowColor = `hsla(${shape.hue}, 80%, 60%, 0.8)`;\n        drawingContext.shadowBlur = 15;\n        \n        \/\/ Dessiner polygone\n        beginShape();\n        for (let i = 0; i < shape.sides; i++) {\n            let angle = map(i, 0, shape.sides, 0, TWO_PI);\n            let x = cos(angle) * shape.size;\n            let y = sin(angle) * shape.size;\n            vertex(x, y);\n        }\n        endShape(CLOSE);\n        \n        drawingContext.shadowBlur = 0;\n        pop();\n    }\n}\n\nfunction drawSurfaceEffects() {\n    \/\/ Lignes de connexion entre formes proches\n    stroke(200, 50, 80, 20);\n    strokeWeight(1);\n    \n    for (let i = 0; i < geometricShapes.length - 1; i++) {\n        for (let j = i + 1; j < geometricShapes.length; j++) {\n            let shape1 = geometricShapes[i];\n            let shape2 = geometricShapes[j];\n            \n            let x1 = shape1.x + cos(time * shape1.orbitSpeed + shape1.phase) * shape1.orbitRadius;\n            let y1 = shape1.y + sin(time * shape1.orbitSpeed + shape1.phase) * shape1.orbitRadius * 0.6;\n            let x2 = shape2.x + cos(time * shape2.orbitSpeed + shape2.phase) * shape2.orbitRadius;\n            let y2 = shape2.y + sin(time * shape2.orbitSpeed + shape2.phase) * shape2.orbitRadius * 0.6;\n            \n            let distance = dist(x1, y1, x2, y2);\n            \n            if (distance < 200) {\n                let alpha = map(distance, 0, 200, 30, 0);\n                stroke(200, 50, 80, alpha);\n                line(x1, y1, x2, y2);\n            }\n        }\n    }\n}\n\nfunction drawModeInfo() {\n    fill(0, 0, 100, 40);\n    textAlign(LEFT, TOP);\n    textSize(16);\n    text(`Mode: ${modeNames[currentMode]}`, 20, 20);\n    textSize(12);\n    text(`${frameRate().toFixed(1)} FPS`, 20, 45);\n}\n\nfunction keyPressed() {\n    if (key === ' ') {\n        currentMode = (currentMode + 1) % modeNames.length;\n        initializeElements();\n    }\n}\n\nfunction windowResized() {\n    resizeCanvas(windowWidth, windowHeight);\n    initializeElements();\n}<\/pre>\n<\/div>\n<\/div>\n<div class=\"monaco-sandbox\" data-block-id=\"exercise-5\">\n<div class=\"monaco-header\">\n<div class=\"monaco-tabs\">\n<button class=\"monaco-tab active\" data-lang=\"html\">HTML<\/button><br \/>\n<button class=\"monaco-tab\" data-lang=\"javascript\">JS (p5.js)<\/button>\n<\/div>\n<div class=\"monaco-actions\">\n<button class=\"monaco-btn monaco-btn-run\">\u25b6 Ex\u00e9cuter<\/button><br \/>\n<button class=\"monaco-btn monaco-btn-reset\">\u21ba Reset<\/button>\n<\/div>\n<\/div>\n<div class=\"monaco-container\">\n<div class=\"monaco-editor-wrapper\">\n<div class=\"monaco-editor-pane active\" data-lang=\"html\"><\/div>\n<div class=\"monaco-editor-pane\" data-lang=\"javascript\"><\/div>\n<\/div>\n<div class=\"monaco-preview-wrapper\">\n<div class=\"monaco-preview-header\">Result<\/div>\n<\/div>\n<\/div>\n<div class=\"monaco-status\">\n<span class=\"monaco-status-left\">\u25cf Pr\u00eat<\/span><br \/>\n<span class=\"monaco-status-right\">Monaco Editor v0.45<\/span>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<h2>R\u00e9capitulatif<\/h2>\n<div class=\"tuto-recap\" style=\"background: #f5f5f5; border-left: 4px solid #9c27b0; padding: 16px 20px; border-radius: 0 8px 8px 0;\">\n<h3 style=\"color: #9c27b0; margin: 0 0 12px 0; font-size: 16px;\">Points essentiels \u00e0 retenir<\/h3>\n<ul style=\"margin: 0; padding-left: 20px; color: #333;\">\n<li><strong>Effets n\u00e9on CSS<\/strong> : Utilisez plusieurs box-shadow empil\u00e9es avec des rayons diff\u00e9rents pour cr\u00e9er des halos lumineux r\u00e9alistes sur fond sombre<\/li>\n<li><strong>P5.js pour le g\u00e9n\u00e9ratif<\/strong> : La structure setup()\/draw() permet de cr\u00e9er facilement des animations avec formes g\u00e9om\u00e9triques et fonctions trigonom\u00e9triques<\/li>\n<li><strong>Patterns et fractales<\/strong> : Les boucles imbriqu\u00e9es g\u00e9n\u00e8rent des motifs r\u00e9p\u00e9titifs, tandis que la r\u00e9cursion cr\u00e9e des structures fractales auto-similaires<\/li>\n<li><strong>Optimisation des performances<\/strong> : Limitez les calculs par frame, pr\u00e9-calculez les valeurs fixes, et utilisez des fonctions p\u00e9riodiques pour des boucles parfaites<\/li>\n<li><strong>Composition en couches<\/strong> : Superposez des \u00e9l\u00e9ments anim\u00e9s \u00e0 diff\u00e9rentes vitesses avec adaptation responsive pour cr\u00e9er de la profondeur et s'adapter \u00e0 tous les \u00e9crans<\/li>\n<\/ul>\n<\/div>\n<h2>Sources<\/h2>\n<div class=\"sources-box\" style=\"background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%); border: 1px solid #cbd5e1; border-radius: 12px; padding: 16px; margin-bottom: 24px;\">\n<p style=\"color: #64748b; margin: 0 0 12px 0; font-size: 13px;\">Pour approfondir vos connaissances :<\/p>\n<ul style=\"margin: 0; padding-left: 0; list-style: none;\">\n<li style=\"margin-bottom: 8px;\">\n<a href=\"#\" style=\"display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: white; border-radius: 8px; text-decoration: none; color: #1e293b; border: 1px solid #e2e8f0;\"><br \/>\n<span style=\"color: #94a3b8;\">\ud83d\udd17<\/span><br \/>\n<span style=\"flex: 1; font-weight: 500; color: #0f172a;\">Documentation officielle P5.js - Guide des animations<\/span><br \/>\n<span style=\"color: #94a3b8;\">\u2192<\/span><br \/>\n<\/a>\n<\/li>\n<li style=\"margin-bottom: 0;\">\n<a href=\"#\" style=\"display: flex; align-items: center; gap: 10px; padding: 10px 14px; background: white; border-radius: 8px; text-decoration: none; color: #1e293b; border: 1px solid #e2e8f0;\"><br \/>\n<span style=\"color: #94a3b8;\">\ud83d\udd17<\/span><br \/>\n<span style=\"flex: 1; font-weight: 500; color: #0f172a;\">CSS-Tricks - Guide complet des effets n\u00e9on et glow<\/span><br \/>\n<span style=\"color: #94a3b8;\">\u2192<\/span><br \/>\n<\/a>\n<\/li>\n<\/ul>\n<\/div>\n<h2>Validez vos connaissances<\/h2>\n<p>Testez votre compr\u00e9hension avec ce quiz de 10 questions :<\/p>\n<div id=\"quiz-block-1\" class=\"quiz-container\" data-quiz-json=\"https:\/\/lmspro.fr\/wp-content\/plugins\/generate-article-endpoint\/quiz-data\/en\/quiz-apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique.json\" aria-label=\"Interactive Quiz\"><div class=\"quiz-loading\" role=\"status\" aria-live=\"polite\"><span class=\"quiz-sr-only\">Loading quiz...<\/span><\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Learn to generate abstract and geometric wallpapers. Dive into the fascinating world of generative design to create animated wallpapers with abstract and geometric shapes. Discover how to master neon effects on a dark background to achieve captivating, endless animations with 5 progressive tutorials suitable for beginners. Module: Module 6: \u2026 <a href=\"https:\/\/lmspro.fr\/en\/apprendre-a-generer-des-fonds-decran-abstrait-et-geometrique\/\" class=\"more-link\">Read More<span class=\"screen-reader-text\"> \u00ab\u00a0Apprendre \u00e0 g\u00e9n\u00e9rer des fonds d&rsquo;\u00e9cran abstrait et g\u00e9om\u00e9trique\u00a0\u00bb<\/span> &raquo;<\/a><\/p>","protected":false},"author":1,"featured_media":241,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[183],"tags":[185,5],"class_list":["post-597","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-module-bonus","tag-bonus","tag-design"],"_links":{"self":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts\/597","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/comments?post=597"}],"version-history":[{"count":1,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts\/597\/revisions"}],"predecessor-version":[{"id":607,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/posts\/597\/revisions\/607"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/media\/241"}],"wp:attachment":[{"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/media?parent=597"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/categories?post=597"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/lmspro.fr\/en\/wp-json\/wp\/v2\/tags?post=597"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}