diff --git a/app.js b/app.js index 1a238fb..29a036c 100644 --- a/app.js +++ b/app.js @@ -561,6 +561,21 @@ ).slice(0, 3); } + // Keyframe di decelerazione con coda lenta LUNGA a parità di durata totale: + // ~88% della distanza nel primo ~40% del tempo (veloce), poi l'ultimo 12% + // nel restante ~60% (crawl lento, così si leggono i nomi ~2s in più). + function decelKeyframes(targetY) { + return [ + { transform: "translateY(0)", easing: "cubic-bezier(0.17, 0.7, 0.4, 1)" }, + { + transform: `translateY(${targetY * 0.88}px)`, + offset: 0.4, + easing: "cubic-bezier(0.25, 0.1, 0.2, 1)", + }, + { transform: `translateY(${targetY}px)`, offset: 1 }, + ]; + } + function bounceReel(el, finalY) { return el.animate( [ @@ -591,18 +606,11 @@ const fakeY = -(targetIndex + dir - 1) * ITEM_H; const col = el.parentElement; - // decelera e "si ferma" sulla stanza SBAGLIATA - await el.animate( - [ - { transform: "translateY(0)" }, - { transform: `translateY(${fakeY}px)` }, - ], - { - duration, - easing: "cubic-bezier(0.05, 0.92, 0.1, 1)", - fill: "forwards", - }, - ).finished; + // decelera lento e "si ferma" sulla stanza SBAGLIATA + await el.animate(decelKeyframes(fakeY), { + duration, + fill: "forwards", + }).finished; Audio.reelStop(); // suspense su quella colonna @@ -629,18 +637,11 @@ return; } } - // atterraggio diretto + micro-assestamento - await el.animate( - [ - { transform: "translateY(0)" }, - { transform: `translateY(${finalY}px)` }, - ], - { - duration, - easing: "cubic-bezier(0.05, 0.92, 0.1, 1)", - fill: "forwards", - }, - ).finished; + // atterraggio diretto (coda lenta lunga) + micro-assestamento + await el.animate(decelKeyframes(finalY), { + duration, + fill: "forwards", + }).finished; await bounceReel(el, finalY); Audio.reelStop(); }