1/* Mobile SVG motion without one compositor layer per transformed SVG node. */ 2(function () { 3 'use strict'; 4 if (!window.matchMedia || !window.matchMedia('(pointer: coarse)').matches) return; 5 if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return; 6 7 const motions = new Map(); 8 let previousFrame = 0; 9 10 function specification(element) { 11 if (element.classList.contains('ring-spin-cw')) { 12 return { duration: parseFloat(element.style.animationDuration) || 60, direction: 1 }; 13 } 14 if (element.classList.contains('ring-spin-ccw')) { 15 return { duration: parseFloat(element.style.animationDuration) || 60, direction: -1 }; 16 } 17 if (element.classList.contains('ring-marker-spin')) return { duration: 6, direction: 1 }; 18 if (element.classList.contains('rotating-squares')) return { duration: 60, direction: 1 }; 19 if (element.classList.contains('rotating-square')) return { duration: 2, direction: -1 }; 20 if (element.matches('.segmented-ring.ring-0')) return { duration: 100, direction: 1 }; 21 if (element.matches('.segmented-ring.ring-1')) return { duration: 80, direction: -1 }; 22 if (element.matches('.segmented-ring.ring-2')) return { duration: 60, direction: -1 }; 23 return null; 24 } 25 26 function register(root) { 27 root.querySelectorAll([ 28 '.ring-spin-cw', '.ring-spin-ccw', '.ring-marker-spin', 29 '.rotating-squares', '.rotating-square', '.segmented-ring' 30 ].join(',')).forEach(function (element) { 31 if (motions.has(element)) return; 32 const motion = specification(element); 33 if (!motion) return; 34 motion.delay = parseFloat(element.style.animationDelay) || 0; 35 // CSS animation time begins when the element itself enters the document. Dynamic 36 // wheel rings are added about a second after navigation, so a page-global clock 37 // shifts their pose relative to desktop even when speed and axis are correct. 38 motion.start = performance.now() / 1000; 39 motions.set(element, motion); 40 }); 41 } 42 43 function draw(now) { 44 if (now - previousFrame >= 1000 / 30) { 45 previousFrame = now; 46 motions.forEach(function (motion, element) { 47 if (!element.isConnected) { 48 motions.delete(element); 49 return; 50 } 51 const elapsed = now / 1000 - motion.start - motion.delay; 52 const angle = motion.direction * (elapsed % motion.duration) / motion.duration * 360; 53 // Use the same CSS property as desktop so transform-box and transform-origin 54 // retain the exact axis defined by the existing stylesheet. 55 element.style.transform = 'rotate(' + angle + 'deg)'; 56 }); 57 } 58 window.requestAnimationFrame(draw); 59 } 60 61 register(document); 62 if (typeof MutationObserver === 'function') { 63 new MutationObserver(function (records) { 64 records.forEach(record => record.addedNodes.forEach(node => { 65 if (node.nodeType === 1) register(node.parentElement || document); 66 })); 67 }).observe(document.getElementById('stage'), { childList: true, subtree: true }); 68 } 69 window.requestAnimationFrame(draw); 70})();
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.