1/* Animation Module: sync */ 2export function init(container) { 3 if (!container) return; 4(function(){ 5 'use strict'; 6 var synEntered = false; 7 8 var PATHS_DESKTOP = { 9 fwd1: { pts: [[10,110],[140,110]], color: '#062617' }, 10 rev1: { pts: [[140,130],[10,130]], color: '#4CAF50' }, 11 fwd2: { pts: [[160,110],[290,110]], color: '#062617' }, 12 rev2: { pts: [[290,130],[160,130]], color: '#4CAF50' }, 13 }; 14 var PATHS_MOBILE = { 15 fwd1: { pts: [[110,10],[110,110]], color: '#062617' }, 16 rev1: { pts: [[130,10],[130,110]], color: '#4CAF50' }, 17 fwd2: { pts: [[110,130],[110,230]], color: '#062617' }, 18 rev2: { pts: [[130,230],[130,130]], color: '#4CAF50' }, 19 }; 20 function getPATHS(){ return window.innerWidth <= 480 ? PATHS_MOBILE : PATHS_DESKTOP; } 21 var DUR = 700; 22 23 function lerp(a,b,t){ return a+(b-a)*t; } 24 function ease(t){ return t<0.5?2*t*t:-1+(4-2*t)*t; } 25 function getPt(pts,t){ return [lerp(pts[0][0],pts[1][0],t), lerp(pts[0][1],pts[1][1],t)]; } 26 27 function spawnDot(pd, delay){ 28 setTimeout(function(){ 29 var g = document.getElementById('synDots'); if(!g) return; 30 function mk(r,op){ 31 var c = document.createElementNS('http://www.w3.org/2000/svg','circle'); 32 c.setAttribute('r',r); c.setAttribute('fill',pd.color); 33 c.setAttribute('opacity',op); g.appendChild(c); return c; 34 } 35 var d=mk(4,1), t1=mk(2.5,0.35); 36 var start=null; 37 requestAnimationFrame(function frame(ts){ 38 if(!start) start=ts; 39 var raw=Math.min((ts-start)/DUR,1), e=ease(raw); 40 var pos=getPt(pd.pts,e); 41 d.setAttribute('cx',pos[0]); d.setAttribute('cy',pos[1]); 42 var pt=getPt(pd.pts,Math.max(0,e-0.1)); 43 t1.setAttribute('cx',pt[0]); t1.setAttribute('cy',pt[1]); 44 if(raw<1){ requestAnimationFrame(frame); } 45 else { d.remove(); t1.remove(); } 46 }); 47 }, delay); 48 } 49 50 function runCycle(){ 51 var p = getPATHS(); 52 spawnDot(p.fwd1, 0); 53 spawnDot(p.rev1, 0); 54 spawnDot(p.fwd2, 80); 55 spawnDot(p.rev2, 80); 56 setTimeout(runCycle, 1800); 57 } 58 59 function initAnimate(){ 60 var isMobile = window.innerWidth <= 480; 61 document.getElementById('synHeader').classList.add('syn-in'); 62 if(isMobile){ 63 var svg = document.getElementById('synSvg'); 64 if(svg){ 65 svg.setAttribute('viewBox','0 0 240 240'); 66 svg.style.display = 'block'; 67 } 68 var pathEls = [ 69 {id:'synP0', d:'M110,10 L110,110'}, 70 {id:'synP1', d:'M130,10 L130,110'}, 71 {id:'synP2', d:'M110,130 L110,230'}, 72 {id:'synP3', d:'M130,130 L130,230'}, 73 ]; 74 pathEls.forEach(function(p){ var el=document.getElementById(p.id); if(el) el.setAttribute('d',p.d); }); 75 } 76 ['synP0','synP1','synP2','synP3'].forEach(function(id,i){ 77 setTimeout(function(){ document.getElementById(id).classList.add('syn-path-in'); }, 300+i*80); 78 }); 79 setTimeout(function(){ document.getElementById('synCard').classList.add('syn-in'); }, 500); 80 setTimeout(function(){ document.getElementById('synGama').classList.add('syn-in'); }, 650); 81 setTimeout(function(){ document.getElementById('synStatus').classList.add('syn-in'); }, 800); 82 setTimeout(runCycle, 1000); 83 } 84 85 var obs = new IntersectionObserver(function(entries){ 86 if(entries[0].isIntersecting && !synEntered){ 87 synEntered = true; 88 initAnimate(); 89 } 90 }, {threshold: 0.2}); 91 92 var wrap = document.querySelector('.syn-wrap'); 93 if(wrap) obs.observe(wrap); 94})(); 95}
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.