1/** 2 * Humano â Problema: animación "del desorden al sistema". 3 * 4 * Iconos reales (personas, documentos, firmas, más personas, comunicación, 5 * turnos, ausencias, fichajes, culturaâ¦) aparecen dispersos y torcidos âla 6 * plantilla dispersa, los procesos sueltosâ y, con el scroll, se enderezan y se 7 * ordenan en un sistema conectado y trazable alrededor del núcleo de Humano. 8 * 9 * Los chips y las lÃneas los pinta render.php (estado ordenado por defecto: sirve 10 * de respaldo sin JS / con prefers-reduced-motion). Aquà solo añadimos el 11 * desorden inicial y su resolución con el scroll, vÃa CSS transform. 12 */ 13( function () { 14 'use strict'; 15 16 var reduce = window.matchMedia && window.matchMedia( '(prefers-reduced-motion: reduce)' ).matches; 17 var clamp = function ( v, a, b ) { return v < a ? a : v > b ? b : v; }; 18 var lerp = function ( a, b, t ) { return a + ( b - a ) * t; }; 19 var easeInOut = function ( t ) { return t < 0.5 ? 4 * t * t * t : 1 - Math.pow( -2 * t + 2, 3 ) / 2; }; 20 21 // PRNG determinista (mulberry32) â desorden estable y compuesto, no azaroso. 22 function prng( seed ) { 23 return function () { 24 seed |= 0; seed = ( seed + 0x6D2B79F5 ) | 0; 25 var t = Math.imul( seed ^ ( seed >>> 15 ), 1 | seed ); 26 t = ( t + Math.imul( t ^ ( t >>> 7 ), 61 | t ) ) ^ t; 27 return ( ( t ^ ( t >>> 14 ) ) >>> 0 ) / 4294967296; 28 }; 29 } 30 31 function init() { 32 var panel = document.querySelector( '.humano-problema__anim' ); 33 if ( ! panel || panel.dataset.ready ) { return; } 34 panel.dataset.ready = '1'; 35 36 var chips = Array.prototype.slice.call( panel.querySelectorAll( '.hp-chip' ) ); 37 var lines = Array.prototype.slice.call( panel.querySelectorAll( '.hp-line' ) ); 38 var core = panel.querySelector( '.hp-core' ); 39 if ( ! chips.length ) { return; } 40 41 // Desorden inicial: cada chip parte de una posición ALEATORIA por todo el 42 // panel (no de su sitio ordenado), muy girado y con escala dispar = caos. 43 var rnd = prng( 20260603 ); 44 chips.forEach( function ( c ) { 45 c._ordFx = ( parseFloat( c.style.left ) || 50 ) / 100; // sitio ordenado (fracción) 46 c._ordFy = ( parseFloat( c.style.top ) || 50 ) / 100; 47 c._sctFx = 0.07 + rnd() * 0.86; // posición caótica de partida (fracción del panel) 48 c._sctFy = 0.05 + rnd() * 0.9; 49 c._rot = ( rnd() * 2 - 1 ) * 42; // giro ±42° 50 c._sc = 0.55 + rnd() * 0.55; // escala 0.55â1.10 (muy dispar) 51 c._op = 0.32 + rnd() * 0.4; // opacidad inicial baja y variada (profundidad) 52 c._ph = rnd() * Math.PI * 2; // fase de flotación 53 c._amp = 6 + rnd() * 10; // flotación más amplia 54 } ); 55
56 function renderState( p, t ) { 57 var moveP = easeInOut( clamp( ( p - 0.05 ) / 0.7, 0, 1 ) ); 58 var inv = 1 - moveP; 59 var w = panel.clientWidth || 400, h = panel.clientHeight || 500; 60 61 chips.forEach( function ( c ) { 62 var fx = t !== null ? Math.sin( t * 0.7 + c._ph ) * c._amp * inv : 0; 63 var fy = t !== null ? Math.cos( t * 0.6 + c._ph ) * c._amp * inv : 0; 64 // DesvÃo = distancia desde la posición caótica a la ordenada (se anula al ordenar). 65 var dx = inv * ( c._sctFx - c._ordFx ) * w + fx; 66 var dy = inv * ( c._sctFy - c._ordFy ) * h + fy; 67 var sc = lerp( c._sc, 1, moveP ); 68 c.style.transform = 'translate(-50%,-50%) translate(' + dx.toFixed( 1 ) + 'px,' + dy.toFixed( 1 ) + 'px) rotate(' + ( c._rot * inv ).toFixed( 1 ) + 'deg) scale(' + sc.toFixed( 3 ) + ')'; 69 c.style.opacity = lerp( c._op, 1, moveP ).toFixed( 3 ); 70 } ); 71 72 // LÃneas de trazabilidad: se dibujan al final, ya ordenado (pathLength=1). 73 lines.forEach( function ( l, i ) { 74 var frac = clamp( ( p - 0.62 - i * 0.012 ) / 0.32, 0, 1 ); 75 l.style.strokeDashoffset = ( 1 - frac ).toFixed( 3 ); 76 l.style.opacity = ( frac * 0.55 ).toFixed( 3 ); 77 } ); 78 79 if ( core ) { 80 var coreP = clamp( ( p - 0.1 ) / 0.55, 0, 1 ); 81 var pulse = t !== null && p > 0.85 ? 1 + Math.sin( t * 1.8 ) * 0.03 : 1; 82 core.style.transform = 'translate(-50%,-50%) scale(' + ( lerp( 0.86, 1, coreP ) * pulse ).toFixed( 3 ) + ')'; 83 core.style.setProperty( '--hp-glow', ( 0.15 + coreP * 0.5 ).toFixed( 3 ) ); 84 } 85 } 86 87 if ( reduce || ! ( 'requestAnimationFrame' in window ) ) { 88 renderState( 1, null ); // estado ordenado, sin movimiento. 89 return; 90 } 91 92 var visible = false, running = false; 93 function progress() { 94 // Override de depuración (capturas deterministas); en producción es undefined. 95 if ( typeof window.__humanoProblemaForceP === 'number' ) { return clamp( window.__humanoProblemaForceP, 0, 1 ); } 96 var r = panel.getBoundingClientRect(); 97 var vh = window.innerHeight || 800; 98 return clamp( ( 0.85 * vh - r.top ) / ( 0.7 * vh ), 0, 1 ); 99 } 100 function frame() { 101 if ( ! visible ) { running = false; return; } 102 renderState( progress(), performance.now() / 1000 ); 103 requestAnimationFrame( frame ); 104 } 105 function kick() { if ( ! running ) { running = true; requestAnimationFrame( frame ); } } 106 107 renderState( progress(), 0 ); 108 if ( 'IntersectionObserver' in window ) { 109 new IntersectionObserver( function ( entries ) { 110 entries.forEach( function ( e ) { visible = e.isIntersecting; if ( visible ) { kick(); } } ); 111 }, { threshold: 0 } ).observe( panel ); 112 } else { 113 visible = true; kick(); 114 } 115 } 116 117 if ( document.readyState !== 'loading' ) { init(); } 118 else { document.addEventListener( 'DOMContentLoaded', init ); } 119}() );
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.