1document.addEventListener("DOMContentLoaded", () => { 2 const widthFactor = 1.5149520833; 3 const ellipses = [ 4 { height: 340, position: { top: -3, left: "0%" }, rotate: -8 }, 5 { height: 140, position: { top: -30, left: "70%" }, rotate: 4 }, 6 { height: 240, position: { left: -2, top: "-15%" }, rotate: 10 }, 7 { height: 470, position: { bottom: -5, right: "5%" }, rotate: -4 }, 8 { height: 300, position: { bottom: "-30%", right: -5 }, rotate: -4 }, 9 { height: 140, position: { bottom: -130, right: "-25%" }, rotate: 2 }, // bottom offscreen 10 { height: 280, position: { bottom: -170, left: "-20%" }, rotate: -3 }, // bottom offscreen 11 { height: 440, position: { left: -360, bottom: "20%" }, rotate: 4 }, // left offscreen 12 { height: 460, position: { right: -420, top: "20%" }, rotate: -4 }, // right offscreen 13 ]; 14 const title = document.querySelector(".hero_area .title"); 15 16 let container = document.createElement("div"); 17 container.classList.add("ellipse-container"); 18 const targetElement = document.querySelector(".hero_area .cq-colctrl-1-fc-c0"); 19 targetElement.appendChild(container); 20 21 function createEllipse(ellipse) { 22 const width = ellipse.height * widthFactor; 23 const wrapper = document.createElement("div"); 24 wrapper.classList.add("ellipse-wrapper"); 25 wrapper.dataset.rotate = ellipse.rotate; 26 wrapper.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 145.44 96" width="${width}" height="${ellipse.height}" class="ellipse" style="transform:rotate(${ellipse.rotate}deg)" data-rotate="${ellipse.rotate}"> 27 <path d="M134.38 20.78a38.49 38.49 0 0 0-27.03-11.49H106c-3.49.06-6.95.62-10.3 1.64a15.03 15.03 0 0 0-5.34-5.88 32.05 32.05 0 0 0-41.18 5.66 38.93 38.93 0 0 0-12.91-1.35 38.6 38.6 0 0 0-25.24 11.63 38.54 38.54 0 0 0-11 25.49 38.4 38.4 0 0 0 10.79 28.36 38.4 38.4 0 0 0 27.9 11.88c.48 0 .95 0 1.42-.03a37.4 37.4 0 0 0 9.6-1.62 15.08 15.08 0 0 0 5.34 5.87 31.98 31.98 0 0 0 41.19-5.68c3.41.9
276 6.92 1.45 10.44 1.45a38.76 38.76 0 0 0 38.72-38.72 38.53 38.53 0 0 0-11.06-27.22Z" style="fill:#F9FAFB"/> 28 </svg>`; 29 return wrapper; 30 } 31 32 function positionEllipse(ellipseWrapper, ellipse, targetRect) { 33 const { height, position } = ellipse; 34 const width = height * widthFactor; 35 const style = ellipseWrapper.style; 36 37 if (position.top !== undefined) { 38 style.top = typeof position.top === "string" ? position.top : `${position.top - height}px`; 39 } 40 if (position.bottom !== undefined) { 41 style.bottom = typeof position.bottom === "string" ? position.bottom : `${position.bottom - height}px`; 42 } 43 if (position.left !== undefined) { 44 style.left = typeof position.left === "string" ? position.left : `${position.left - width}px`; 45 } 46 if (position.right !== undefined) { 47 style.right = typeof position.right === "string" ? position.right : `${position.right - width}px`; 48 } 49 } 50 51 function updateEllipses() { 52 const targetRect = targetElement.getBoundingClientRect(); 53 ellipses.forEach((ellipse, index) => { 54 const ellipseWrapper = container.children[index]; 55 positionEllipse(ellipseWrapper, ellipse, targetRect); 56 }); 57 } 58 59 ellipses.forEach((ellipse) => { 60 const ellipseWrapper = createEllipse(ellipse); 61 container.appendChild(ellipseWrapper); 62 }); 63 64 updateEllipses(); 65 66 window.addEventListener("resize", updateEllipses); 67 68 let runCount = 0; 69 function animateEllipsesOnScroll(scrollY) { 70 // So initial scroll can be set on load 71 if (scrollY == undefined) { 72 scrollY = window.scrollY; 73 } 74 75 // No transition on first run (init position), 76 // then slow transition for page load, then fast transition for scrolling 77 let currentTransition = ''; 78 if (runCount === 1) { 79 currentTransition = 'transform 2.3s cubic-bezier(0.34, 1.56, 0.64, 1)'; 80 } else if (runCount > 1) { 81 currentTransition = 'transform 1s cubic-bezier(0.22, 0.61, 0.36, 1)'; 82 } 83 84 ellipses.forEach((ellipse, index) => { 85 const ellipseWrapper = container.children[index]; 86 const scrollAccelerationFactor = 600; 87 const translateY = -scrollY * (ellipse.height / scrollAccelerationFactor); 88 const rotateValue = parseFloat(ellipseWrapper.getAttribute('data-rotate')); 89 const adjustedRotate = -scrollY * 0.01 * (rotateValue + (rotateValue < 0 ? 1 : -1)); 90 91 ellipseWrapper.style.transform = `translateY(${translateY}px) rotate(${adjustedRotate}deg)`; 92 ellipseWrapper.style.transition = currentTransition; 93 }); 94 95 title.style.transform = `translateY(${-scrollY * 0.3}px)`; 96 title.style.transition = currentTransition; 97 98 runCount++; 99 } 100 101 // Animate up into position on page load 102 animateEllipsesOnScroll(-50); 103 setTimeout(() => animateEllipsesOnScroll(0), 100); 104 105 window.addEventListener("scroll", () => animateEllipsesOnScroll(undefined)); 106});
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.