1window.scrollToTarget = function (targetId) { 2 const scrollTarget = document.getElementById(targetId); 3 scrollTarget?.scrollIntoView({ 4 behavior: "smooth", 5 block: "start", 6 }); 7} 8 9window.scrollToTargetWithOffset = function (targetId, offset) { 10 const target = document.getElementById(targetId); 11 const off = Number(offset) || 0; 12 if (!target) return; 13 14 const y = target.getBoundingClientRect().top + window.scrollY - off; 15 16 window.scrollTo({ 17 top: y, 18 behavior: "smooth" 19 }); 20}; 21 22window.scrollToTop = function () { 23 if (typeof window !== "undefined") { 24 window.scroll({ top: 0, behavior: "smooth" }); 25 } 26} 27 28// TODO: Move this to its own file 29// Does the rollover effect on the kids of the element i need 30// This is in JS because we have access to the full event, and it's been more accurate 31function CardSectionListener(targets) { 32 const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent); 33 const parents = document.querySelectorAll('.' + targets); 34 const toolTipImages = document.getElementsByClassName('toolTipGuides'); 35 if(!parents){ 36 return; 37 } 38 39 // Auto hide tool tips on scroll 40 addEventListener("scroll", () => { 41 const tooltip = document.querySelector('#tooltip'); 42 if (tooltip) { 43 gsap.set(tooltip, { display: 'none' }); 44 } 45 }); 46 47 48 parents.forEach(function(parent) { 49 const children = parent.children; 50 if(!children){ 51 return; 52 } 53 // for each object assign roll over effects directly so we can 54 // access the full event 55 Array.from(children).forEach(function(card, cardIndex) { 56 const secondRow = cardIndex>3; 57 // will set-up the 3d acceleration on start 58 gsap.set(card, { 59 transformPerspective:500, 60 transformOrigin:"50% 50%", 61 rotateX:0, 62 rotateY:0, 63 }) 64 65 // Desktop mode has the fancy hover effects 66 if(!isMobile){ 67 card.addEventListener('mouseover', function(e) { 68 // instantly snaps to start pos 69 gsap.set("#tooltip", { 70 display: 'inherit' 71 }) 72 showToolTipOverSource(e,secondRow, card,toolTipImages[cardIndex].style.backgroundImage, true); 73 74 }); 75 card.addEventListener('mousemove', function(e) { 76 MouseMoveParallax3d(e, card); 77 showToolTipOverSource(e,secondRow, card); 78 79 }); 80 card.addEventListener('mouseout', function(e) { 81 MouseMoveParallax3d(null, card); 82 gsap.set("#tooltip", { 83 display: 'none' 84 }) 85 }); 86 }else{ // Mobile mode is just tap to show info 87 card.addEventListener('click', function(e) { 88 gsap.set("#tooltip", { 89 display: 'inherit' 90 }) 91 showToolTipOverSource(e,secondRow, card, toolTipImages[cardIndex].style.backgroundImage, true); 92 }); 93 } 94 }); 95 }); 96 97 98} 99// Does a fake parallax effect on cards 100function MouseMoveParallax3d(e, el) { 101 102 // Reset if no event 103 if (!e) { 104 gsap.to(el, { 105 transformPerspective:500, 106 overwrite:true, 107 duration: 1, 108 transformOrigin:"50% 50%", 109 rotateX:0, 110 rotateY:0, 111 ease:"power2.out", 112 }) 113 return; 114 } 115 116 const rect = el.getBoundingClientRect(); 117 const centerX = rect.left + rect.width / 2; 118 const centerY = rect.top + rect.height / 2; 119 120 const xPercent = ((e.clientX - centerX) / (rect.width / 2)) * 100; 121 const yPercent = ((e.clientY - centerY) / (rect.height / 2)) * 100; 122 123 const maxDegrees = 20; 124 125 const rotateY = (xPercent / 100) * maxDegrees; 126 const rotateX = (-yPercent / 100) * maxDegrees; 127 gsap.to(el, { 128 transformPerspective:500, 129 overwrite:true, 130 duration: 1, 131 transformOrigin:"50% 50%", 132 rotateX:rotateX, 133 rotateY:rotateY, 134 ease:"power1.out", 135 }) 136} 137 138// Shows a tooltip asset(if available) over a source object(if available) 139function showToolTipOverSource(e, isSecondRow, el, backgroundImage, instant){ 140 if(!backgroundImage){ 141 return; 142 } 143 const tooltip = document.getElementById('tooltip'); 144 tooltip.style.backgroundImage = backgroundImage; 145 146 let yPositionRect = isSecondRow?document.getElementById('card-preview-guide-bottom') : document.getElementById('card-preview-guide-top'); 147 if(!yPositionRect || !tooltip){ 148 return; 149 } 150 const toolTipRect = el.getBoundingClientRect(); 151 const centerX = toolTipRect.left + toolTipRect.width / 2; 152 153 const x = centerX - (tooltip.offsetWidth / 2); 154 let y = yPositionRect.getBoundingClientRect().top; 155 // if its on first row, offset by tooltips own height so it doesn't overlap 156 if(!isSecondRow){ 157 y-= tooltip.offsetHeight; 158 } 159 160 if (instant) { 161 gsap.set(tooltip, { 162 scale:0.8, 163 transformOrigin:!isSecondRow?"50% 100%" : "50% 0%", 164 x: x, 165 y: y, 166 overwrite:true, 167 left: 0, 168 top: 0 169 }); 170 gsap.fromTo(tooltip, {opacity:0}
170,{ 171 duration:0.8, 172 opacity:1, 173 ease:"power4.out", 174 }); 175 return; 176 } 177 178 const xPercent = ((e.clientX - centerX) / (toolTipRect.width / 2)) * 42; 179 180 gsap.to(tooltip, { 181 duration:14.3, 182 overwrite:2, 183 x: x + xPercent, 184 ease: "power2.out" 185 }); 186}
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.