fix(recorrido): no se puede quedar entre dos estados
Las tarjetas iban atadas a la posición del scroll, así que cualquier punto intermedio era un fotograma válido: parando a media rueda, la tarjeta de creeer se quedaba como una losa gris translúcida y parecía un fallo de render. Ahora el scroll solo elige el tiempo —doce: pregunta, respuesta, pregunta…— y las tarjetas animan hacia ese tiempo por duración. Pares donde pares, aterrizan. Verificado en 41 paradas repartidas por la sección: cero opacidades a medias. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
81c36bb657
commit
379d80b915
2 files changed
+70
-65
No files matched your search
@@ -88,10 +88,17 @@ function Escenificado() {
|
||||
// hilo conductor taught this project what an overdamped spring feels like.
|
||||
const progreso = useSpring(bruto, { stiffness: 260, damping: 42, restDelta: 0.0005 });
|
||||
|
||||
const [activo, setActivo] = useState(0);
|
||||
// Twelve beats, not a continuum: question, answer, question, answer… Scroll
|
||||
// picks the beat and nothing else. When the cards were driven straight off
|
||||
// the scroll value, every position in between was a frame you could stop on,
|
||||
// and creeer's card sat there as a half-transparent grey slab.
|
||||
const TIEMPOS = TOTAL * 2;
|
||||
const [tiempo, setTiempo] = useState(0);
|
||||
useMotionValueEvent(progreso, 'change', (v) => {
|
||||
setActivo(Math.min(TOTAL - 1, Math.max(0, Math.floor(v * TOTAL))));
|
||||
setTiempo(Math.min(TIEMPOS - 1, Math.max(0, Math.floor(v * TIEMPOS))));
|
||||
});
|
||||
const activo = Math.floor(tiempo / 2);
|
||||
const respondida = tiempo % 2 === 1;
|
||||
|
||||
const barra = useTransform(progreso, [0, 1], [0, 1]);
|
||||
const fondoY = useTransform(progreso, [0, 1], [0, -140]);
|
||||
@@ -104,7 +111,7 @@ function Escenificado() {
|
||||
|
||||
{/* One viewport of stage, six viewports of scroll to move through it. */}
|
||||
<div ref={contenedor} className="relative" style={{ height: `${TOTAL * 100}vh` }}>
|
||||
<div data-escena={activo} className="sticky top-0 h-screen overflow-hidden">
|
||||
<div data-escena={activo} data-tiempo={tiempo} className="sticky top-0 h-screen overflow-hidden">
|
||||
<motion.div style={{ y: fondoY }} className="absolute inset-0">
|
||||
<FondoPuntos className="-bottom-10 -right-16 w-80 md:w-[34rem] text-azul-profundo/10" distance={32} />
|
||||
</motion.div>
|
||||
@@ -140,6 +147,8 @@ function Escenificado() {
|
||||
i={i}
|
||||
total={TOTAL}
|
||||
progreso={progreso}
|
||||
activa={i === activo}
|
||||
respondida={i === activo && respondida}
|
||||
n={String(i + 1).padStart(2, '0')}
|
||||
{...item}
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user