
Il pulsante da far scorrere
Pulsanti, Fisica, Transizioni
NuovaGratis
La palette dei comandi ⌘K di un editor di progetti, fluida come in un’app nativa: a riposo è una pillola Search or jump to… col suo tasto disegnato, e premendola (o con ⌘K, Ctrl K) la pillola stessa si allarga e diventa la palette. Scrivendo i comandi si filtrano con un punteggio fuzzy, quelli che restano scivolano al loro posto e le lettere trovate si accendono; la fascia sotto la riga scelta scivola su una molla. Un comando con altro dentro apre la sua pagina: quella di prima arretra in profondità sfocandosi, e in alto compaiono le briciole. Sulla pagina dei temi, passando su un tema la palette lo indossa subito.
Una cartella che funziona da sola: index.html, style.css, script.js e le librerie da CDN. Nelle schede React e Vue la stessa demo è già un componente, che spegne le sue animazioni quando esce dalla pagina.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>The command menu</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist@5.3.0/index.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource-variable/geist-mono@5.3.0/index.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<main class="stage">
<!-- the command menu of a project editor. At rest a search pill with its shortcut drawn as two little keys;
pressed (or with Cmd K / Ctrl K) the pill itself grows into the palette. Typing filters the commands, the
ones left slide to their places, the letters found light up; a command with more inside opens its own page,
the page before sinking back behind it. The rows are made by the script from the list in script.js -->
<div class="cmdk" data-cmdk data-autoclic>
<div class="cmdk__shell" data-shell>
<button class="cmdk__pill" type="button" aria-haspopup="dialog" aria-expanded="false" aria-controls="cmdk-dialog" aria-keyshortcuts="Meta+K Control+K" data-pill>
<svg class="cmdk__lens" viewBox="0 0 24 24" aria-hidden="true"><path d="M10.5 4.5a6 6 0 1 0 0 12a6 6 0 1 0 0-12zM15 15l4.5 4.5"/></svg>
<span class="cmdk__pilltext" data-pilltext>Search or jump to…</span>
<span class="cmdk__keys" aria-hidden="true"><kbd class="cmdk__key" data-mod>⌘</kbd><kbd class="cmdk__key">K</kbd></span>
</button>
<div class="cmdk__dialog" id="cmdk-dialog" role="dialog" aria-modal="true" aria-label="Command menu" data-dialog hidden>
<div class="cmdk__head">
<svg class="cmdk__lens" viewBox="0 0 24 24" aria-hidden="true"><path d="M10.5 4.5a6 6 0 1 0 0 12a6 6 0 1 0 0-12zM15 15l4.5 4.5"/></svg>
<nav class="cmdk__crumbs" aria-label="Where you are in the menu" data-crumbs></nav>
<input class="cmdk__input" type="text" role="combobox" aria-expanded="true" aria-autocomplete="list" aria-label="Search commands" autocomplete="off" autocapitalize="off" spellcheck="false" enterkeyhint="go" placeholder="Search or jump to…" data-input>
<kbd class="cmdk__key cmdk__key--esc" aria-hidden="true">esc</kbd>
</div>
<div class="cmdk__body" data-body></div>
<div class="cmdk__foot" aria-hidden="true">
<span class="cmdk__tip"><kbd class="cmdk__key cmdk__key--icon"><svg viewBox="0 0 24 24"><path d="M12 18V6M7 11l5-5 5 5"/></svg></kbd><kbd class="cmdk__key cmdk__key--icon"><svg viewBox="0 0 24 24"><path d="M12 6v12M7 13l5 5 5-5"/></svg></kbd>Move</span>
<span class="cmdk__tip"><kbd class="cmdk__key cmdk__key--icon"><svg viewBox="0 0 24 24"><path d="M19 5v7.5H6M10 8.5l-4 4 4 4"/></svg></kbd>Open</span>
<span class="cmdk__tip" data-backtip><kbd class="cmdk__key cmdk__key--icon"><svg viewBox="0 0 24 24"><path d="M9 6h11v12H9l-5.5-6z"/></svg></kbd>Back</span>
</div>
</div>
</div>
<p class="sr" role="status" aria-live="polite" data-live></p>
</div>
</main>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.15.0/dist/Flip.min.js"></script>
<script src="script.js"></script>
</body>
</html>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.
25 valori da cambiare
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 menu dei comandi» da Animorio e adattala al mio sitoLa pillola e la palette sono lo stesso elemento: un riquadro col fondo, il bordo e l’ombra, di cui GSAP muove posizione, larghezza, altezza e raggio degli angoli dalla misura della pillola a quella del pannello (expo.out). Dentro ci sono il pulsante della pillola, ancorato in alto, e la finestra di dialogo: la prima svanisce in 0,12 secondi, la seconda compare subito dopo, col campo nello stesso punto dove stava la scritta, così sembra che la pillola si sia aperta. Chiudendo, lo stesso al contrario.
Ogni lettera scritta deve comparire nell’etichetta, in ordine. Per ogni punto di partenza possibile si calcola un punteggio: uno per lettera, tre in più se è attaccata alla precedente, quattro se comincia una parola, quattro se la corrispondenza comincia l’etichetta, e un poco in meno per i buchi; vince la migliore, e le sue posizioni diventano i <mark> viola. Le parole nascoste di ogni comando (dark, appearance…) lo trovano anche se l’etichetta non combacia, con un punteggio più basso.
Prima di filtrare Flip fotografa righe e titoli dei gruppi; poi si nascondono quelle che non c’entrano e Flip.from le fa scivolare dalla vecchia posizione alla nuova. Le righe tengono il loro ordine, così si muovono solo dentro lo spazio lasciato libero e non si sovrappongono mai; la fascia va sul punteggio migliore. Le righe che ritornano aspettano metà della corsa delle altre prima di comparire, e l’altezza del pannello si misura dall’ultima riga (non da scrollHeight, che conta anche le righe ancora spostate).
La fascia sotto la riga scelta è un solo elemento nella lista: la sua posizione e la sua altezza sono due molle (BAND) che inseguono la riga, integrate a passi di 1/240 di secondo; l’altezza ha una molla più morbida e cresce un poco con la velocità, così la fascia si allunga in corsa e si riassesta all’arrivo. Quando arriva, il ciclo si ferma.
Ogni pagina ha la sua lista (role listbox) sovrapposta alle altre. Andando avanti la pagina di prima si rimpicciolisce di DEPTH, sale di quattro pixel, si sfoca di BLUR pixel e svanisce, mentre la nuova arriva da un poco più grande e sfocata e si mette a fuoco; tornando indietro il contrario. Il campo prende le briciole (pulsanti veri per tornare), un segnaposto nuovo e la ricerca di ogni pagina resta salvata per quando si torna.
Il campo è un combobox con aria-controls sulla lista della pagina e aria-activedescendant sulla riga scelta; le righe sono option con aria-selected. La finestra è un dialog modale: Tab gira solo fra le briciole e il campo, Esc chiude e il fuoco torna alla pillola. Un annuncio dice quanti risultati ci sono e cosa ha fatto il comando.
| Nome | File | Di partenza | Cosa cambia |
|---|---|---|---|
PILL | script.js | 300 | La larghezza della pillola a riposo, in pixel. |
OPEN | script.js | 0.55 | I secondi del passaggio dalla pillola alla palette. |
DEPTH | script.js | 0.06 | Quanto arretra una pagina dietro la successiva (0,06 = il 6% più piccola). |
BLUR | script.js | 6 | Quanto è sfocata la pagina dietro, in pixel. |
SLIDE | script.js | 0.4 | I secondi che le righe impiegano a scivolare al loro posto mentre si scrive. |
BAND | script.js | [520, 36] | La molla della fascia sotto la riga scelta: rigidità e smorzamento. |
SHORTCUT | script.js | 'k' | Il tasto che la apre insieme a ⌘ (Mac) o Ctrl. |
Per un’app con molte azioni e pagine: un editor, un pannello di amministrazione, uno strumento per sviluppatori o per squadre, la documentazione di un prodotto. Le pagine interne servono per le scelte con più opzioni (tema, progetto, lingua, persona a cui assegnare); i comandi e i gruppi si cambiano nell’elenco in cima allo script.
Il riquadro prende la larghezza dello schermo meno 32 pixel; la pillola resta di 300. La riga dei suggerimenti in fondo e il tasto esc spariscono (sul telefono non c’è tastiera fisica), le righe restano alte 42 pixel per il dito, la lista scorre col dito dentro il pannello senza far scorrere la pagina, e un tocco fuori la chiude.
Niente morph né profondità: la palette compare in dissolvenza già della sua misura e la pillola sparisce subito; le pagine si scambiano con una dissolvenza, senza scala né sfocatura. Le righe filtrate vanno subito al loro posto e la fascia salta sulla riga scelta. Tutto il resto, tastiera, temi, briciole, funziona uguale.
GSAP 3.15.0, Flip (GSAP) 3.15.0, Geist (font variabile) 5.3.0, Geist Mono (font variabile) 5.3.0.
Compressi con gzip, i tre file della demo pesano 13 KB; le librerie: GSAP + Flip 37 KB.
Provata il 5 ottobre 2026
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.
Con l’email e la password del tuo account.
oppure con l’email
Hai fatto l’accesso come .
Con l’account scarichi lo zip di ogni animazione e di ogni pacchetto, gratis.