1jQuery(document).ready(function($) { 2 var marquee = gsap.utils.toArray('#anniversary-marquee'); 3 4 marquee.forEach(marque => { 5 var marqueItems = gsap.utils.toArray('#anniversary-marquee .vc_column-inner > .wpb_wrapper > div'); 6 var marqueLoop = horizontalLoop(marqueItems, { 7 speed: .5, 8 repeat: -1, 9 }); 10 $('#anniversary-marquee').on('mouseenter', function() { 11 marqueLoop.pause(); 12 }); 13 $('#anniversary-marquee').on('mouseleave', function() { 14 marqueLoop.play(); 15 }); 16 }); 17}); 18 19function horizontalLoop(items, config) { 20 items = gsap.utils.toArray(items); 21 config = config || {}; 22 let tl = gsap.timeline({repeat: config.repeat, paused: config.paused, defaults: {ease: "none"}, onReverseComplete: () => tl.totalTime(tl.rawTime() + tl.duration() * 100)}), 23 length = items.length, 24 startX = items[0].offsetLeft, 25 times = [], 26 widths = [], 27 xPercents = [], 28 curIndex = 0, 29 pixelsPerSecond = (config.speed || 1) * 100, 30 snap = config.snap === false ? v => v : gsap.utils.snap(config.snap || 1), // some browsers shift by a pixel to accommodate flex layouts, so for example if width is 20% the first element's width might be 242px, and the next 243px, alternating back and forth. So we snap to 5 percentage points to make things look more natural 31 totalWidth, curX, distanceToStart, distanceToLoop, item, i; 32 gsap.set(items, { // convert "x" to "xPercent" to make things responsive, and populate the widths/xPercents Arrays to make lookups faster. 33 xPercent: (i, el) => { 34 let w = widths[i] = parseFloat(gsap.getProperty(el, "width", "px")); 35 xPercents[i] = snap(parseFloat(gsap.getProperty(el, "x", "px")) / w * 100 + gsap.getProperty(el, "xPercent")); 36 return xPercents[i]; 37 } 38 }); 39 gsap.set(items, {x: 0}); 40 totalWidth = items[length-1].offsetLeft + xPercents[length-1] / 100 * widths[length-1] - startX + items[length-1].offsetWidth * gsap.getProperty(items[length-1], "scaleX") + (parseFloat(config.paddingRight) || 0); 41 for (i = 0; i < length; i++) { 42 item = items[i]; 43 curX = xPercents[i] / 100 * widths[i]; 44 distanceToStart = item.offsetLeft + curX - startX; 45 distanceToLoop = distanceToStart + widths[i] * gsap.getProperty(item, "scaleX"); 46 tl.to(item, {xPercent: snap((curX - distanceToLoop) / widths[i] * 100), duration: distanceToLoop / pixelsPerSecond}, 0) 47 .fromTo(item, {xPercent: snap((curX - distanceToLoop + totalWidth) / widths[i] * 100)}, {xPercent: xPercents[i], duration: (curX - distanceToLoop + totalWidth - curX) / pixelsPerSecond, immediateRender: false}, distanceToLoop / pixelsPerSecond) 48 .add("label" + i, distanceToStart / pixelsPerSecond); 49 times[i] = distanceToStart / pixelsPerSecond; 50 } 51 function toIndex(index, vars) { 52 vars = vars || {}; 53 (Math.abs(index - curIndex) > length / 2) && (index += index > curIndex ? -length : length); // always go in the shortest direction 54 let newIndex = gsap.utils.wrap(0, length, index), 55 time = times[newIndex]; 56 if (time > tl.time() !== index > curIndex) { // if we're wrapping the timeline's playhead, make the proper adjustments 57 vars.modifiers = {time: gsap.utils.wrap(0, tl.duration())}; 58 time += tl.duration() * (index > curIndex ? 1 : -1); 59 } 60 curIndex = newIndex; 61 vars.overwrite = true; 62 return tl.tweenTo(time, vars); 63 } 64 tl.next = vars => toIndex(curIndex+1, vars); 65 tl.previous = vars => toIndex(curIndex-1, vars); 66 tl.current = () => curIndex; 67 tl.toIndex = (index, vars) => toIndex(index, vars); 68 tl.times = times; 69 tl.progress(1, true).progress(0, true); // pre-render for performance 70 if (config.reversed) { 71 tl.vars.onReverseComplete(); 72 tl.reverse(); 73 } 74 return tl; 75}
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.