Vai al contenuto
animorio
EN
Tutti i componenti

Il deframmentatore della memoria

Caricamento, Fisica, TransizioniGSAP, CanvasImpegnativaPeso compresso: Demo 11 KBGSAP 28 KBGratisScarica lo zip

L’ottimizzazione della memoria di un telefono fatta come un vecchio deframmentatore: una griglia di blocchi, uno per pezzo di file, con sistema, app, foto e documenti sparsi fra buchi vuoti e cache tratteggiata. Premuto Optimize la cache sparisce in un’onda, poi ogni blocco viene sollevato, cresce, vola in un arco al suo posto e atterra con uno schiacciamento, mentre quello che stava in mezzo vola dall’altra parte. I blocchi a posto prendono il loro colore pieno e la griglia si riempie come una barra di avanzamento, tipo dopo tipo. Un file aperto non si sposta e resta su in rosso fino a Retry; alla fine un’onda attraversa la griglia e Optimize again rimanda ogni blocco da dove era venuto.

Il codice

Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
  <title>The storage defragmenter</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/martian-mono@5.3.0/wdth.css">
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main class="stage">
    <!-- the storage defragmenter: a phone's storage as a grid of blocks, one per file chunk, scattered with gaps and
         cache. Optimize clears the cache in a wave, then every block is lifted and flown, in an arc, to its place:
         system, apps, photos, documents, and the free space all in one piece at the end. The grid is drawn by script.js -->
    <section class="df" aria-labelledby="df-title" data-defrag>
      <div class="df__head">
        <div class="df__words">
          <h2 class="df__title" id="df-title"><span class="df__swap" data-title>Optimize storage</span></h2>
          <p class="df__meta"><span class="df__swap" data-meta>128 GB · 115 fragments</span></p>
        </div>
        <p class="df__figure" aria-hidden="true">
          <span class="df__pct" data-pct>0%</span>
          <svg class="df__tick" viewBox="0 0 28 28" data-tick><path d="M6.5 14.8l5 5 10-11.4" pathLength="1"/></svg>
        </p>
      </div>

      <div class="df__grid" role="progressbar" aria-labelledby="df-title" aria-valuemin="0" aria-valuemax="100"
           aria-valuenow="0" aria-valuetext="Not started" data-bar>
        <canvas class="df__canvas" aria-hidden="true" data-grid></canvas>
      </div>

      <p class="df__legend" aria-label="What is stored">
        <span class="df__kind" style="--kind: var(--system)"><span>System</span> <b data-size="system">11 GB</b></span>
        <span class="df__kind" style="--kind: var(--apps)"><span>Apps</span> <b data-size="apps">23 GB</b></span>
        <span class="df__kind" style="--kind: var(--photos)"><span>Photos</span> <b data-size="photos">35 GB</b></span>
        <span class="df__kind" style="--kind: var(--docs)"><span>Files</span> <b data-size="docs">15 GB</b></span>
        <span class="df__kind df__kind--cache" style="--kind: var(--cache-ink)"><span>Cache</span> <b data-size="cache">2.4 GB</b></span>
      </p>

      <div class="df__foot">
        <span class="df__status"><span class="df__swap" data-status>Last optimized 3 months ago</span></span>
        <button class="pill" type="button" data-btn data-autoclic>
          <span class="pill__fill" aria-hidden="true"></span>
          <span class="pill__label" data-label>Optimize</span>
        </button>
      </div>
      <p class="sr" role="status" aria-live="polite" data-live></p>
    </section>
  </main>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
  <script src="script.js"></script>
</body>
</html>

Playground

Cambia valori, colori e testi con le manopole e guarda l’animazione rispondere dal vivo. Oppure scrivi tu nel codice. Poi scarica la cartella con le tue modifiche.

53 valori da cambiare

Oppure chiedila a Claude Code

Col connettore di Animorio, Claude Code la prende da qui con tutta la sua guida e la adatta al tuo progetto. Incolla questa richiesta:

Prendi «Il deframmentatore della memoria» da Animorio e adattala al mio sito

Cosa fa

Su un fondo bianco, da solo al centro: in alto Optimize storage e sotto, piccolo, 128 GB · 115 fragments, a destra 0% in un carattere monospaziato stretto; sotto, una griglia di 24 per 10 posti con gli angoli tondi, i posti liberi disegnati a filo e gli altri pieni: neri per il sistema, blu per le app, arancio per le foto, sabbia per i documenti, e la cache a righe diagonali, tutti mescolati come li lasciano anni di uso. Sotto la griglia la legenda in cinque colonne, ogni nome nel colore del suo tipo e il suo peso in gigabyte, poi Last optimized 3 months ago e la pillola nera Optimize. Entrando, i blocchi cadono nei loro posti con un piccolo rimbalzo, in un’onda in diagonale. Premuto Optimize, i blocchi ancora fuori posto diventano pallidi, una cornice sottile si posa sul primo posto e la cache sparisce blocco dopo blocco, stringendosi su sé stessa, nell’ordine in cui si legge una pagina, mentre il suo peso scende a 0 GB e la parola Cache si cancella con una riga. Poi la cornice cammina sulla griglia: per ogni posto il blocco che ci va viene sollevato, cresce di metà, fa un arco con la sua ombra e atterra schiacciandosi un poco e tornando su con una molla, e il blocco che stava lì vola via nell’arco opposto. I voli si sovrappongono, quindi c’è sempre un piccolo stormo di blocchi in aria; i blocchi arrivati prendono il colore pieno, così la parte ordinata cresce come una barra di avanzamento, prima il nero, poi il blu, l’arancio e la sabbia, e i frammenti contati in alto scendono. Durante il lavoro la pillola diventa un anello con Pause: la cornice si ferma, Resume riparte. Una volta su due un file è aperto: il blocco si alza, trema e resta su con un bordo rosso, il titolo dice in rosso Could not move a file e sotto Notes.app is using it; Retry lo fa volare e il lavoro continua. Alla fine lo spazio libero è tutto in un pezzo in fondo, un’onda gonfia i blocchi dall’angolo in alto a sinistra, la percentuale lascia il posto a una spunta verde che si disegna, il titolo dice Storage optimized e in basso 2.4 GB freed. Optimize again rimanda ogni blocco al suo posto di partenza in una grande nuvola di voli, la cache ricompare e tutto torna com’era.

Come funziona

Il disordine col seme

I blocchi di ogni tipo (quanti, lo dice MIX) e i posti vuoti si mescolano con un generatore pseudocasuale col seme (il moltiplicativo di Park e Miller), quindi il disordine è sempre lo stesso e il giro dell’anteprima si ripete identico. Due passate scambiano qualche blocco isolato con il vicino uguale: il disordine vero di un disco ha piccoli gruppi, non è rumore puro. Ogni blocco ricorda il suo posto di partenza, dove torna con Optimize again.

Il piano prima del movimento

Come un deframmentatore vero, il lavoro si calcola prima su una copia della griglia: prima si cancella la cache, poi per ogni posto, in ordine, si guarda quale tipo ci deve stare (sistema, app, foto, documenti); se c’è già il blocco giusto si tiene, se no si prende il più vicino dopo quel posto e il blocco che stava in mezzo va dove era lui. Ogni operazione ha un peso (un volo 1, una cancellazione 0,16, un blocco già a posto 0,12) e quindi il suo istante nel lavoro, da 0 a 1.

Un orologio che suona il piano

Durante il lavoro un orologio avanza nel ticker di GSAP (il passo è al massimo 1/30 di secondo) e fa partire ogni operazione quando passa il suo istante: la percentuale è l’orologio stesso. La pausa ferma l’orologio e lascia finire i voli in aria; il file aperto è la prima operazione di volo dopo FAIL, che ferma l’orologio finché Retry non la fa partire.

Il volo ad arco

Un blocco vola lungo la retta fra i due posti più una spinta di lato, sin(πt) per un’altezza che cresce con la distanza, e i due blocchi di uno scambio piegano da parti opposte, così si incrociano senza coprirsi. In cima all’arco il blocco è più grande di LIFT e ha un’ombra che si allarga; atterrando si schiaccia in larghezza e in altezza con un elastic.out e torna con un assestamento. Le posizioni stanno in celle e non in pixel, quindi se la finestra cambia misura a metà volo il disegno si rifà e niente salta.

Il disegno sul canvas

Tutto è un canvas più grande della griglia di dodici pixel per lato, perché un blocco in aria non sia mai tagliato: prima i posti a filo, poi i blocchi a terra, poi quelli in aria dal più basso al più alto, poi la cornice. Il pallore di un blocco fuori posto è la sua trasparenza, la cache è tratteggiata con un clip. Quando niente si muove e il lavoro è fermo il ciclo esce dal ticker e non ridisegna niente.

Valori da cambiare

NomeFileDi partenzaCosa cambia
GRIDscript.js[24, 10]Colonne e righe della griglia di blocchi.
MIXscript.js{ system: 18, apps: 38, photos: 62, docs: 30, cache: 28 }Quanti blocchi di ogni tipo; il resto della griglia è spazio libero (almeno un quinto resta libero).
CACHE_GBscript.js2.4Quanto pesa la cache che viene cancellata.
SECONDSscript.js7Quanti secondi dura un’ottimizzazione nella demo.
GAPscript.js2Lo spazio fra due blocchi, in pixel.
ROUNDscript.js0.22L’angolo tondo di un blocco, come parte del suo lato.
LIFTscript.js0.55Quanto cresce un blocco in cima al suo volo.
ARCscript.js0.32Quanto è alto l’arco di un volo, come parte della sua lunghezza.
FLIGHTscript.js0.6Quanto dura un volo, in secondi.
SEEDscript.js11Il disordine di partenza: un altro numero, un altro disordine.
FAIL_EVERYscript.js2Un’ottimizzazione ogni quante trova un file aperto (0 mai).
FAILscript.js0.58Dove si trova il file aperto, da 0 a 1.
PREVIEWscript.js1.45Nel giro dell’anteprima: quante volte più veloce.
LABELSscript.js['Optimize', 'Pause', 'Resume', 'Retry', 'Optimize again']Le parole della pillola, stato per stato.
--photosstyle.css#ff7442Il colore dei blocchi delle foto.
--appsstyle.css#4f56e8Il colore dei blocchi delle app.

Provali nel Playground

Quando usarla

Per l’ottimizzazione o la pulizia della memoria in un’app per il telefono o il computer, per un antivirus o un pulitore, per la compattazione di un archivio o di un database in una dashboard, per ogni lavoro lungo che mette in ordine tante piccole cose.

Sul telefono

Il pannello prende tutta la larghezza meno i margini e la griglia si rimpicciolisce con lui: ha sempre 24 colonne, con i blocchi più piccoli. I voli sono gli stessi, perché le posizioni stanno in celle; la legenda resta su cinque colonne. La pillola risponde al tocco come al mouse.

Con il movimento ridotto

Niente vola: un blocco che cambia posto si spegne dov’era e si accende dove va, la cache si spegne invece di stringersi, la cornice salta da un posto all’altro e non c’è l’onda finale. Il colore pieno dei blocchi a posto, la percentuale e la spunta restano.

Trappole

  • Il nome dell’elenco dei posti di partenza era lo stesso della funzione che fa partire il lavoro: lo script non partiva nemmeno. Ora l’elenco si chiama scatter.
  • Tornando a riposo i blocchi volavano in archi alti che uscivano dal canvas e venivano tagliati in cima alla griglia: ora la posizione in volo resta dentro la griglia, e il canvas sborda di dodici pixel per lato per l’ombra e la crescita.
  • La legenda in una riga sola andava a capo a metà e la parola Cache finiva da sola sotto: ora sono cinque colonne con il peso sotto il nome, che stanno anche a 390 pixel.
  • La riga che cancella Cache passava anche sul suo peso, perché la decorazione del testo scende nei figli a blocco: ora la riga è sulla sola parola, in un suo span.
  • Il blocco del file aperto restava pallido come i blocchi fuori posto e il bordo rosso si vedeva poco: quando si blocca prende il suo colore pieno.

Librerie

GSAP 3.15.0, Martian Mono (font variabile, asse wdth) 5.3.0.

Compressi con gzip, i tre file della demo pesano 11 KB; le librerie: GSAP 28 KB.

Collaudo

Provata il 19 ottobre 2026

  • Computer: Fatto
  • Telefono: Fatto
  • Movimento ridotto: Fatto
  • Safari su iPhone: Da fare

Licenza d’uso

Puoi usarla nei tuoi progetti e in quelli dei tuoi clienti. Non puoi rivenderla né ridistribuirla così com’è. GSAP resta sotto la sua licenza Standard. Licenza completa.

Tutti i componenti