Home > Blockchain >  Animate on scroll - animation buildups issue
Animate on scroll - animation buildups issue

Time:12-30

I have a text static text element that changes when user scrolls more than 600px and again when it scrolls more than 1400px

$(window).scroll(function () {
  if ($(this).scrollTop() > 600) {                    
    $('.p-circle').html('Text 1');
    $('.p-circle-s').html('Text 2');                     
  } 
});
$(window).scroll(function () {
  if ($(this).scrollTop() > 1400) { 
    $('.p-circle').html('Text 1 updated');     
    $('.p-circle-s').html('Text 2 updated');
  }
});

How can I make a basic animation of fading for them, I tried next variants and they don't work well (it is fading 2 times)

if (scrollTop > 600 && scrollTop <= 1400) { 
    
  $('.p-circle').fadeOut(500, function() {
    $(this).text('Text 1').fadeIn(500);
  });
  $('.p-circle-s').fadeOut(500, function() {
    $(this).text('Text 2').fadeIn(500);
  });   
      
} else if (scrollTop > 1400 && scrollTop <= 2100) {

  $('.p-circle').fadeOut(500, function() {
    $(this).text('Text 1 updated').fadeIn(500);
  });
  $('.p-circle-s').fadeOut(500, function() {
    $(this).text('Text 2 Updated').fadeIn(500);
  }); 

}

CodePudding user response:

I think you're on the right track, however your logic in that last bit there isn't testing whether the transition already happened. Something along the lines of:

if ($(this).scrollTop() > 600 && $(this).scrollTop() <= 1400 && $(".p-circle").text() != 'Text 1')

I think I got your values wrong, but here's a fiddle to get you on the right track...

https://jsfiddle.net/64mj3k7n/3/

CodePudding user response:

A better solution would be to create a function (or Class) Waypoints, to be used like:

Waypoints(window, [0, 100, 600, 1400], (wp) => {
  console.log(wp);   // {index:Int, value:Int}
});

which accepts three arguments:

  1. an Element (or String selector) to scroll-watch
  2. an Array of scrollY waypoints values
  3. a callback Function

The callbacks is triggered only once a scroll index changes — in order to prevent buildups on every scroll Event call.

/**
 * Waypoints
 * Trigger callbacks on a scrollY milestone 
 * @url https://stackoverflow.com/a/70520524/383904
 * @param {string|object} el String selector or Element object
 * @param {array} waypoints Array of px from lower to higher
 * @param {function} cb Callback function
 */

function Waypoints(el, waypoints = [0], cb) {
  el = (typeof el === "string") ? document.querySelector(el) : el;
  const wp = [...waypoints].reverse();
  const wpTot = wp.length;
  const getIndex = (n) => {
    const i = wp.findIndex(m => m <= n);
    return wpTot - 1 - (i < 0 ? wpTot : i);
  };
  let index = -1;
  const getTask = () => {
    const i = getIndex(el.scrollY);
    if (index === i) return; // No task to trigger
    index = i; // Update index
    const value = wp[wpTot - 1 - i]; // Get the waypoint name
    cb({ index, value }); // Trigger the callback
  };
  el.addEventListener("scroll", getTask);
  window.addEventListener("DOMContentLoaded", () => getTask);
  window.addEventListener("load", () => getTask);
  getTask();
}


/**
 * YOUR APP:
 */

const $circle1 = $('.p-circle');
const $circle2 = $('.p-circle-s');

const circle1txt = ["Text 1 scroll", "Text 1", "Text 1 updated"];
const circle2txt = ["Text 2 scroll", "Text 2", "Text 2 updated"];

Waypoints(window, [0, 600, 1400], (wp) => {
  $circle1.fadeOut(500, () => {
    $circle1.text(circle1txt[wp.index]).fadeIn(500);
  });
  $circle2.fadeOut(500, () => {
    $circle2.text(circle2txt[wp.index]).fadeIn(500);
  });
});
body { height: 3000px; } /* Just to force some scrollbars for this demo */
[class^="p-"] { position: fixed; }
.p-circle-s { top: 2rem; }
<div ></div>
<div ></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

  • Related