Frame by Frame Scroll Animation lagging

I have a page that utilises frame by frame animation. The animation is triggered by mouse scroll. I’ve got everything to work but I’m having a problem with the animation.
ezgif.com-gif-maker (4)

As you can see, the images flash and sometimes the black background comes through. I was wondering if there’s a way for the animation to be a lot more smooth. Here’s my code:

HTML

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="./styles.css">
  <title>Document</title>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>

<div class="content-wrapper"> 
  <header>
    <a href="#" class="logo">[My Coily Story]</a>
    <ul>
      <li><a href="#" class="active">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </header>
</div>

  <div data-aos="zoom-in">
<div id="target">
  <div class="imageBox">
  </div>
</div>
</div>

<div class="gif"></div>
<div class="scroll"></div>

<div class="Stay">
<a href="#">
  <span></span>
  <span></span>
  <span></span>
  <span></span> 
  Stay Natural
</a>
</div>

<div class="Try">
<a href="#">
  <span></span>
  <span></span>
  <span></span>
  <span></span> 
  Try Relaxer
</a>
</div>

</body>
<script type="text/javascript" src="./main.js"></script>
</html>

CSS

@font-face {
    font-family: 'arcade';
    src: url(fonts/ARCADECLASSIC.TTF);
    font-weight: 100;
    font-style: Regular;
}

body {
 background-color:black;
 margin: 0px;
}

@font-face {
    font-family: 'arcade';
    src: url(fonts/ARCADECLASSIC.TTF);
    font-weight: 100;
    font-style: Regular;
}
*{
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: sans-serif;
    letter-spacing: 1px;
    transition: all 0.35s linear;

}

body {
   background-color: black;
   padding: 0;
   margin: 0;
   height: 100vh;
   width: 100vh;
   min-height: 100vh;
   align-items: center;
   justify-content: center;
}
header {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    padding: 1.875rem 6.25rem;
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-family: Poppins, sans-serif;
    z-index: 10000;
}

header .logo {
    color: #fff;
    font-weight: 700;
    text-decoration: none;
    font-size: 1.563rem;
    text-transform: uppercase;
    letter-spacing: 0.313rem;
    font-family: Poppins, sans-serif;

}

.logo:hover{
   pointer-events: none;
   border: none;
   box-shadow: none;
   background: transparent;
   color: #fff;
}

header ul{
    display: flex;
    justify-content: center;
    align-items: center;
    font-family: Poppins, sans-serif;
    font-size: 1.1rem;
    text-transform: none;

}

header ul li {
    list-style: none;
    margin-left: 1.25rem;
    font-family: Poppins, sans-serif;
    font-size: 1.1rem;
    text-transform: none;

}

header ul li a {
     text-decoration: none;
     padding: 0.375rem 0.938rem;
     color: #fff;
     border-radius: 1.25rem;
     font-family: Poppins, sans-serif;
     font-size: 1.1rem;
     text-transform: none;
     position: sticky;


}

header ul li a:hover,
header ul li a.active {
    background: #fff;
    color: #2b1055;
    font-family: Poppins, sans-serif;
    font-size: 1.1rem;
    text-transform: none;
    position: sticky;
    border: none;
    box-shadow: none;
    transition-delay: 0s;
}

#target {
 width: 100%;
 height:1500px;
 position: relative;
}

.imageBox {

 width: 90vh;
 height: 90vh;
 position: fixed;
  top: 450px;
  left: 50%;
  transform: translate(-50%, -50%);
 background-image: url('./Images/1.jpg');
 background-repeat: no-repeat;
 background-size: 100%;
}

.slideOne {
 display:flex;
 justify-content: center;
}

.slideOne p {
 font-weight:bold;
 font-size: 25px;
}

.gif {
    background: url(./Images/1.gif);
    position: fixed;
    background-repeat: no-repeat;
    background-size: 100%;
    height: 60%;
    width: 60%;
    left: 242px;
    top: 585px;

}

.scroll {
    background: url(./Images/2.gif);
    position: fixed;
    background-repeat: no-repeat;
    background-size: 25%;
    height: 189px;
    width: 898px;
    left: 370px;
    top: 570px;

}

a {
    z-index: 10000;
    position: relative;
    display: inline-block;
    padding: 15px 30px;
    color: #ffffff;
    font-family: arcade;
    text-transform: uppercase;
    letter-spacing: 4px;
    text-decoration: none;
    font-size: 24px;
    overflow: hidden;
    transition: 0.2s;
    position: relative;

 

}

a:hover {
   color: #c967b6;
}



.Stay {
    position: fixed;
    top: 745px;
    left: 350px;
    animation-name: fadeIn ;
    animation-duration: 5s;
    animation-delay: 12s;
    opacity: 0;
    animation-fill-mode: forwards;

}

.Try {
    position: fixed;
    top: 745px;
    left: 850px;
    font-family: arcade;
    animation-name: fadeIn ;
    animation-duration: 5s;
    animation-delay: 12s;
    opacity: 0;
    animation-fill-mode: forwards;

}
@keyframes fadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

JS

const layerImage = {
 1:'./Images/1.jpg',
 2:'./Images/2.jpg',
 3:'./Images/3.jpg',
 4:'./Images/4.jpg',
 5:'./Images/5.jpg',
 6:'./Images/6.jpg',
 7:'./Images/7.jpg',
 8:'./Images/8.jpg',
 9:'./Images/9.jpg',
 10:'./Images/10.jpg',
 11:'./Images/11.jpg',
 12:'./Images/12.jpg',
 13:'./Images/13.jpg',
 14:'./Images/14.jpg',
 15:'./Images/15.jpg',
 16:'./Images/16.jpg',
 17:'./Images/17.jpg',
 18:'./Images/18.jpg',
 19:'./Images/19.jpg',
 20:'./Images/20.jpg',
 21:'./Images/21.jpg',
 22:'./Images/22.jpg',
 23:'./Images/23.jpg',
 24:'./Images/24.jpg',
 25:'./Images/25.jpg',
 26:'./Images/26.jpg',
 27:'./Images/27.jpg',
 28:'./Images/28.jpg',
 29:'./Images/29.jpg',
 30:'./Images/30.jpg',
 31:'./Images/31.jpg',
 32:'./Images/32.jpg',
 33:'./Images/33.jpg',
 34:'./Images/34.jpg',
 35:'./Images/35.jpg',
 36:'./Images/36.jpg',
 37:'./Images/37.jpg',
 38:'./Images/38.jpg',
 39:'./Images/39.jpg',
 40:'./Images/40.jpg',
 41:'./Images/41.jpg',
 42:'./Images/42.jpg',
 43:'./Images/43.jpg',
 44:'./Images/44.jpg',
 45:'./Images/45.jpg',
 46:'./Images/46.jpg',
 47:'./Images/47.jpg',
 48:'./Images/48.jpg',
 49:'./Images/49.jpg',
 50:'./Images/50.jpg',
 51:'./Images/51.jpg',
 52:'./Images/52.jpg',
 53:'./Images/53.jpg',
 54:'./Images/54.jpg',
 55:'./Images/55.jpg',
 56:'./Images/56.jpg',
 57:'./Images/57.jpg',
 58:'./Images/58.jpg',
 59:'./Images/59.jpg',
 60:'./Images/60.jpg',
 61:'./Images/61.jpg',
 62:'./Images/62.jpg',
 63:'./Images/63.jpg',
 64:'./Images/64.jpg',
 65:'./Images/65.jpg',
 66:'./Images/66.jpg',
 67:'./Images/67.jpg',
 68:'./Images/68.jpg',
 69:'./Images/69.jpg',
 70:'./Images/70.jpg',
 71:'./Images/71.jpg',
 72:'./Images/72.jpg',
 73:'./Images/73.jpg',
 74:'./Images/74.jpg',
 75:'./Images/75.jpg',
 76:'./Images/76.jpg',
 77:'./Images/77.jpg',
 78:'./Images/78.jpg',
 79:'./Images/79.jpg',
 80:'./Images/80.jpg',
 81:'./Images/81.jpg',
 82:'./Images/82.jpg',
 83:'./Images/83.jpg',
 84:'./Images/84.jpg',
 85:'./Images/85.jpg',
 86:'./Images/86.jpg',
 87:'./Images/87.jpg',
 88:'./Images/88.jpg',
 89:'./Images/89.jpg',
 90:'./Images/90.jpg',
 91:'./Images/91.jpg',
 92:'./Images/92.jpg',
 93:'./Images/93.jpg',
 94:'./Images/94.jpg',
 95:'./Images/95.jpg',
 96:'./Images/96.jpg',
 97:'./Images/97.jpg',
 98:'./Images/98.jpg',
 99:'./Images/99.jpg',
 100:'./Images/100.jpg',
 101:'./Images/101.jpg',
 102:'./Images/102.jpg',
 103:'./Images/103.jpg',
 104:'./Images/104.jpg',
 105:'./Images/105.jpg',
 106:'./Images/106.jpg',
 107:'./Images/107.jpg',
 108:'./Images/108.jpg',
 109:'./Images/109.jpg',
 110:'./Images/110.jpg',
 111:'./Images/111.jpg',
 112:'./Images/112.jpg',
 113:'./Images/113.jpg',
 114:'./Images/114.jpg',
 115:'./Images/115.jpg',
 116:'./Images/116.jpg',
 117:'./Images/117.jpg',
 118:'./Images/118.jpg',
 119:'./Images/119.jpg',
 120:'./Images/120.jpg',
 121:'./Images/121.jpg',
 122:'./Images/122.jpg',
 123:'./Images/123.jpg',
 124:'./Images/124.jpg',
 125:'./Images/125.jpg',
 126:'./Images/126.jpg',
 127:'./Images/127.jpg',
 128:'./Images/128.jpg',
 129:'./Images/129.jpg',
 130:'./Images/130.jpg',
 131:'./Images/131.jpg',
 132:'./Images/132.jpg',
 133:'./Images/133.jpg',
 134:'./Images/134.jpg',
 135:'./Images/135.jpg',
 136:'./Images/136.jpg',
 137:'./Images/137.jpg',
 138:'./Images/138.jpg',
 139:'./Images/139.jpg',
 140:'./Images/140.jpg',
 141:'./Images/141.jpg',
 142:'./Images/142.jpg',
 143:'./Images/143.jpg',
 144:'./Images/144.jpg',
 145:'./Images/145.jpg',
 146:'./Images/146.jpg',
 147:'./Images/147.jpg',
 148:'./Images/148.jpg'
};


function checkScroll() {
  const y = window.scrollY;
  const scrollPixels = Math.min(Math.floor(y/4.5) + 1, 148);
  const imageToUse = layerImage[scrollPixels];
  // Change the background image
  $('.imageBox').css('background-image', `url('${imageToUse}')`);
}
$(document).ready(()=>{
  $(window).scroll(()=>{
    checkScroll();
  });
});

Any help is appreciated.

Hey @chip7077575665 ! By any chance do you have GitHub repo of your code to share?

Hi, thank you for your response. Is this okay?

not sure if this link will work

1 Like

Hey @chip7077575665 ! Thanks for the link. So I think the problem here is that when scrolling, the client is skipping frames. I did some googling and I found a way to throttle this. I’ve made a PR to your repo. You’ll just have to merge the Pull Request to your main branch.

1 Like

Thank you so much for this! I’m still quite new to github; do you know how I can go about doing this?

I can’t find an article online that can best explain how to do this. I also don’t want you to merge the PR to only discover you don’t like the suggested changes :rofl:

Maybe just save your main.js file in another place, and just copy and paste this into it:

const layerImage = {
 1:'./Images/1.jpg',
 2:'./Images/2.jpg',
 3:'./Images/3.jpg',
 4:'./Images/4.jpg',
 5:'./Images/5.jpg',
 6:'./Images/6.jpg',
 7:'./Images/7.jpg',
 8:'./Images/8.jpg',
 9:'./Images/9.jpg',
 10:'./Images/10.jpg',
 11:'./Images/11.jpg',
 12:'./Images/12.jpg',
 13:'./Images/13.jpg',
 14:'./Images/14.jpg',
 15:'./Images/15.jpg',
 16:'./Images/16.jpg',
 17:'./Images/17.jpg',
 18:'./Images/18.jpg',
 19:'./Images/19.jpg',
 20:'./Images/20.jpg',
 21:'./Images/21.jpg',
 22:'./Images/22.jpg',
 23:'./Images/23.jpg',
 24:'./Images/24.jpg',
 25:'./Images/25.jpg',
 26:'./Images/26.jpg',
 27:'./Images/27.jpg',
 28:'./Images/28.jpg',
 29:'./Images/29.jpg',
 30:'./Images/30.jpg',
 31:'./Images/31.jpg',
 32:'./Images/32.jpg',
 33:'./Images/33.jpg',
 34:'./Images/34.jpg',
 35:'./Images/35.jpg',
 36:'./Images/36.jpg',
 37:'./Images/37.jpg',
 38:'./Images/38.jpg',
 39:'./Images/39.jpg',
 40:'./Images/40.jpg',
 41:'./Images/41.jpg',
 42:'./Images/42.jpg',
 43:'./Images/43.jpg',
 44:'./Images/44.jpg',
 45:'./Images/45.jpg',
 46:'./Images/46.jpg',
 47:'./Images/47.jpg',
 48:'./Images/48.jpg',
 49:'./Images/49.jpg',
 50:'./Images/50.jpg',
 51:'./Images/51.jpg',
 52:'./Images/52.jpg',
 53:'./Images/53.jpg',
 54:'./Images/54.jpg',
 55:'./Images/55.jpg',
 56:'./Images/56.jpg',
 57:'./Images/57.jpg',
 58:'./Images/58.jpg',
 59:'./Images/59.jpg',
 60:'./Images/60.jpg',
 61:'./Images/61.jpg',
 62:'./Images/62.jpg',
 63:'./Images/63.jpg',
 64:'./Images/64.jpg',
 65:'./Images/65.jpg',
 66:'./Images/66.jpg',
 67:'./Images/67.jpg',
 68:'./Images/68.jpg',
 69:'./Images/69.jpg',
 70:'./Images/70.jpg',
 71:'./Images/71.jpg',
 72:'./Images/72.jpg',
 73:'./Images/73.jpg',
 74:'./Images/74.jpg',
 75:'./Images/75.jpg',
 76:'./Images/76.jpg',
 77:'./Images/77.jpg',
 78:'./Images/78.jpg',
 79:'./Images/79.jpg',
 80:'./Images/80.jpg',
 81:'./Images/81.jpg',
 82:'./Images/82.jpg',
 83:'./Images/83.jpg',
 84:'./Images/84.jpg',
 85:'./Images/85.jpg',
 86:'./Images/86.jpg',
 87:'./Images/87.jpg',
 88:'./Images/88.jpg',
 89:'./Images/89.jpg',
 90:'./Images/90.jpg',
 91:'./Images/91.jpg',
 92:'./Images/92.jpg',
 93:'./Images/93.jpg',
 94:'./Images/94.jpg',
 95:'./Images/95.jpg',
 96:'./Images/96.jpg',
 97:'./Images/97.jpg',
 98:'./Images/98.jpg',
 99:'./Images/99.jpg',
 100:'./Images/100.jpg',
 101:'./Images/101.jpg',
 102:'./Images/102.jpg',
 103:'./Images/103.jpg',
 104:'./Images/104.jpg',
 105:'./Images/105.jpg',
 106:'./Images/106.jpg',
 107:'./Images/107.jpg',
 108:'./Images/108.jpg',
 109:'./Images/109.jpg',
 110:'./Images/110.jpg',
 111:'./Images/111.jpg',
 112:'./Images/112.jpg',
 113:'./Images/113.jpg',
 114:'./Images/114.jpg',
 115:'./Images/115.jpg',
 116:'./Images/116.jpg',
 117:'./Images/117.jpg',
 118:'./Images/118.jpg',
 119:'./Images/119.jpg',
 120:'./Images/120.jpg',
 121:'./Images/121.jpg',
 122:'./Images/122.jpg',
 123:'./Images/123.jpg',
 124:'./Images/124.jpg',
 125:'./Images/125.jpg',
 126:'./Images/126.jpg',
 127:'./Images/127.jpg',
 128:'./Images/128.jpg',
 129:'./Images/129.jpg',
 130:'./Images/130.jpg',
 131:'./Images/131.jpg',
 132:'./Images/132.jpg',
 133:'./Images/133.jpg',
 134:'./Images/134.jpg',
 135:'./Images/135.jpg',
 136:'./Images/136.jpg',
 137:'./Images/137.jpg',
 138:'./Images/138.jpg',
 139:'./Images/139.jpg',
 140:'./Images/140.jpg',
 141:'./Images/141.jpg',
 142:'./Images/142.jpg',
 143:'./Images/143.jpg',
 144:'./Images/144.jpg',
 145:'./Images/145.jpg',
 146:'./Images/146.jpg',
 147:'./Images/147.jpg',
 148:'./Images/148.jpg'
};


function checkScroll() {
  const y = window.scrollY;
  const scrollPixels = Math.min(Math.floor(y/4.5) + 1, 148);
  console.log(y);
  const imageToUse = layerImage[scrollPixels];
  // Change the background image
  $('.imageBox').css('background-image', `url('${imageToUse}')`);
}
let scrolling=false;
$(document).ready(()=>{
  $(window).scroll(()=>{
    scrolling=true
   
})});

setInterval(() => {
  if(scrolling){
    checkScroll();
  scrolling=false
  }
  },300);
1 Like

Thank you!! i’ve started playing around with the number to get my desired result :slight_smile: