skip to Main Content

I created a landing page for my website. The animation repeats whenever the user reloads or comes back to the landing page. This will be quite distracting for the user. Hence, I tried to write the JavaScript codes that limits the animation to run only once every hour. However, it is not working. Can we achieve this using JavaScript?

function runAnimations() {
  const textElement = document.querySelector('.text');
  const mainElement = document.querySelector('main');
 

  // Add animation classes to elements
  textElement.style.animation = 'herot 1s forwards';
  mainElement.style.animation = 'herolanding 1.1s';
 

  // Remove animation classes after animations complete
  textElement.addEventListener('animationend', () => {
    textElement.style.animation = ''; // Reset animation
  }, { once: true });

  mainElement.addEventListener('animationend', () => {
    mainElement.style.animation = ''; // Reset animation
  }, { once: true });
}

// Run the animations immediately
runAnimations();

// Set the interval to run the animations every hour
setInterval(runAnimations, 3600000); // 3600000 milliseconds = 1 hour
.text{
  width: 100%;
  position: relative;
  left: 50%;
  top: 45%;
  transform: translate(-50%, -50%);
  color:black;
  text-align: center;
  animation: herot 1s forwards;
  animation-iteration-count: 1;
  z-index: 1000;
}

@keyframes herot{
  0%{font-size: 15rem;}
  100%{font-size: 0px;}
}

@keyframes herolanding{
  0%{opacity: 0;}
  100%{opacity: 1;}
}


main{
  animation-name: herolanding;
  animation-duration: 1.1s;
  transition: ease;
}
<div class="text">
  <a> Hello </a>
</div>

<main class="text2">
 <a>body</aa>
</main>

2

Answers


  1. setInterval doesn’t persist its state if you refresh your page, navigate to another route (unless your app is an SPA), close the tab, or close the browser.

    So, in order to persist the countdown of the 1 hour non-animation, you need to store that state in localStorage or browser cookie, etc.

    My suggestion is to store the last animated time on user’s browser’s localStorage and before running the animation, first check that value and decide whether to run the animation or not.

    Here’s the pseudo-code using localStorage:

    function runAnimation() {
      const lastAnimatedAt = localStorage.getItem('lastAnimatedAt');
    
      if (lastAnimatedAt) {
        if (/* lastAnimatedAt was within last hour */) return;
      }
    
      // do animation
      // ...
      
      localStorage.setItem('lastAnimatedAt', /* current time in ISO string */);
    }
    

    Obviously, you can also improve your logic by adding setInterval just for the case the user opens the homepage and stays there for a long time.

    Login or Signup to reply.
  2. I think that best way to orchestrate it could be to use animation with duration matching your desired period and only progressively enhance it with animation-delay to align its first occurrence with some fixed point in the future.

    Example scaled down to single minute period:

    const w = 60 - (new Date).getSeconds();
    document.write(
      `Wait ${w} seconds for the first run.`
    );
    document.body.style.setProperty(
      '--secondsToNextWholeMinute',
      w
    );
    body {
      background-color: white;
      color: black;
      animation-duration: 60s;
      animation-iteration-count: infinite;
      animation-delay: calc(var(--secondsToNextWholeMinute, 0) * 1s);
      animation-name: a;
    }
    
    @keyframes a {
      1% {
        background-color: black;
        color: white;
      }
      0%,
      2% {
        background-color: white;
        color: black;
      }
    }
    Animation runs each minute.

    With this you’ll get guaranteed period without necessity of client-side persistence nor JavaScript intervals.

    The second (fallback) value for the --secondsToNextWholeMinute custom property can be used for cases client-side JavaScript does not run: 0 would mean the animation will run immediately after each reload and then in minute intervals from that point onwards.

    JS progressively enhances that delay to be shifted to whole user’s wall clock minute (in our case).

    Perhaps the trickiest part of this approach will be setting percentage fractions of the long 1h period to match seconds: 1s should be 0.0277777778% of one hour.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search