Fractali, quelle figure enigmatiche che sono ovunque ma non possono essere viste dall'occhio non addestrato. Oggi disegneremo uno dei più noti Fractali, utilizzando solo Vanilla JS e l'API HTML5 Canvas. Cosa imparerai Che cosa è un albero fractale? Scrivere l'albero fractale in vaniglia JS Al di là dell'albero fractale Che cosa è un albero fractale? Per definire un albero fractale, prima dobbiamo conoscere la definizione di fractale, ovviamente. I fractali sono schemi infiniti creati ripetendo equazioni matematiche, che, su qualsiasi scala, su qualsiasi livello di zoom, sembrano approssimativamente gli stessi. Quindi, se dividiamo un Fractal, vedremo una copia ridotta del tutto. Benoit Mandelbrot, che ha inventato il termine fractale nel 1975, ha detto: Un fractale è una forma fatta di parti simili al tutto in qualche modo. Un fractale è una forma fatta di parti simili al tutto in qualche modo. Molto chiaro no? Ecco alcuni esempi: Cos’è un albero fractale? Immaginate un ramo, e rami che escono da esso, e poi due rami che escono da ciascun ramo, e così via... ecco come appare un albero fractale. La sua forma deriva dal triangolo Sierpinski (o gazzetta Sierpinski). Come potete vedere, uno diventa l'altro quando si cambia l'angolo tra i rami: Oggi, finiremo con una figura simile alla forma finale di quel GIF. Scrivere l'albero fractale in vaniglia JS Prima di tutto, ecco il prodotto finale (puoi regolarlo lungo la strada): E adesso facciamo questo, passo dopo passo. Prima di tutto, inizializziamo il nostro file index.html con un panno di qualsiasi dimensione ragionevole e un tag script dove sarà tutto il nostro codice JS. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script></script> </body> </html> Quindi iniziamo a scrivere il nostro JavaScript. Inizializziamo il nostro elemento canvas su JS, accedendolo attraverso la variabile myCanvas e creando il contesto di rendering 2D con la variabile ctx (context). <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); </script> </body> </html> Quindi sì, il metodo getContext aggiunge proprietà e metodi che consentono di disegnare, in questo caso, in 2D. Come possiamo definire l’algoritmo per disegnare un albero fractale? Vediamo, sappiamo che i rami sono sempre più piccoli e che ogni ramo finisce con due rami che escono da esso, uno a sinistra e uno a destra. In altre parole, quando un ramo è abbastanza lungo, attaccare due rami più piccoli ad esso. Sembra che dovremmo usare qualche dichiarazione recursiva da qualche parte, non è vero? Torniamo al codice, ora definiamo la nostra funzione che dovrebbe prendere almeno quattro argomenti: le coordinate X e Y dove inizia il ramo, la lunghezza del suo ramo e il suo angolo. fractalTree All'interno della nostra funzione, iniziamo il disegno con il metodo beginPath() e quindi salviamo lo stato del canvas con il metodo save() . <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); function draw(startX, startY, len, angle) { ctx.beginPath(); ctx.save(); } </script> </body> </html> Il metodo beginPath viene spesso utilizzato quando si inizia una nuova riga o figura che ha uno stile fisso, come lo stesso colore lungo l'intera riga, o la stessa larghezza. Ora disegneremo il nostro albero fractale disegnando una linea (ramo), ruotando il panno, disegnando il ramo successivo, e così via. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); function draw(startX, startY, len, angle) { ctx.beginPath(); ctx.save(); ctx.translate(startX, startY); ctx.rotate(angle * Math.PI/180); ctx.moveTo(0, 0); ctx.lineTo(0, -len); ctx.stroke(); if(len < 10) { ctx.restore(); return; } draw(0, -len, len*0.8, -15); draw(0, -len, len*0.8, +15); ctx.restore(); } draw(400, 600, 120, 0) </script> </body> </html> Quindi prima aggiungiamo tre metodi, tradurre, ruotare e muovereTo, che "muove" il panno, la sua origine e il nostro "penna" in modo da poter disegnare il ramo all'angolo desiderato. Gli ultimi due metodi prima della dichiarazione if sono lineTo e stroke; il primo aggiunge una linea retta al percorso corrente, e il secondo lo rende. Ora abbiamo una dichiarazione se che dice quando fermare la recursione, quando smettere di disegnare. , "restaurare lo stato di tela salvato di recente popping l'entrata superiore nella pila di stato di disegno". Documenti MDN Dopo la dichiarazione if, abbiamo la chiamata ricorrente e un'altra chiamata al metodo di ripristino e poi una chiamata alla funzione che abbiamo appena terminato. Ora esegui il codice nel tuo browser. Vedrai, finalmente, un albero fractale! E’ bello, giusto, ma facciamolo ancora meglio. Aggiungeremo un nuovo parametro alla nostra funzione di disegno, BranchWidth, per rendere il nostro albero fractale più realistico. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); function draw(startX, startY, len, angle, branchWidth) { ctx.lineWidth = branchWidth; ctx.beginPath(); ctx.save(); ctx.translate(startX, startY); ctx.rotate(angle * Math.PI/180); ctx.moveTo(0, 0); ctx.lineTo(0, -len); ctx.stroke(); if(len < 10) { ctx.restore(); return; } draw(0, -len, len*0.8, angle-15, branchWidth*0.8); draw(0, -len, len*0.8, angle+15, branchWidth*0.8); ctx.restore(); } draw(400, 600, 120, 0, 10) </script> </body> </html> Così in ogni iterazione, stiamo rendendo ogni ramo più sottile. ho anche cambiato il parametro d'angolo nella chiamata recursiva per fare un albero più "aperto". Ora, aggiungiamo qualche colore! e ombre, perché no. <!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> </head> <body> <canvas id="my_canvas" width="1000" height="800"></canvas> <script> var myCanvas = document.getElementById("my_canvas"); var ctx = myCanvas.getContext("2d"); function draw(startX, startY, len, angle, branchWidth) { ctx.lineWidth = branchWidth; ctx.beginPath(); ctx.save(); ctx.strokeStyle = "green"; ctx.fillStyle = "green"; ctx.translate(startX, startY); ctx.rotate(angle * Math.PI/180); ctx.moveTo(0, 0); ctx.lineTo(0, -len); ctx.stroke(); ctx.shadowBlur = 15; ctx.shadowColor = "rgba(0,0,0,0.8)"; if(len < 10) { ctx.restore(); return; } draw(0, -len, len*0.8, angle-15, branchWidth*0.8); draw(0, -len, len*0.8, angle+15, branchWidth*0.8); ctx.restore(); } draw(400, 600, 120, 0, 10) </script> </body> </html> Entrambi i metodi di colore sono auto-esplicativi (strokeStyle e fillStyle). Inoltre, quelli di ombra, shadowBlur e shadowColor. Salva il file e aprilo con il tuo browser per vedere il prodotto finale. Ora vi incoraggio a giocare con il codice! cambiare l'ombraColore, il fillStyle, fare un albero frattale più corto o più lungo, cambiare l'angolo, o provare ad aggiungere foglie, che dovrebbe essere impegnativo 😉 Al di là dell'albero fractale Come vi ho mostrato all'inizio di questo post, ci sono diversi Fractals. Ain't gonna essere facile fare tutti quelli con l'API Canvas, ma dovrebbe essere possibile. ho fatto alcuni di quelli nel linguaggio di programmazione C, e ho anche giocato intorno con p5.js. p5.js è una libreria open source di JavaScript creata da artisti, per artisti, basata su Puoi disegnare o animare qualsiasi cosa immaginabile. Se sei interessato a fare arte con il codice, è un must. Pagina che puoi controllare . Linguaggio di elaborazione iniziato qui Grazie per averlo letto, commentato qualsiasi domanda, e ci vediamo nel mio prossimo post! Copertina di socialtrendspr0 da Pixabay Copertina di socialtrendspr0 da Pixabay