3

I do have a feeling that this post will get a lot more negative responses as compared to positive ones but it's ok, one response containing the correct answer is worth it!

Ok, this feature is a bit hard to explain in words. I want to add a loading animation whenever a button from the navigation bar is clicked. It should take up 100vh height and 100vw width and should be from right to left and then disappear. (Need help with both CSS and js, maybe HTML too)

I suggest checking out https://www.jacekjeznach.com using a laptop. You can see the really cool loading animation going on when you click on any of the options from the main navigation bar situated on the left side of the website I know I can't make the exact effect without becoming an expert in web development. I even checked out the GitHub repo of his portfolio but there was no index.html there. A lot of .jsx files (ReactJS) though.

I know the basics of HTML, CSS, JS and never worked with any frameworks (not been more than 2 months since I started learning web dev) but I need help with this project because it is a college assignment. I chose to make an eLearning website, similar to what this guy teaches(using webflow and few backend tools like MemberStack, Airtable & Zapier): https://www.youtube.com/watch?v=1-_rGcBQLzE&list=PL23ZvcdS3XPINPbP6y06tcLY_rZLi8euf

I am allowed to use any frameworks but I am not allowed to use any website building tools(I can't explain the complex javascript code if I ignore the instructions and use it anyway). Connection to the backend is a plus point but not a requirement. Currently I am just making the basic homepage of the website and its code is:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Document</title>
  <style>
    .slide {
      width: 97vw;
      height: 97vh;
      margin: auto;
    }
    .wrapper {
      display: flex;
      flex-direction: row;
      width: 500vw;
      transform: rotate(90deg) translateY(-97vh);
      transform-origin: top left;
    }
    .one {
      background: #efdefe;
    }
    .two {
      background: #a3f3d3;
    }
    .three {
      background: rgb(245, 228, 228);
    }
    .four {
      background: #ffddcc;
    }
    .five {
      background: rgb(245, 241, 225);
    }
    .outer-wrapper {
      width: 97vh;
      height: 97vw;
      margin: auto;
      transform: rotate(-90deg) translateX(-97vh);
      transform-origin: top left;
      overflow-y: scroll;
      overflow-x: hidden;
      position: absolute;
      scrollbar-width: none;
      -ms-overflow-style: none;
    }
    ::-webkit-scrollbar {
      display: none;
    }
    .wrap-class {
      margin-left: 1vw;
      display: flex;
      align-items: middle;
      justify-content: space-around;
      height: 100vh;
      width: 10vw;
      align-content: space-between;
      justify-content: center;
      position: fixed;
      flex-direction: column;
      vertical-align: center;
    }
    /*Code for the horizontal navbar on left side: */
    .navbar {
      width: 10vw;
      height: auto;
    }
    .margin1vh {
      margin-top: 0.7vh;
      margin-bottom: 0.7vh;
    }
    a:-webkit-any-link {
      text-decoration: none;
      color: white;
      padding: 1vw;
      padding-left: 0;
      display: block;
      /* padding: 3vh 1vw 3vh 1; */
      height: 100%;
      width: 100%;
    }
    button {
      background-color: black;
      display: block;
      width: 100%;
      box-shadow: inset 2px 2px black, 4px 4px 0 grey;
    }
    button:hover {
      transform: scale(1.1);
    }
    html {
      background-color: black;
      /* filter: invert(1); */
      scroll-behavior: smooth;
    }
    /*This code allow us to add linear gradient to a text*/
    p,
    h1 {
      display: block;
      margin-left: 31%;
      margin-top: 5000px !important;
      max-width: 1vw;
      background: rgb(2, 0, 36);
      background: radial-gradient(circle,
          rgba(2, 0, 36, 1) 0%,
          rgba(165, 106, 108, 1) 0%,
          rgba(175, 99, 99, 1) 0%,
          rgba(148, 116, 123, 1) 0%,
          rgba(91, 153, 175, 1) 0%,
          rgba(62, 172, 200, 1) 0%,
          rgba(194, 226, 162, 1) 0%,
          rgba(0, 212, 255, 1) 0%,
          rgba(18, 255, 21, 1) 14%,
          rgba(230, 65, 87, 1) 29%,
          rgba(194, 185, 52, 1) 46%,
          rgba(43, 83, 210, 1) 64%,
          rgba(59, 221, 55, 1) 80%,
          rgba(222, 85, 217, 1) 92%);
      -webkit-background-clip: text;
      background-clip: text;
      /*for compatibility with safari browser*/
      -webkit-text-fill-color: transparent;
      display: inline;
      background-size: 300%;
      animation: bg-animation 17s infinite;
    }
    @keyframes bg-animation {
      0% {
        background-position: left;
      }
      50% {
        background-position: right;
      }
      100% {
        background-position: left;
      }
    }
    /*Now, let's add the animation that happens when a button of fixed position is clicked: */
    .animation-on-click {
      min-width: 100vw;
      min-height: 100vh;
      background-color: black;
      animation-name: animate;
      animation-duration: 2s;
      animation-iteration-count: 1;
      overflow: visible;
    }
    @keyframes animate {
      0% {
        transform: translateX(100%);
      }
      100% {
        transform: translateX(-100%);
      }
    }
  </style>
</head>

<body>
  <div class="outer-wrapper">
    <div class="wrapper">
      <div class="slide one" id="one">
        <div>
          <br />
          <br />
          <h1>Welcome to the website</h1>
        </div>
      </div>
      <div class="slide two" id="two">
        <div>
          <br />
          <br />
          <h1>Welcome to the eLearning website</h1>
        </div>
      </div>
      <div class="slide three" id="three"></div>
      <div class="slide four" id="four"></div>
      <div class="slide five" id="five"></div>
    </div>
  </div>
  <div class="wrap-class">
    <div class="navbar">
      <button>
        <a href="#one" onclick="clicked()">Home</a>
      </button>
      <div class="margin1vh"></div>
      <button>
        <a href="#two">About</a>
      </button>
      <div class="margin1vh"></div>
      <button>
        <a href="#three">Website</a>
      </button>
      <div class="margin1vh"></div>
      <button>
        <a href="#four">Support</a>
      </button>
      <div class="margin1vh"></div>
      <button>
        <a href="#five" style="scroll-behavior: smooth !important">Contact</a>
      </button>
    </div>
  </div>
  <script>
    function clicked() {
      var element = document.getElementById("one");
      element.classList.add("animation-on-click");
      setTimeout(function () {
        element.classList.remove("animation-on-click");
      }, 2000);
    }
  </script>
</body>
</html>

I just need a loading animation (without a loading bar should also work) but it should be done on the whole screen. I think I might change the background color of all the elements in CSS horizontal flexbox to black also because black is the best background and it will allow me to change width ad height attributes of the .slide class and translateX and translateY functions from 97vw, 97vh to 100vw, 100vh (as they were in the original code)

Btw, I have combined the codes of CSS and JS files in the HTML file here to be able to share the code here on StackOverflow. You can visit https://github.com/shubham-garg1/web-project to check the GitHub code. I have also published the work done till now online so you can go to http://www.elearningweb.tk and check the sources files.

Any help is appreciated, thanks.

Shubham Garg
  • 459
  • 3
  • 10
  • Unless you're actually loading something this is a bad idea. It's annoying UX. Did you notice the loading animation for that site you referenced lasted the same time irrelevant of what the page showed or what data was loaded? – Andy Jun 07 '21 at 18:20
  • 1
    Yes @Andy , I noticed the loading animation for that site lasted the same time irrelevant of what the page showed or what data was loaded and I want to implement it in this website because 1-2 seconds animation time won't annoy any user. And of course, it's not an official website that is capable of earning any real money... – Shubham Garg Jun 07 '21 at 18:40
  • 1
    Well, it annoyed me. – Andy Jun 07 '21 at 19:08

1 Answers1

1

They're actually pretty easy to do if you just want a spinner, but a "loading" animation should be tied to a "loading" process. Without making any assumptions, lets consider some native Javascript Ajax call...

var xmlhttp = new XMLHttpRequest();

document.getElementById("myLoader").style.display = "block";
xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == XMLHttpRequest.DONE) {   
    if (xmlhttp.status == 200) {
      document.getElementById("myLoader").style.display = "none";
    }
  }
};

xmlhttp.open("GET", "https://www.httpbin.org/get", true);
xmlhttp.send();

You can just throw an animation inside your myLoader div... If you want to get a little fancy, you can use Javascript to animate it after you load it.

Let's grab some code: I'll grab it from https://www.w3schools.com/howto/howto_css_flip_card.asp. It's just a card flip on hover, but I've removed the hover part.

The important part here is in the flip-card-inner portion of the CSS. It's going to dictate to Javascript how long the animation process should take. If you want a longer one, just adjust the transition value.

JsFiddle: https://jsfiddle.net/L1fk0nhm/

<style>
.flip-card {
  background-color: transparent;
  width: 300px;
  height: 200px;
  border: 1px solid #f1f1f1;
  perspective: 1000px; 
}

.flip-card-inner {
  position: relative;
  width: 100%;
  height: 100%;
  text-align: center;
  transition: transform 0.8s;
  transform-style: preserve-3d;
}

.flip-card-front, .flip-card-back {
  position: absolute;
  width: 100%;
  height: 100%;
  -webkit-backface-visibility: hidden; /* Safari */
  backface-visibility: hidden;
}

.flip-card-front {
  background-color: #bbb;
  color: black;
}

.flip-card-back {
  background-color: dodgerblue;
  color: white;
  transform: rotateY(180deg);
}
</style>
<div class="flip-card">
  <div id="myLoader" class="flip-card-inner">
    <div class="flip-card-front">
       I'm hiding stuff that's loading!
    </div>
    <div id="loadedStuff" class="flip-card-back">

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

We can actually have it flip on load, using Javascript after the inside of the element has loaded.

var xmlhttp = new XMLHttpRequest();

xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == XMLHttpRequest.DONE) {   
    if (xmlhttp.status == 200) {
      document.getElementById("loadedStuff").innerHTML = xmlhttp.responseText;
      animatedCardRotation(document.getElementById("myLoader"), 0, 180);
    }
  }
};

xmlhttp.open("GET", "https://www.httpbin.org/get", true);
xmlhttp.send();

function animatedCardRotation (Element, startDegree, endDegree) {
  if(startDegree < endDegree ) {
    startDegree += 10;
    Element.style.transform = `rotateY(${startDegree}deg)`;
    requestAnimationFrame( () => this.animatedCardRotation(Element, startDegree, endDegree) );
  }
}

Combining requestAnimationFrame here really adds a lot to your CSS animations. You can virtually do any kind of CSS transformation here and if you have something that loads in chunks, it can help you build a very accurate "loading bar".

Any Day
  • 418
  • 2
  • 9
  • 1
    Thanks for your efforts [Any Day](https://stackoverflow.com/users/1832943/any-day) but this is very far from what I wanted. However, I think I might just drop the idea and follow this one but without using that API. Just the w3schools thing with a transition effect when user clicks on the option. Should look good – Shubham Garg Jun 08 '21 at 04:41
  • You might find it hard to believe, but with a little thought, this is actually what you want. I just used a different example. The `animatedCardRotation` function I provided you can be used for any kind of css transform not just rotations. The speed of that transform is dictated by the css transition value. (such as a bar being loaded and a div removed after animation) – Any Day Jun 08 '21 at 11:54
  • The `XMLHttpRequest` might be useful to you as well. Just throw some HTML (without the beginning html or body tags) on another page inside your root directory and use the `XMLHttpRequest` to do a request to that local page, then put the contents inside your card. – Any Day Jun 08 '21 at 12:06