Preloader with a Counter and an Image

Share
Preloader with a counter and an image on Elementor

The goal is to display an animated loading screen with:

  • a counter that goes up to 100%,
  • a text transition (logo),
  • images that animate in/out,
  • then the smooth disappearance of the preloader to display the page.

Add the Code in Elementor

  1. In the WordPress dashboard, go to Elementor → Custom Code.
  2. Click on Add New.
  3. Name it, for example, “Preloader with a counter and an image”.
  4. Paste the code below.
  5. Set the location to <head>
  6. Publish.
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>

<style>
.layout {
  position: fixed;
  top: 0; left: 0;
  width: 100%; height: 100vh;
  background: #101012;
  display: flex; justify-content: center; align-items: center;
  z-index: 10000;
}
.overlay-content { width: 85%; }
.images { position: relative; height: 50vh; }
.img-contain { position: relative; width: 40%; height: 100%; margin: 0 auto; z-index: 1000; clip-path: polygon(0 0,100% 0,100% 100%,0% 100%); }
.img-contain img { position: absolute; top: 0; left: -110%; }

.text { position: relative; margin: 1em 0; clip-path: polygon(0 0,100% 0,100% 100%,0% 100%); }
.counter, .logo p {
  font-size: 10rem; text-align: center; text-transform: uppercase;
  font-family: "Sora", Sans-serif; font-weight: 700;
}
.counter p { line-height: 100%; }
.counter p span, .logo p span { position: relative; z-index: 9999; color: white; }
.logo { position: absolute; top: 0%; left: 50%; transform: translateX(-50%); }
.logo p { line-height: 100%; }
.logo p span { position: relative; top: 200px; opacity: 0; }
</style>

<div class="layout">
  <div class="overlay-content">
    <div class="images">
      <div class="img-contain">
        <img src="https://images.pexels.com/photos/18131871/pexels-photo-18131871.jpeg?w=800&auto=compress&cs=tinysrgb" alt="" />
        <img src="https://images.pexels.com/photos/18398708/pexels-photo-18398708.jpeg?w=800&auto=compress&cs=tinysrgb" alt="" />
        <img src="https://images.pexels.com/photos/18131896/pexels-photo-18131896.jpeg?w=800&auto=compress&cs=tinysrgb" alt="" />
      </div>
    </div>
    <div class="text">
      <div class="counter"><p>100%</p></div>
      <div class="logo"><p>HELLO</p></div>
    </div>
  </div>
</div>

<script>
document.addEventListener("DOMContentLoaded", function () {
  splitTextIntoSpans(".logo p");

  // entrée des images
  gsap.to(".img-contain img", {
    left: 0, stagger: 0.1,
    ease: "power4.out", duration: 1.5, delay: 4,
  });

  // sortie des images
  gsap.to(".img-contain img", {
    left: "110%", stagger: -0.1,
    ease: "power4.out", duration: 1.5, delay: 7,
  });
});

function splitTextIntoSpans(selector) {
  var element = document.querySelector(selector);
  if (element) {
    var text = element.innerText;
    element.innerHTML = text.split("").map(char => `<span>${char}</span>`).join("");
  }
}

function startLoader() {
  var counterElement = document.querySelector(".counter p");
  var currentValue = 0;

  function updateCounter() {
    if (currentValue === 100) { animateText(); return; }

    currentValue += Math.floor(Math.random() * 10) + 1;
    currentValue = currentValue > 100 ? 100 : currentValue;

    counterElement.innerHTML =
      currentValue.toString().split("").map(char => `<span>${char}</span>`).join("") + "<span>%</span>";

    setTimeout(updateCounter, Math.floor(Math.random() * 200) + 100);
  }

  function animateText() {
    setTimeout(() => {
      gsap.to(".counter p span", { top: "-400px", stagger: 0.1, ease: "power3.inOut", duration: 1 });
      gsap.to(".logo p span", { top: "0", opacity: 1, stagger: 0.1, ease: "power3.inOut", duration: 1 });
      gsap.to(".logo p span", { top: "-400px", stagger: 0.1, ease: "power3.inOut", duration: 1, delay: 3 });
      gsap.to(".layout", { opacity: 0, ease: "power3.inOut", duration: 1, delay: 4 });
    }, 300);
  }

  updateCounter();
}
startLoader();
</script>

Explanation of Elements

  • .layout → the full-screen preloading screen.
  • .counter → the text that displays the progress.
  • .logo → your word/logo that appears then disappears.
  • .img-contain img → the animated images for entry and exit.

Easily Customize

Here are the parts of the code you can modify:

  • Change the images: replace the URLs in the <img src="..."> tag.
  • Change the logo text: modify the content of <div class="logo"><p>HELLO</p></div>.
  • Durations and timings:
    • delay: 4 → when the images appear,
    • delay: 7 → when they disappear,
    • duration: 1.5 → duration of the image animation.
  • Counter speed: adjust the lines Math.floor(Math.random() * 200) + 100 → decrease the values for the counter to go faster.
  • Logo text effect: gsap.to(".logo p span", { top: "0", opacity: 1, ... }) → you can play with top, opacity, and ease.

Practical Tips

  • Compress the preloader images (otherwise it can slow down the site).
  • Choose a suitable background (background: #101012;) to match your brand guidelines.
  • If you want the preloader to display only once per session, you can add a small script with sessionStorage.
Category
Compatible
WordPress, Elementor
Updated
17 Sep 2025

Built with Elementor

Host, create, and grow your dream website with the leading platform for WordPress.

Inspire your Elementor projects with 1 animation per week.

Thank you for subscribing!