Search code examples
htmlcsscss-shapes

How can I transform a line into two and rotate with css


I want to have a straight line in my header, and then a few seconds after the page loads, I want those lines to slowly move down until they look like the one in the image below:

enter image description here

I thought of using css transform property to rotate two rotate two divs, but that does not seem to be a solution as you can see the result in my pen here

HTML:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<div id="big">
  <div class="arrow-box">
    <div class="line line-1"></div>    
    <div class="line line-2"></div>

  </div>
</div>

CSS:

#big{
  background: red;
  height: 200px;
}
.arrow-box{
  max-width: 200px;
  margin: 0 auto;
  padding-top: 10px;

}
.line{
  background: white;
  width: 60px;
  height: 1px;
}

.line-1{
  transform: rotate(20deg);
}

.line-2{
  transform: rotate(-20deg);
}

How can I make a/the line look like the icon on the image after the page loads?


Solution

  • You could do this using css animation. You could use rotateZ transform to create arrow shape and also scale to keep increasing width of the lines as animation goes.

    You also need to use transform-origin for both parts to transform at the right point.

    .line {
      position: relative;
      width: 100px;
    }
    
    .line:after,
    .line:before {
      background: black;
      position: absolute;
      content: "";
      height: 2px;
      width: 50%;
      bottom: 0;
    }
    
    .line:before {
      left: 0;
      animation: moveBefore 1s linear forwards;
      transform-origin: center left;
    }
    
    .line:after {
      right: 0;
      animation: moveAfter 1s linear forwards;
      transform-origin: center right;
    }
    
    @keyframes moveBefore {
      0% {
        transform: rotateZ(0) scale(1, 1);
      }
      50% {
        transform: rotateZ(15deg) scale(1.05, 1);
      }
      
      100% {
        transform: rotateZ(30deg) scale(1.16, 1);
      }
    }
    
    @keyframes moveAfter {
      0% {
        transform: rotateZ(0) scale(1, 1);
      }
      50% {
        transform: rotateZ(-15deg) scale(1.05, 1);
      }
      
      100% {
        transform: rotateZ(-30deg) scale(1.16, 1);
      }
    }
    <div class="line"></div>

    You could also do this with svg using line element and some javascript to move y position left and right line parts. To increase angle gradually you can use setInterval method.

    let step = 0;
    const left = document.querySelector('.left-line');
    const right = document.querySelector('.right-line');
    
    function move(el, prop, size) {
      el.setAttribute(prop, +el.getAttribute(prop) + size);
    }
    
    setInterval(() => {
      if (step <= 40) {
        move(left, 'y2', 0.8);
        move(right, 'y1', 0.8)
        step += 1;
      }
    }, 30)
    <svg xmlns="http://www.w3.org/2000/svg">
      <line class="left-line" x1="0" y1="20" x2="40" y2="20" stroke="black" />
      <line class="right-line" x1="40" y1="20" x2="80" y2="20" stroke="black" />
    </svg>