531 lines
25 KiB
Markdown
531 lines
25 KiB
Markdown
# 03 — Interattività e Coinvolgimento
|
||
|
||
> Come trasformare l'assegnazione di ~20 persone a un set di stanze in uno **spettacolo condiviso**
|
||
> in stile scommesse / game-show / slot machine, guardato tutti insieme su un unico schermo.
|
||
|
||
Questo documento raccoglie idee di game design, meccaniche di gamification, sound design,
|
||
momenti di celebrazione e soluzioni tecniche concrete (con nomi di librerie e URL CDN reali)
|
||
per rendere la web app **massimamente divertente e coinvolgente**.
|
||
|
||
---
|
||
|
||
## 1. Il principio di base: l'attesa vale più del premio
|
||
|
||
La ricerca sul gambling e sui game-show è concorde: **l'anticipazione conta più del risultato**.
|
||
Il rilascio di dopamina è massimo *nei momenti che precedono* la rivelazione, non nella rivelazione
|
||
stessa. I "reward" imprevedibili (variable ratio reward schedule) generano una risposta emotiva
|
||
molto più forte di quelli prevedibili.
|
||
|
||
Implicazioni di design per la nostra app:
|
||
|
||
- **Non rivelare tutto insieme.** Diluire l'assegnazione nel tempo (una persona / una stanza alla
|
||
volta) moltiplica i picchi di tensione.
|
||
- **Rallentare proprio prima del risultato.** Come la ruota della fortuna che decelera: gli ultimi
|
||
secondi prima dello "stop" sono quelli che valgono.
|
||
- **Sfruttare il "quasi-vinto" (near-miss).** Far vedere che qualcuno stava per finire nella "stanza
|
||
VIP" ma poi... no. Il near-miss tiene il cervello in stato di attesa e alza l'engagement di tutta
|
||
la sala.
|
||
- **Incertezza come feature, non come bug.** Non mostrare mai l'esito prima del tempo; la sorpresa è
|
||
il prodotto.
|
||
|
||
Questi principi guidano tutte le sezioni successive.
|
||
|
||
---
|
||
|
||
## 2. Meccaniche di engagement e gamification
|
||
|
||
### 2.1 Suspense e reveal sociale
|
||
|
||
- **Reveal una persona alla volta**: il nome della persona appare, parte lo "spin", e solo dopo si
|
||
scopre la stanza. Ogni singola assegnazione diventa un micro-evento.
|
||
- **Spinning wheel / slot reel come metafora principale**: la ruota/rullo che gira e decelera è una
|
||
delle meccaniche di suspense più efficaci perché il pubblico *vede tutti gli esiti possibili*
|
||
scorrere davanti e può "tifare" per uno di essi.
|
||
- **Ordine di rivelazione studiato per il dramma** (vedi §6): non alfabetico, ma costruito a
|
||
crescendo.
|
||
- **Countdown visibile** (3… 2… 1…) prima di ogni spin, con drumroll audio e vibrazione.
|
||
|
||
### 2.2 Scommesse / pronostici prima del reveal (il cuore "gambling")
|
||
|
||
Prima che l'algoritmo riveli le assegnazioni, si apre una **finestra di pronostici**:
|
||
|
||
- Ogni partecipante (o la sala a mano alzata, in modalità single-screen) prova a indovinare
|
||
**in quale stanza finirà una data persona**.
|
||
- Si possono mostrare **quote/odds** fittizie accanto a ogni stanza ("Stanza VIP paga 5x", "Stanza
|
||
Sgabuzzino paga 1.2x") per dare sapore da sala scommesse e orientare l'ironia del gruppo.
|
||
- **Punti / gettoni virtuali** da puntare: chi indovina di più sale in classifica.
|
||
- Il momento della rivelazione diventa doppiamente teso: non scopri solo dove va la persona, ma
|
||
anche *se hai vinto la scommessa*.
|
||
|
||
Questa meccanica sfrutta esattamente la psicologia dell'incertezza del premio: la posta in gioco
|
||
personale amplifica l'attenzione di tutti.
|
||
|
||
### 2.3 Leaderboard e classifiche
|
||
|
||
- **Classifica pronosticatori**: chi ha indovinato più assegnazioni.
|
||
- Aggiornamento **live dopo ogni reveal**, con animazione di scalata (righe che si riordinano).
|
||
- Ranking individuale e/o a squadre; le squadre aumentano il tifo e le esultanze collettive.
|
||
- La leaderboard è essa stessa un momento di spettacolo: mostrarla a schermo intero tra un blocco di
|
||
reveal e l'altro.
|
||
|
||
### 2.4 Reazioni, emoji e tifo
|
||
|
||
- **Emoji reactions in tempo reale** che volano sullo schermo condiviso (🎉 😱 🔥 👑 💀) quando esce
|
||
un'assegnazione clamorosa.
|
||
- Se i telefoni sono connessi (vedi §7), i partecipanti "lanciano" emoji dal telefono e appaiono
|
||
sul proiettore.
|
||
- In modalità puramente single-screen: reazioni scatenate da tasti/hotkey dell'MC, o semplicemente
|
||
dal tifo dal vivo amplificato dagli effetti audio/visivi.
|
||
|
||
### 2.5 Streak e momenti speciali
|
||
|
||
- **Streak del pronosticatore**: 3 assegnazioni indovinate di fila → effetto "on fire" 🔥 con audio
|
||
e confetti dedicati.
|
||
- **Streak di stanza**: se la stessa stanza riceve N persone di fila → "HOT ROOM" con luci
|
||
lampeggianti.
|
||
- **Combo/moltiplicatori**: più la streak è lunga, più i punti valgono (moltiplicatore visibile che
|
||
sale), come nei giochi arcade.
|
||
|
||
### 2.6 Feedback game-show generale
|
||
|
||
- **MC / annunciatore** (testo + audio): battute pre-scritte a tema per ogni tipo di reveal (vedi §6.4).
|
||
- **Barra di "hype"** che si riempie con le reazioni della sala.
|
||
- **Achievement/badge** sbloccabili ("Primo Jackpot", "Cappotto di pronostici", "Sfortunato del
|
||
giorno").
|
||
|
||
---
|
||
|
||
## 3. Sound design
|
||
|
||
Il suono è metà dello spettacolo. Serve un piccolo **kit di effetti** riutilizzabili.
|
||
|
||
### 3.1 Gli effetti chiave da avere
|
||
|
||
| Momento | Suono | Quando parte |
|
||
|---|---|---|
|
||
| Avvio spin | *whoosh* / rullo che accelera | inizio dell'animazione della slot/ruota |
|
||
| Rotazione | tick-tick-tick dei rulli | durante lo spin (loop) |
|
||
| Decelerazione | ticchettio che rallenta | ultimi secondi prima dello stop |
|
||
| Assegnazione normale | *ding* / campanello | quando si ferma su una stanza |
|
||
| Stanza VIP / jackpot | *jackpot* + monete che cadono (coin drop) | reveal di una stanza speciale |
|
||
| Pre-reveal drammatico | *drumroll* (rullo di tamburi) | durante il countdown 3-2-1 |
|
||
| Vittoria / grande momento | *crowd cheer* (folla che esulta) | jackpot, fine evento, streak |
|
||
| Errore / near-miss | *buzz* / *sad trombone* | quando un pronostico fallisce |
|
||
| Cambio schermata | *swoosh* UI | transizioni tra i blocchi |
|
||
|
||
### 3.2 Dove trovare effetti sonori GRATIS (royalty-free)
|
||
|
||
Tutte fonti utilizzabili in progetti personali e commerciali (verificare la licenza del singolo file).
|
||
|
||
**Mixkit** — nessuna registrazione, uso libero personale e commerciale:
|
||
- Slot machine: <https://mixkit.co/free-sound-effects/slot-machine/>
|
||
- Casino: <https://mixkit.co/free-sound-effects/casino/>
|
||
- Utili qui: reel spin, coin drop, big win jingle.
|
||
|
||
**Pixabay** — royalty-free, nessuna attribuzione richiesta, download MP3:
|
||
- Slot machine: <https://pixabay.com/sound-effects/search/slot-machine/>
|
||
- Slot spin: <https://pixabay.com/sound-effects/search/slot%20spin/>
|
||
- Jackpot: <https://pixabay.com/sound-effects/search/jackpot/>
|
||
- Casino: <https://pixabay.com/sound-effects/search/casino/>
|
||
- Per gli altri effetti cercare: `drumroll`, `applause` / `crowd cheer`, `coin`, `ding`, `buzzer`,
|
||
`whoosh`.
|
||
|
||
**Freesound** — database collaborativo Creative Commons (attenzione: alcuni file richiedono
|
||
attribuzione, controllare la licenza CC0 vs CC-BY):
|
||
- Home / ricerca: <https://freesound.org/>
|
||
- Esempio pack slot machine: <https://freesound.org/people/lukaso/packs/4497/>
|
||
|
||
Suggerimento pratico: scaricare gli MP3, **normalizzare i volumi** (un jackpot troppo forte rispetto
|
||
al ding rovina l'esperienza) e tenerli in una cartella `assets/audio/` con nomi parlanti
|
||
(`spin.mp3`, `ding.mp3`, `jackpot.mp3`, `drumroll.mp3`, `coin.mp3`, `cheer.mp3`, `buzz.mp3`).
|
||
|
||
### 3.3 Come far partire i suoni nel browser
|
||
|
||
Due strade: `<audio>` semplice, oppure la **Web Audio API** / **Howler.js** per controllo fine e
|
||
niente latenza.
|
||
|
||
**Attenzione all'autoplay policy.** I browser (da Chrome 71 in poi) **bloccano l'audio finché non
|
||
c'è un'interazione utente**. Un `AudioContext` creato prima di un gesto utente nasce in stato
|
||
`suspended`. Va **sbloccato al primo click/tap** (es. il bottone "Inizia lo show") chiamando
|
||
`resume()`. Best practice: un unico "gesto di sblocco" all'avvio dell'evento.
|
||
|
||
Sblocco base con Web Audio API:
|
||
|
||
```javascript
|
||
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
||
|
||
// da chiamare dentro un handler di click/tap (es. bottone "Avvia lo show")
|
||
function unlockAudio() {
|
||
if (audioCtx.state === 'suspended') {
|
||
audioCtx.resume();
|
||
}
|
||
}
|
||
document.querySelector('#start-btn').addEventListener('click', unlockAudio, { once: true });
|
||
```
|
||
|
||
**Howler.js** (consigliato: gestisce autoplay, sprite audio, volumi, fallback HTML5 in automatico).
|
||
|
||
CDN:
|
||
```html
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.4/howler.min.js"></script>
|
||
```
|
||
|
||
Uso:
|
||
```javascript
|
||
const sfx = {
|
||
spin: new Howl({ src: ['assets/audio/spin.mp3'], volume: 0.6 }),
|
||
ding: new Howl({ src: ['assets/audio/ding.mp3'] }),
|
||
jackpot: new Howl({ src: ['assets/audio/jackpot.mp3'], volume: 0.9 }),
|
||
drumroll: new Howl({ src: ['assets/audio/drumroll.mp3'] }),
|
||
coin: new Howl({ src: ['assets/audio/coin.mp3'] }),
|
||
cheer: new Howl({ src: ['assets/audio/cheer.mp3'] }),
|
||
buzz: new Howl({ src: ['assets/audio/buzz.mp3'] }),
|
||
};
|
||
|
||
// esempio: sequenza di un reveal
|
||
sfx.drumroll.play();
|
||
// ...al momento dello stop
|
||
sfx.ding.play();
|
||
```
|
||
|
||
Perché Howler: parte da ~7KB gzipped, usa Web Audio con **fallback su HTML5 Audio**, supporta
|
||
**audio sprite** (utile per impacchettare tutti gli effetti in un solo file e ridurre le richieste)
|
||
e semplifica volumi/fade. Docs: <https://howlerjs.com/>.
|
||
|
||
---
|
||
|
||
## 4. Momenti di celebrazione (celebration UX)
|
||
|
||
Gli effetti visivi trasformano un reveal in un evento memorabile. La regola d'oro: **scalare
|
||
l'intensità dell'effetto in base all'importanza del momento** (assegnazione normale = piccolo puff;
|
||
jackpot VIP = tutto lo schermo esplode).
|
||
|
||
### 4.1 Confetti — `canvas-confetti`
|
||
|
||
Libreria leggera (< 10KB gzip), performante, esposta come funzione globale `confetti()`.
|
||
|
||
CDN:
|
||
```html
|
||
<script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.4/dist/confetti.browser.min.js"></script>
|
||
<!-- alternativa cdnjs -->
|
||
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/canvas-confetti/1.9.3/confetti.min.js"></script> -->
|
||
```
|
||
|
||
**Burst semplice** (assegnazione normale):
|
||
```javascript
|
||
confetti({ particleCount: 120, spread: 70, origin: { y: 0.6 } });
|
||
```
|
||
|
||
**Fireworks / fuochi d'artificio** (jackpot, fine evento) — due getti laterali ripetuti:
|
||
```javascript
|
||
const duration = 4 * 1000;
|
||
const end = Date.now() + duration;
|
||
(function frame() {
|
||
confetti({ particleCount: 7, angle: 60, spread: 55, origin: { x: 0 } });
|
||
confetti({ particleCount: 7, angle: 120, spread: 55, origin: { x: 1 } });
|
||
if (Date.now() < end) requestAnimationFrame(frame);
|
||
}());
|
||
```
|
||
|
||
**Confetti a emoji/testo** (es. 👑 per la stanza VIP):
|
||
```javascript
|
||
const crown = confetti.shapeFromText({ text: '👑', scalar: 2 });
|
||
confetti({ shapes: [crown], scalar: 2, particleCount: 40, spread: 100 });
|
||
```
|
||
|
||
Opzioni utili: `particleCount`, `spread`, `angle`, `startVelocity`, `gravity`, `colors` (array HEX),
|
||
`shapes` (`square`/`circle`/`star`/custom), `origin.x/.y`, `scalar`, `ticks`.
|
||
**Accessibilità**: usare `disableForReducedMotion: true` per rispettare chi preferisce meno
|
||
animazioni.
|
||
|
||
Demo/preset ufficiali (fireworks, snow, school pride, ecc.): <https://www.kirilv.com/canvas-confetti/>
|
||
|
||
Alternativa con supporto emoji nativo: **js-confetti** — <https://github.com/loonywizard/js-confetti>.
|
||
|
||
### 4.2 Screen shake, flash e luci lampeggianti
|
||
|
||
Effetti CSS/JS a basso costo, molto d'impatto sullo schermo grande:
|
||
|
||
```css
|
||
@keyframes shake {
|
||
0%,100% { transform: translate(0,0); }
|
||
20% { transform: translate(-8px, 4px); }
|
||
40% { transform: translate(8px, -4px); }
|
||
60% { transform: translate(-6px, -6px); }
|
||
80% { transform: translate(6px, 6px); }
|
||
}
|
||
.shake { animation: shake 0.4s ease-in-out; }
|
||
|
||
@keyframes flash {
|
||
0%,100% { background: transparent; }
|
||
50% { background: rgba(255,255,255,0.85); }
|
||
}
|
||
.flash { animation: flash 0.15s ease-in-out 3; } /* triplo flash */
|
||
```
|
||
|
||
- **Screen shake** sul reveal del jackpot (aggiungere/rimuovere la classe `.shake` sul container).
|
||
- **Flash bianco** al momento dello "stop" della slot.
|
||
- **Luci lampeggianti** in stile casinò: bordo dello schermo con luci che corrono
|
||
(box-shadow animato o una fila di "bulbi" attorno al frame).
|
||
|
||
### 4.3 Winner spotlight (riflettore sul vincitore)
|
||
|
||
Al reveal di una persona in stanza speciale, o del "vincitore" dei pronostici:
|
||
|
||
- **Oscurare lo sfondo** (overlay scuro) e lasciare un **cono di luce/riflettore** (radial-gradient)
|
||
sul nome/foto della persona.
|
||
- **Zoom-in + pop** dell'elemento (scala da 0.8 a 1.1 e ritorno) con anime.js o CSS.
|
||
- Nome grande, corona/badge, confetti a corona (§4.1) e crowd cheer (§3).
|
||
|
||
### 4.4 Anime.js per orchestrare le animazioni
|
||
|
||
Per sequenze complesse (countdown → spin → stop → celebrazione) conviene una **timeline**.
|
||
|
||
CDN:
|
||
```html
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js"></script>
|
||
```
|
||
|
||
Esempio di reveal a più elementi con **stagger** (le lettere/righe che appaiono a cascata):
|
||
```javascript
|
||
anime({
|
||
targets: '.reveal-letter',
|
||
translateY: [40, 0],
|
||
opacity: [0, 1],
|
||
delay: anime.stagger(60), // 60ms tra un elemento e l'altro
|
||
easing: 'easeOutBack'
|
||
});
|
||
```
|
||
|
||
Anime.js gestisce timeline, keyframes, easing e staggering: ideale per sincronizzare animazione
|
||
visiva e cue audio. Docs: <https://animejs.com/documentation/>.
|
||
|
||
---
|
||
|
||
## 5. Haptics / feedback su mobile (`navigator.vibrate`)
|
||
|
||
Se i partecipanti tengono il telefono in mano (modalità connessa, §7), la **vibrazione** aggiunge un
|
||
canale sensoriale al reveal.
|
||
|
||
API base:
|
||
```javascript
|
||
// vibrazione singola (ms)
|
||
navigator.vibrate(200);
|
||
|
||
// pattern: [vibra, pausa, vibra, ...]
|
||
navigator.vibrate([100, 50, 100]); // doppio buzz "successo"
|
||
navigator.vibrate([300, 100, 300, 100, 300]); // jackpot
|
||
```
|
||
|
||
Idee d'uso:
|
||
- **Countdown**: micro-vibrazione a ogni tick (3-2-1).
|
||
- **Spin**: vibrazione continua/pulsata durante la rotazione.
|
||
- **Stop/assegnazione**: singolo buzz secco.
|
||
- **Pronostico indovinato**: doppio buzz "successo"; **fallito**: triplo buzz "errore".
|
||
- **Jackpot**: pattern lungo e ritmico.
|
||
|
||
Best practice (da MDN):
|
||
- Durate brevi: **50–200ms** sono ideali; una nuova `vibrate()` annulla la precedente, quindi
|
||
evitare chiamate a raffica.
|
||
- Va invocata dentro un **gesto utente** (sticky user activation): legarla a click/tap.
|
||
- **Additiva, mai unico canale di feedback**: offrire un toggle per disattivarla (c'è chi la odia o
|
||
non la percepisce).
|
||
|
||
Supporto: Chrome/Edge/Opera/Samsung Internet e Android. **Safari (iOS/macOS) non la supporta** e
|
||
**Firefox l'ha rimossa da v129**: fare feature-detection e degradare con grazia.
|
||
```javascript
|
||
if ('vibrate' in navigator) { navigator.vibrate(200); }
|
||
```
|
||
Riferimento: <https://developer.mozilla.org/en-US/docs/Web/API/Navigator/vibrate>
|
||
|
||
---
|
||
|
||
## 6. Idee specifiche per il reveal "persone → stanze"
|
||
|
||
Qui sta la vera anima dello spettacolo. Suggerimenti per rendere l'assegnazione un evento condiviso.
|
||
|
||
### 6.1 Struttura del reveal, una persona alla volta
|
||
|
||
1. Appare il **nome (e foto)** della persona di turno al centro.
|
||
2. Parte lo **spin** della slot/ruota con le stanze come simboli.
|
||
3. **Countdown 3-2-1** con drumroll + vibrazione.
|
||
4. La ruota **decelera** (near-miss: rallenta vicino a una stanza "clamorosa" e poi supera).
|
||
5. **Stop** su una stanza → *ding* / o *jackpot* se speciale → confetti scalati all'importanza.
|
||
6. Aggiornamento **leaderboard pronostici** e reazioni della sala.
|
||
|
||
### 6.2 Scommesse su chi va dove
|
||
|
||
- Prima del blocco, la sala pronostica: *"Dove finirà Marco?"*.
|
||
- **Quote/odds** mostrate accanto alle stanze per ironia e strategia.
|
||
- La rivelazione risolve due tensioni insieme (dove va Marco + chi ha indovinato).
|
||
|
||
### 6.3 Stanze speciali e "VIP room jackpot"
|
||
|
||
- Designare una o più stanze come **speciali**: "Stanza VIP" 👑, "Suite Presidenziale", oppure la
|
||
temutissima "Sgabuzzino" 💀.
|
||
- Quando qualcuno ci finisce → **trattamento jackpot**: full-screen fireworks, crowd cheer, coin
|
||
drop, screen shake, spotlight.
|
||
- Le stanze speciali possono avere **posti limitati** (scarsità = più tensione a ogni assegnazione:
|
||
"resta un solo posto VIP!").
|
||
- **Progressive jackpot**: una stanza "misteriosa" il cui contenuto/premio cresce a ogni reveal
|
||
finché non viene assegnata.
|
||
|
||
### 6.4 Ordine di rivelazione per il massimo dramma
|
||
|
||
- **Non alfabetico.** Costruire un crescendo: prima assegnazioni "normali", poi i colpi di scena.
|
||
- Tenere per **ultimi** i reveal più attesi (le stanze speciali, le persone-chiave, il pareggio di
|
||
una scommessa).
|
||
- Alternare ritmo: qualche reveal veloce di fila, poi uno **rallentato al massimo** con countdown
|
||
lungo.
|
||
- **Blocchi tematici** con schermate-ponte (leaderboard, "coming up next") per far respirare la
|
||
tensione e ripartire.
|
||
|
||
### 6.5 Testi da MC / annunciatore
|
||
|
||
Frasi pre-scritte (testo a schermo + eventuale TTS/audio) a seconda dell'esito. Esempi:
|
||
|
||
- Apertura: *"Signore e signori, benvenuti alla GRANDE ASSEGNAZIONE! 20 persone, X stanze, un solo
|
||
destino. Che la sorte decida!"*
|
||
- Pre-spin: *"Il prossimo concorrente è… MARCO. Dove lo manderà la ruota? Fate le vostre puntate!"*
|
||
- Near-miss: *"Ohhh! Era a un passo dalla Suite VIP… ma no!"*
|
||
- Assegnazione normale: *"E Marco va nella Stanza 3! Un applauso."*
|
||
- Jackpot: *"JACKPOT!!! Marco conquista la STANZA VIP! 👑 Che fortuna sfacciata!"*
|
||
- Sfortuna: *"Ahia… Sgabuzzino. Condoglianze, Marco. 💀"*
|
||
- Chiusura: *"E con questo le stanze sono assegnate! Applauso finale per tutti i concorrenti!"*
|
||
|
||
### 6.6 Reazioni ed emoji legate al reveal
|
||
|
||
- Set di emoji rapide (👑 😱 🔥 💀 🎉 👏) scatenabili dalla sala/telefoni al momento giusto.
|
||
- Contatore reazioni per rendere "virale" il momento in sala.
|
||
|
||
---
|
||
|
||
## 7. Multiplayer / schermo condiviso (anche senza backend)
|
||
|
||
Obiettivo: farlo funzionare bene **anche senza server**, con opzioni di upgrade se serve interazione
|
||
dai telefoni.
|
||
|
||
### 7.1 Modalità "single-screen / projector" (zero backend) — consigliata per partire
|
||
|
||
- **Un solo schermo** (proiettore o TV) mostra tutto lo show; l'MC guida con tastiera/telecomando.
|
||
- Tutta la logica gira **client-side** nel browser: l'assegnazione può essere pre-calcolata o
|
||
generata in loco, poi il reveal è pura animazione.
|
||
- I pronostici si fanno **a voce / a mano alzata**, l'MC li registra o semplicemente la sala tifa.
|
||
- Pro: nessuna infrastruttura, nessun rischio di rete, massima affidabilità in evento dal vivo.
|
||
- Il modello dei party game (Jackbox, Kahoot) conferma che *un solo schermo condiviso* è al centro
|
||
dell'esperienza collettiva; i telefoni sono solo controller opzionali.
|
||
|
||
### 7.2 Aggiungere i telefoni con un QR code
|
||
|
||
Come Jackbox.tv / Kahoot: a schermo appare un **QR code + codice stanza**; i partecipanti scansionano
|
||
e aprono una pagina "controller" nel browser (nessuna app da installare).
|
||
|
||
Generare il QR lato client:
|
||
```html
|
||
<script src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
|
||
<div id="qr"></div>
|
||
<script>
|
||
new QRCode(document.getElementById('qr'), 'https://tuo-dominio/join?room=AB12');
|
||
</script>
|
||
```
|
||
(libreria: **qrcodejs** — <https://github.com/davidshimjs/qrcodejs>)
|
||
|
||
### 7.3 Sincronizzazione telefoni ↔ schermo con backend minimale
|
||
|
||
Se vuoi che i pronostici/emoji dai telefoni appaiano in tempo reale sul proiettore, serve un piccolo
|
||
canale realtime. Opzioni leggere:
|
||
|
||
- **BroadcastChannel API** — *gratis, zero backend*, ma solo tra schede **dello stesso dispositivo/
|
||
browser** (utile per prototipare o per setup a più finestre sullo stesso PC). Non attraversa
|
||
dispositivi diversi.
|
||
- **WebSocket** su un piccolo server (Node) o servizio serverless.
|
||
- **Cloudflare Durable Objects** — ottimi per "stanze" realtime multiplayer con stato condiviso
|
||
(coordinamento di una room, WebSocket, stato per-stanza) senza gestire server tradizionali.
|
||
- Servizi realtime gestiti (es. Firebase Realtime Database / Firestore, Supabase Realtime) se si
|
||
preferisce non scrivere backend.
|
||
|
||
Raccomandazione: **partire single-screen (§7.1)**, aggiungere il **QR + controller** (§7.2) solo se
|
||
si vuole l'interazione dai telefoni, e introdurre un backend realtime **solo se** i pronostici live
|
||
diventano centrali.
|
||
|
||
---
|
||
|
||
## 8. Stack tecnico consigliato (riepilogo librerie e CDN)
|
||
|
||
| Scopo | Libreria | CDN |
|
||
|---|---|---|
|
||
| Confetti / fuochi | **canvas-confetti** | `https://cdn.jsdelivr.net/npm/canvas-confetti@1.9.4/dist/confetti.browser.min.js` |
|
||
| Confetti con emoji (alt.) | **js-confetti** | <https://github.com/loonywizard/js-confetti> |
|
||
| Audio / SFX | **Howler.js** | `https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.4/howler.min.js` |
|
||
| Animazioni / timeline | **anime.js** | `https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js` |
|
||
| QR code join | **qrcodejs** | `https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js` |
|
||
| Haptics | **Vibration API** (nativa) | `navigator.vibrate()` |
|
||
| Sblocco/gestione audio | **Web Audio API** (nativa) | `AudioContext` + `resume()` |
|
||
| Realtime opzionale | **Cloudflare Durable Objects** / WebSocket / Firebase | — |
|
||
|
||
**Checklist di implementazione**
|
||
|
||
- [ ] Sbloccare l'audio al primo tap (bottone "Avvia lo show").
|
||
- [ ] Precaricare tutti gli SFX (Howler) e le immagini prima dell'evento.
|
||
- [ ] Scalare gli effetti (confetti/shake/audio) sull'importanza del reveal.
|
||
- [ ] Rispettare `prefers-reduced-motion` (`disableForReducedMotion`) e offrire toggle audio/haptics.
|
||
- [ ] Feature-detection per `navigator.vibrate` (assente su iOS/Safari e Firefox recenti).
|
||
- [ ] Testare su schermo grande + audio potente (l'evento è dal vivo, il volume conta).
|
||
- [ ] Curare l'ordine di reveal per il crescendo drammatico.
|
||
|
||
---
|
||
|
||
## Fonti
|
||
|
||
**Confetti / animazioni**
|
||
- canvas-confetti (GitHub): <https://github.com/catdad/canvas-confetti>
|
||
- canvas-confetti (npm): <https://www.npmjs.com/package/canvas-confetti>
|
||
- canvas-confetti (cdnjs): <https://cdnjs.com/libraries/canvas-confetti>
|
||
- canvas-confetti (jsDelivr): <https://www.jsdelivr.com/package/npm/canvas-confetti>
|
||
- Demo/preset canvas-confetti (Kiril Vatev): <https://www.kirilv.com/canvas-confetti/>
|
||
- js-confetti (emoji): <https://github.com/loonywizard/js-confetti>
|
||
- anime.js (sito): <https://animejs.com/>
|
||
- anime.js (documentazione): <https://animejs.com/documentation/>
|
||
- anime.js — stagger: <https://animejs.com/documentation/utilities/stagger/>
|
||
|
||
**Audio / Web Audio**
|
||
- Howler.js (sito): <https://howlerjs.com/>
|
||
- Howler.js (GitHub): <https://github.com/goldfire/howler.js/>
|
||
- Howler.js (cdnjs): <https://cdnjs.com/libraries/howler>
|
||
- MDN — Using the Web Audio API: <https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Using_Web_Audio_API>
|
||
- MDN — Autoplay guide: <https://developer.mozilla.org/en-US/docs/Web/Media/Guides/Autoplay>
|
||
- MDN — Web Audio API best practices: <https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API/Best_practices>
|
||
- Chrome for Developers — Web Audio, Autoplay Policy and Games: <https://developer.chrome.com/blog/web-audio-autoplay>
|
||
- Chrome for Developers — Autoplay policy in Chrome: <https://developer.chrome.com/blog/autoplay>
|
||
|
||
**Effetti sonori gratuiti**
|
||
- Mixkit — Slot Machine: <https://mixkit.co/free-sound-effects/slot-machine/>
|
||
- Mixkit — Casino: <https://mixkit.co/free-sound-effects/casino/>
|
||
- Pixabay — Slot Machine: <https://pixabay.com/sound-effects/search/slot-machine/>
|
||
- Pixabay — Slot Spin: <https://pixabay.com/sound-effects/search/slot%20spin/>
|
||
- Pixabay — Jackpot: <https://pixabay.com/sound-effects/search/jackpot/>
|
||
- Pixabay — Casino: <https://pixabay.com/sound-effects/search/casino/>
|
||
- Freesound (home): <https://freesound.org/>
|
||
- Freesound — pack Slot Machine (lukaso): <https://freesound.org/people/lukaso/packs/4497/>
|
||
|
||
**Haptics**
|
||
- MDN — Vibration API: <https://developer.mozilla.org/en-US/docs/Web/API/Vibration_API>
|
||
- MDN — Navigator.vibrate(): <https://developer.mozilla.org/en-US/docs/Web/API/Navigator/vibrate>
|
||
- WICG — Web Haptics API: <https://github.com/WICG/web-haptics>
|
||
|
||
**Gamification / game-show / psicologia**
|
||
- Yu-kai Chou — The Spinning Wheel (gamification): <https://yukaichou.com/gamification-analysis/the-spinning-wheel-a-comprehensive-guide-to-boosting-user-engagement/>
|
||
- Guidebook — Event App Gamification: <https://www.guidebook.com/post/master-event-gamification-with-these-engaging-app-features>
|
||
- Contest Factory — Gamification & Interactive Mechanics: <https://contestfactory.com/gamification-interactive-mechanics-that-drive-participation/>
|
||
- The Conversation — How gambling distorts reality and hooks your brain: <https://theconversation.com/designed-to-deceive-how-gambling-distorts-reality-and-hooks-your-brain-91052>
|
||
- NCBI/PMC — Reward anticipation and outcome evaluation in gambling: <https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3971161/>
|
||
- Near-miss effect: <https://accenteyes.com/how-near-misses-deceive-your-brain-into-persistent-betting/>
|
||
|
||
**Schermo condiviso / multiplayer**
|
||
- Jackbox — How to play remotely (QR / room code): <https://www.jackboxgames.com/blog/how-to-play-jackbox-games-with-friends-and-family-remotely>
|
||
- Kahoot — How to host a live kahoot: <https://support.kahoot.com/hc/en-us/articles/360039422694-How-to-host-a-live-kahoot>
|
||
- Kahoot — How to join (PIN / link / QR): <https://support.kahoot.com/hc/en-us/articles/360039890713-Kahoot-join-How-to-join-a-Kahoot-game>
|
||
- qrcodejs: <https://github.com/davidshimjs/qrcodejs>
|
||
- MDN — BroadcastChannel API: <https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API>
|
||
- Cloudflare Durable Objects: <https://developers.cloudflare.com/durable-objects/>
|