Search code examples
javascripthtmlcssanimationcss-animations

How to transition text along with a circle in CSS animation?


The code I am developing is for mobile site and the animation I expect is as following: Firstly a bigger circle appears such that it covers the whole screen looking like a splash screen and afterwards the bigger circle will transition into smaller circle towards bottom left. Along with that image inside the bigger circle will transit towards bottom left.

The Problem is circle is transitioning properly but the text is not going to bottom left properly it kind of goes to left and then goes down. Below is the code that I tried.

setTimeout(function() {
  let i = document.getElementById("test");
  let d = document.getElementById("icon-img");

  i.classList.add("active");
  d.classList.add("active");
}, 2000);
.test {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 40px;
  transition: all 3s ease;
  background: gray;
  transform: scale(100);
  border-radius: 30px;
  left: 20px;
  bottom: 20px;
}

.test.active {
  transform: scale(1);
  transition: all 2s ease;
  left: 20px;
  bottom: 20px;
}

.wrapper {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100vh;
}

.myclass {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.before {
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 2s ease-in-out;
  width: 50%;
  height: 50%;
  position: fixed;
  font-size: 50px;
}

.before.active {
  left: 20px;
  bottom: 20px;
  width: 40px;
  height: 40px;
  font-size: 15px;
  position: fixed;
  transform: translate(0, 0);
}
<div class="wrapper">
  <div id="test" class="test"></div>
  <div class="myclass">
    <img src="./logo.svg" id="icon-img" class="before"></img>
  </div>
</div>


Solution

  • A problem is that some properties do not have an initial value set so there is nothing for them to transition from. So you get a sort of jump effect.

    This snippet removes the flex used for centering the image and instead uses left and bottom in conjunction with translation to center it initially.

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1" />
      <title></title>
      <style type="text/css">
        .test {
          position: fixed;
          left: 0;
          bottom: 0;
          width: 40px;
          display: flex;
          align-items: center;
          justify-content: center;
          height: 40px;
          transition: all 3s ease;
          background: gray;
          transform: scale(100);
          border-radius: 30px;
          left: 20px;
          bottom: 20px;
        }
        
        .test.active {
          transform: scale(1);
          transition: all 2s ease;
          left: 20px;
          bottom: 20px;
        }
        
        .wrapper {
          position: relative;
          display: flex;
          align-items: center;
          justify-content: center;
          height: 100vh;
        }
        
        .myclass {
          width: 100%;
          height: 100%;
        }
        
        .before {
          display: flex;
          align-items: center;
          justify-content: center;
          transition: all 2s ease-in-out;
          width: 50%;
          height: 50%;
          position: fixed;
          font-size: 50px;
          left: 50%;
          bottom: 50%;
          transform: translate(-50%, 50%);
          background: pink;
        }
        
        .before.active {
          left: 20px;
          bottom: 20px;
          width: 40px;
          height: 40px;
          font-size: 15px;
          position: fixed;
          transform: translate(0, 0);
        }
      </style>
    </head>
    
    <body>
      <div class="wrapper">
        <div id="test" class="test"></div>
        <div class="myclass">
          <img src="./logo.svg" id="icon-img" class="before"></img>
        </div>
      </div>
      <script>
        setTimeout(function() {
          let i = document.getElementById("test");
          let d = document.getElementById("icon-img");
    
          i.classList.add("active");
          d.classList.add("active");
        }, 2000);
      </script>
    </body>
    
    </html>

    Note: the image is given a background of pink as no actual image was supplied, just so we can see its position and size.

    Two transition times are used in the question - 2s and 3s. This means the image and text arrive at different times. I've kept that in the snippet but maybe the same time was intended?