0

With this CSS I make the animation of the three Divs, said animation consists of putting the second div on top of the first, passing the first one back and moving the third div to the second position and thus showing all the divs one by one.

html, body { position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; }
.card{
  position: absolute;
  transform: scale(0.75);
  height:200px;
  width:300px;
  animation-name: cards-animation;
  animation-iteration-count:infinite;
  animation-duration: 6s;
}
.card-blue{
  background-color:blue;
  animation-delay: 1s;
} 
.card-red{
  background-color:red;
  animation-delay: 3s;
}
.card-green{
  background-color:green;
  animation-delay: 5s;
}

@keyframes cards-animation {
  0%  {
    transform: scale(0.75) ;
    z-index: 0;
  }
  9% {
    transform: scale(0.9) translateY(40px);
    z-index: 2;
  }
  33% {
    transform: scale(0.9) translateY(40px);
    z-index: 2;
  }
  42% {
    transform: translateY(80px);
    z-index: 3;
  } 
  66% {
    transform: translateY(80px);
    z-index: 3;
    opacity: 1;
  }
  75% {
    transform: translateY(130px);
    opacity: 0;
  }
  80% {
    transform: scale(0.75) translateY(40px);
    opacity: 0;
    z-index: 1;
  } 
  90% {
    transform: scale(0.75);
    opacity: 1;
    z-index: 1;
  }
}
<div class="card card-blue"></div>
<div class="card card-red"></div>
<div class="card card-green"></div>

What I need is to know how I can pass the CSS code that makes that animation to a Javascript code, I mean to have the same animation but instead of doing it with CSS, do it with Javascript in order to have more control over it.

<div class="card card-blue"></div>
<div class="card card-red"></div>
<div class="card card-green"></div>
1
  • 2
    People will disapprove of this question in its current form - you should include specifically what you want to achieve by using javascript. That way we'll understand if you really need a js solution, or if your css can be modified. Commented Feb 14, 2021 at 5:34

2 Answers 2

3

Javascript can theoretically do anything that css can do - it's just a lot (a lot) more work in most cases. For animations, the tool you need is window.requestAnimationFrame(callback) - this allows you to queue an animation task for the next rendering frame. By recursively calling window.requestAnimationFrame you can perform updates on every frame, and by using performance.now() to measure the time you can perform updates based on real time.

For example, let's animate the left property with window.requestAnimationFrame, performance.now, and Math.sin:

let applyLeftSinAnimation = (item, hz, px) => {
  
  // `hz` controls oscillations per second
  // `px` controls oscillation magnitude in pixels

  // Returning `result` from this function provides a way to stop the
  // animation:
  // let controlAnim = applyLeftSinAnimation(someElem);
  // controlAnim.stop(); // Stops the animation
  let result = {
    active: true,
    stop: () => result.active = false
  };
  
  // Get initial time
  let ms = performance.now();
  
  // We can compile a number of factors into a single coefficient
  let sinMult = Math.PI * 2 * hz * (1/1000);
  
  // Add an async animation loop to the event loop
  (async () => {
    
    while (result.active) {
      
      // Wait for the next animation frame to be ready
      await new Promise(r => window.requestAnimationFrame(r));
      
      // Get millisecond delta
      let dms = performance.now() - ms;
      
      // Apply custom animation based on millisecond delta
      item.style.left = (px * Math.sin(dms * sinMult)).toFixed(2) + 'px';
      
    }
    
  })();
  
  return result;
  
};

applyLeftSinAnimation(document.querySelector('.item'), 1, 100);
html, body { position: absolute; left: 0; right: 0; top: 0; bottom: 0; overflow: hidden; }
.item {
  position: absolute;
  left: 0; top: 50%; margin-left: 50%; margin-top: -25px;
  width: 50px; height: 50px;
  box-shadow: inset 0 0 0 1px #000;
}
<div class="item"></div>

Sign up to request clarification or add additional context in comments.

Comments

1

 var elems = document.getElementsByClassName('item');
        var countItem = 1;
        var totalSecond = 0;
        myFunction();
        function myFunction() {
            for (var i = 0; i < countItem; i++) {

                var transY = parseFloat(elems[i].getAttribute("transy"));
                var margin = parseFloat(elems[i].getAttribute("margin"));
                var get = elems[i].getAttribute("get");
                if (get === "n") {
                    transY = transY + 1;
                    margin = margin + 1;

                    if (transY >= 100 && transY < 130)
                        zindex = "1";
                    else if (transY >= 130 && transY < 160)
                        zindex = "2";
                    else if (transY >= 160 && transY <= 190)
                        zindex = "3";
                }
                else {
                    transY = 100;
                    margin = margin - 2;

                    if (margin < 0) {
                        if (get === "n") {
                            elems[i].setAttribute("get", "r");
                        }
                        else {
                            elems[i].setAttribute("get", "n");
                        }
                    }
                    zindex = "0";
                }

                elems[i].style.width = (transY) + 'px';
                elems[i].style.height = (transY) + 'px';
                elems[i].style.opacity = 1;
                elems[i].style.zIndex = zindex;
                elems[i].style.marginTop = margin + 'px';
                elems[i].style.marginLeft = (transY * .5) + 'px';
                if (transY >= 190) {
                    if (get === "n") {
                        elems[i].setAttribute("get", "r");
                    }
                    else {
                        elems[i].setAttribute("get", "n");
                    }
                }


                elems[i].setAttribute("transy", transY);
                elems[i].setAttribute("margin", margin);




            }
            totalSecond = totalSecond + 20;
            if (totalSecond > 1000) {
                if (countItem < elems.length) {
                    countItem = countItem + 1;
                }
                totalSecond = 0;
                myVar = setTimeout(myFunction, 150);
            }
            else
                myVar = setTimeout(myFunction, 20);
        }
        .item {
            position: absolute;
            top: 20%;
            width: 100px;
            height: 100px;
            box-shadow: inset 0 0 0 1px #000;
            background: white;
            opacity: 1;
            margin-top: 0;
        }
<div style="height:700px;width:300px;background:black;position:relative;margin:auto;">
    <div class="item" transy="100" get="n" margin="0" style="background:blue;opacity:0;"></div>
    <div class="item" transy="100" get="n" margin="0" style="background:green;opacity:0;"></div>

    <div class="item" transy="100" get="n" margin="0" style="background:red;opacity:0;"></div>

</div>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.