why my css marquee wont work after an XML request on all my pages

36 Views Asked by At

I am trying to minimize a simple website and add elements to the whole site without write the code double.

so there is a marque that will be on all pages :

//marquee.js

function includeMarquee() {
    var xhr = new XMLHttpRequest();
    var marqueeFilePath = 'marquee.html';

    xhr.open('GET', marqueeFilePath, true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
            var marqueeContent = xhr.responseText;
            var marqueeContainer = document.getElementById('marquee-container');
            if (marqueeContainer) {
                marqueeContainer.innerHTML = marqueeContent;
            }
        }
    };

    xhr.send();
}

window.onload = function () {
    includeMarquee();
};

 ``` ```
.services-ticker-block {
  position: relative;
  display:flex; 
  align-items:center;
  overflow-x: hidden;
}


.stb_line_single {
  position: relative;
  white-space: nowrap;
  padding: 0;
  will-change: transform;

}

.stb-item {
  padding: 0;
  font-size: 6.4rem;
  display: inline-block;
  margin-right: 10rem;
  background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Yin_yang.svg/1024px-Yin_yang.svg.png');
  background-size: 21px 21px;
  height: 21px;
  width: 21px;
  display: inline-block;
  margin-right: 0px; /* Adjust as needed */
  width: 100vw;
  line-break: none;


}

.stb-item:hover {
    color: #C02534;
}
 a.stb-item { 
 padding: 0;
font-size: 6.4rem;
display: inline-block;
margin-right: 10rem;
background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/1/17/Yin_yang.svg/1024px-Yin_yang.svg.png');
background-size: 21px 21px;
height: 21px;
width: 21px;
display: inline-flex;
margin-right: -11px;
width:1000vw; 
line-break: none;
justify-content: flex-start;
flex-direction: row;
flex-wrap: nowrap;
align-content: center;
align-items: center; 
overflow: visible; 
} 



.d90 {
  position:absolute;
  top: 0;
  left: 0;
  -webkit-transform: rotate(90deg);
  -moz-transform: rotate(90deg);
  -o-transform: rotate(90deg);
  -ms-transform: rotate(90deg);
  transform: rotate(90deg);
} 
.-d90
{
  position:absolute;
  bottom: 0;
  right: 0;
  -webkit-transform: rotate(-90deg);
  -moz-transform: rotate(-90deg);
  -o-transform: rotate(-90deg);
  -ms-transform: rotate(-90deg);
  transform: rotate(-90deg);
}

<!-- Yings&YangsTOP -->
<div class="services-ticker-block" style="position: absolute;top:0;">
 <div class="stb_line_single">
 <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">

     </a>
 </div>
</div>


<!-- Yings&YangsBottom -->
<div class="services-ticker-block" style="position: fixed;bottom: 0;">
 <div class="stb_line_single">
     <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
         <a href="#" class="stb-item">
     </a>
 </div>
</div> 
<!-- Yings&YangsSides -->
<div class="d90">
<div class="services-ticker-block" style="position: absolute;bottom: 0;">
 <div class="stb_line_single">
     <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
        <a href="#" class="stb-item">
     </a>
         <a href="#" class="stb-item">
     </a>
 </div></div>
</div> 
<!-- Yings&Yangssides -->
<div class="-d90">
 <div class="services-ticker-block" style="position: absolute;bottom: 0;right:-6000vw;">
   <div class="stb_line_single">
       <a href="#" class="stb-item">
       </a>
          <a href="#" class="stb-item">
       </a>
          <a href="#" class="stb-item">
       </a>
          <a href="#" class="stb-item">
       </a>
          <a href="#" class="stb-item">
       </a>
          <a href="#" class="stb-item">
       </a>
          <a href="#" class="stb-item">
       </a>
         <a href="#" class="stb-item">
       </a>
   </div>
 </div>
 </div> 

So it is a frame of a repeated image that stops animating when I call it with a request and henceforth the same with other objects, here is the animating script :

  const links = line.querySelectorAll("a"),
        tl = horizontalLoop(links, {
          repeat: 1.7, 
          speed: 1 + i / 5,
          reversed: i ? true : false,
          paddingRight: parseFloat(gsap.getProperty(links[0], "marginRight", "px")) // otherwise first element would be right up against the last when it loops. In this layout, the spacing is done with marginRight.
        });
  links.forEach(link => {
    link.addEventListener("mouseenter", () => gsap.to(tl, {timeScale: 0, overwrite: true}));
    link.addEventListener("mouseleave", () => gsap.to(tl, {timeScale: i ? -1 : 1, overwrite: true}));
  });
});


/*
This helper function makes a group of elements animate along the x-axis in a seamless, responsive loop.

Features:
 - Uses xPercent so that even if the widths change (like if the window gets resized), it should still work in most cases.
 - When each item animates to the left or right enough, it will loop back to the other side
 - Optionally pass in a config object with values like "speed" (default: 1, which travels at roughly 100 pixels per second), paused (boolean),  repeat, reversed, and paddingRight.
 - The returned timeline will have the following methods added to it:
   - next() - animates to the next element using a timeline.tweenTo() which it returns. You can pass in a vars object to control duration, easing, etc.
   - previous() - animates to the previous element using a timeline.tweenTo() which it returns. You can pass in a vars object to control duration, easing, etc.
   - toIndex() - pass in a zero-based index value of the element that it should animate to, and optionally pass in a vars object to control duration, easing, etc. Always goes in the shortest direction
   - current() - returns the current index (if an animation is in-progress, it reflects the final index)
   - times - an Array of the times on the timeline where each element hits the "starting" spot. There's also a label added accordingly, so "label1" is when the 2nd element reaches the start.
 */
function horizontalLoop(items, config) {
    items = gsap.utils.toArray(items);
    config = config || {};
    let tl = gsap.timeline({repeat: config.repeat, paused: config.paused, defaults: {ease: "none"}, onReverseComplete: () => tl.totalTime(tl.rawTime() + tl.duration() * 100)}),
        length = items.length,
        startX = items[0].offsetLeft,
        times = [],
        widths = [],
        xPercents = [],
        curIndex = 0,
        pixelsPerSecond = (config.speed || 1) * 100,
        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
        totalWidth, curX, distanceToStart, distanceToLoop, item, i;
    gsap.set(items, { // convert "x" to "xPercent" to make things responsive, and populate the widths/xPercents Arrays to make lookups faster.
        xPercent: (i, el) => {
            let w = widths[i] = parseFloat(gsap.getProperty(el, "width", "px"));
            xPercents[i] = snap(parseFloat(gsap.getProperty(el, "x", "px")) / w * 100 + gsap.getProperty(el, "xPercent"));
            return xPercents[i];
        }
    });
    gsap.set(items, {x: 0});
    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);
    for (i = 0; i < length; i++) {
        item = items[i];
        curX = xPercents[i] / 100 * widths[i];
        distanceToStart = item.offsetLeft + curX - startX;
        distanceToLoop = distanceToStart + widths[i] * gsap.getProperty(item, "scaleX");
        tl.to(item, {xPercent: snap((curX - distanceToLoop) / widths[i] * 100), duration: distanceToLoop / pixelsPerSecond}, 0)
          .fromTo(item, {xPercent: snap((curX - distanceToLoop + totalWidth) / widths[i] * 100)}, {xPercent: xPercents[i], duration: (curX - distanceToLoop + totalWidth - curX) / pixelsPerSecond, immediateRender: false}, distanceToLoop / pixelsPerSecond)
          .add("label" + i, distanceToStart / pixelsPerSecond);
        times[i] = distanceToStart / pixelsPerSecond;
    }
    function toIndex(index, vars) {
        vars = vars || {};
        (Math.abs(index - curIndex) > length / 2) && (index += index > curIndex ? -length : length); // always go in the shortest direction
        let newIndex = gsap.utils.wrap(0, length, index),
            time = times[newIndex];
        if (time > tl.time() !== index > curIndex) { // if we're wrapping the timeline's playhead, make the proper adjustments
            vars.modifiers = {time: gsap.utils.wrap(0, tl.duration())};
            time += tl.duration() * (index > curIndex ? 1 : -1);
        }
        curIndex = newIndex;
        vars.overwrite = true;
        return tl.tweenTo(time, vars);
    }
    tl.next = vars => toIndex(curIndex+1, vars);
    tl.previous = vars => toIndex(curIndex-1, vars);
    tl.current = () => curIndex;
    tl.toIndex = (index, vars) => toIndex(index, vars);
    tl.times = times;
  if (config.reversed) {
    tl.vars.onReverseComplete();
    tl.reverse();
  }
    return tl;
}


So then I can add this to all the pages a my navbar will appear. but the isssue is the stopping animation.

<div id="marquee-container"></div>
   <script src="/src/js/include-marquee.js"></script>
0

There are 0 best solutions below