Home > database >  How do I make a keyframe translate animation seamless?
How do I make a keyframe translate animation seamless?

Time:07-18

I'm trying to animate a border of a logo that's just two letters. I can't figure out how to animate the border of my logo so I resorted to creating 4 divs with different borders (top, down, left, right) and animate them one by one. However, the animation isn't seamless as it keeps snapping back to its original location, and the div wrapper I created can't contain the animation overflowing outside.

I'm new to css animations so I'm wondering if there is a way to make an animated moving dashed border for a logo.

Here's my jsfiddle (first time using jsfiddle so let me know if the link doesnt work)

/* div border for top */
.logo-border-up {
  background-color: transparent;
  border-top: 10px dashed #252422;
  width: 5rem;
  height: 10px;

  position: absolute;

  animation: animate-up 1s linear infinite;
}

@keyframes animate-up {
  0% {
    transform: translatex(0%);
  }

  100% {
    transform: translatex(100%);
  }

Edit: I managed to solve it. Thanks to this stackoverflow Dashed border animation in css3 animation

CodePudding user response:

To eliminate the animation snapping back to the beginning when it reaches the end, a minor modification can be applied to your existing code:

position: relative

Your animation will now be contained within <div >.

CodePudding user response:

As the moving border is just a visual clue rather than part of the content here is a snippet which draws and animates it using pseudo elements rather than putting extra elements into the DOM.

linear-gradients are used to draw background images of dashes which are repeated in the horizontal or vertical direction as appropriate.

The background positions are then animated using CSS keyframes.

The after and before pseudo elements are made slightly bigger than the wrapper and positioned so the borders are slightly outside.

The logo characters are centered within the wrapper using flex.

Sizing of the dashes is done relative to the size of the wrapper rather than mixing px and rem values which can make things difficult to adjust relatively (rem can be changed for example).

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">

  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@400;500&display=swap" rel="stylesheet">

  <link rel="stylesheet" href="style.css">
  <title>Logo</title>
  <style>
    body {
      background-color: #FFFCF2;
    }
    
    .logo-wrapper {
      width: 5rem;
      aspect-ratio: 1 / 1;
      roverflow: hidden;
      position: relative;
      box-sizing: border-box;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    
    .logo {
      font-family: 'Poppins', sans-serif;
      font-size: 3rem;
      text-decoration: none;
      font-weight: 700;
      color: #252422;
      /* border: 0.5rem dashed #252422; */
    }
    
    .logo-wrapper::before,
    .logo-wrapper::after {
      content: '';
      position: absolute;
      top: -5%;
      left: -5%;
      width: 110%;
      aspect-ratio: 1 / 1;
      overflow: hidden;
      animation: var(--name) 2s linear infinite;
    }
    
    .logo-wrapper::before {
      background-image: linear-gradient(to right, #252422 0 50%, transparent 50% 100%), linear-gradient(to right, transparent 0 50%, #252422 50% 100%);
      background-size: 25% 6.25%;
      background-repeat: repeat no-repeat;
      background-position: 0 0, 100% 100%;
      --name: horizMove;
    }
    
    .logo-wrapper::after {
      background-image: linear-gradient(#252422 0 50%, transparent 50% 100%), linear-gradient(transparent 0 50%, #252422 50% 100%);
      background-size: 6.25% 25%;
      background-repeat: no-repeat repeat;
      background-position: 100% 0, 0 100%;
      --name: vertMove;
    }
    
    @keyframes horizMove {
      0% {
        background-position: 0 0, 100% 100%;
      }
      100% {
        background-position: 100% 0, 0 100%;
      }
    }
    
    @keyframes vertMove {
      0% {
        background-position: 100% 0, 0 100%;
      }
      100% {
        background-position: 100% 100%, 0 0;
      }
    }
    /*
.logo-border-up {
  background-color: transparent;
  border-top: 10px dashed #252422;
  width: 5rem;
  height: 10px;

  position: absolute;

  animation: animate-up 1s linear infinite;
}
*/
    
    @keyframes animate-up {
      0% {
        transform: translatex(0%);
      }
      100% {
        transform: translatex(100%);
      }
    }
    
    @keyframes animate-down {
      0% {
        transform: translatex(0%);
      }
      100% {
        transform: translatex(-100%);
      }
    }
  </style>
</head>

<body>
  <nav>
    <div >
      <div ></div>
      <a href="" >bt</a>
    </div>
  </nav>
</body>

</html>

Note: setting all background colors as is done in the code given in the question can lead to unexpected results. This snippet has removed that and put the background color on the body.

  • Related