/* global React */ const { useEffect: gUseEffect, useRef: gUseRef, useState: gUseState, useCallback: gUseCallback } = React; /** * BeforeAfter * - Slider arrastrable (mouse + touch) y por scroll. * - Múltiples pares de proyectos seleccionables con tabs. * - Fotos reales de antes y después de obras propias. */ function BeforeAfter() { const pairs = [ { key: 'suelo', tab: 'Suelo', loc: 'Cambio de solería', name: 'Salón · Suelo nuevo', after: 'imagenes/ba-suelo-despues.jpeg', before: 'imagenes/ba-suelo-antes.jpeg', }, { key: 'habitacion', tab: 'Habitación', loc: 'Reforma integral', name: 'Habitación · Llave en mano', after: 'imagenes/ba-habitacion-despues.jpeg', before: 'imagenes/ba-habitacion-antes.jpeg', }, { key: 'pladur', tab: 'Pladur', loc: 'Acabados de pladur', name: 'Dormitorio · Pladur', after: 'imagenes/ba-pladur-despues.jpeg', before: 'imagenes/ba-pladur-antes.jpeg', }, ]; const [active, setActive] = gUseState(0); const [pos, setPos] = gUseState(50); const [dragging, setDragging] = gUseState(false); const wrapRef = gUseRef(null); const draggingRef = gUseRef(false); const onMove = gUseCallback((clientX) => { if (!wrapRef.current) return; const r = wrapRef.current.getBoundingClientRect(); const p = ((clientX - r.left) / r.width) * 100; setPos(Math.max(0, Math.min(100, p))); }, []); gUseEffect(() => { const move = (e) => { if (draggingRef.current) onMove(e.clientX); }; const touch = (e) => { if (draggingRef.current && e.touches[0]) onMove(e.touches[0].clientX); }; const up = () => { if (draggingRef.current) { draggingRef.current = false; setDragging(false); } }; window.addEventListener('mousemove', move); window.addEventListener('touchmove', touch, { passive: true }); window.addEventListener('mouseup', up); window.addEventListener('touchend', up); return () => { window.removeEventListener('mousemove', move); window.removeEventListener('touchmove', touch); window.removeEventListener('mouseup', up); window.removeEventListener('touchend', up); }; }, [onMove]); // Animación sutil de presentación: la primera vez que entra en pantalla, mueve la línea para dejar claro que se arrastra. const animatedRef = gUseRef(false); gUseEffect(() => { if (animatedRef.current) return; const el = wrapRef.current; if (!el) return; const io = new IntersectionObserver((entries) => { entries.forEach(e => { if (e.isIntersecting && !animatedRef.current) { animatedRef.current = true; // pequeño "barrido" para invitar a interactuar const seq = [60, 70, 50, 40, 50]; seq.forEach((v, i) => setTimeout(() => setPos(v), 600 + i * 420)); io.disconnect(); } }); }, { threshold: 0.4 }); io.observe(el); return () => io.disconnect(); }, []); const current = pairs[active]; const onTouchStartKnob = (e) => { draggingRef.current = true; setDragging(true); if (e.touches && e.touches[0]) onMove(e.touches[0].clientX); }; const onMouseDownKnob = (e) => { draggingRef.current = true; setDragging(true); e.preventDefault(); }; // Tap-to-move también en la stage para mejor UX en mobile const onStageClick = (e) => { if (e.target.closest('.ba-handle')) return; onMove(e.clientX); }; return (
Desliza la línea blanca para ver la transformación. Cambia de proyecto con las pestañas.