CSS animation. Slide in for 10 seconds and then move up and down infinitely

Viewed 658

I currently have an image "floating". So it moves up and down over 10 seconds. But what I'd really like it to do is to do is slide in right from off canvas over 10 seconds and then float infinitely.

The code I have now just makes it float up and down and I'm struggling to add the slide in part. I'm new to CSS animation so I'd appreciate any help.

This is what I have so far.

.shake-vertical {
    -webkit-animation: shake-vertical 15s cubic-bezier(0.455, 0.030, 0.515, 0.955) infinite both;
    animation: shake-vertical 15s cubic-bezier(0.455, 0.030, 0.515, 0.955) infinite both;
}

@-webkit-keyframes shake-vertical {
    0%,
    100% {
        -webkit-transform: translateY(0);
        transform: translateY(0);
    }

    10%,
    30%,
    50%,
    70% {
        -webkit-transform: translateY(-8px);
        transform: translateY(-8px);
    }

    20%,
    40%,
    60% {
        -webkit-transform: translateY(8px);
        transform: translateY(8px);
    }

    80% {
        -webkit-transform: translateY(6.4px);
        transform: translateY(6.4px);
    }

    90% {
        -webkit-transform: translateY(-6.4px);
        transform: translateY(-6.4px);
    }
}

@keyframes shake-vertical {
    0%,
    100% {
        -webkit-transform: translateY(0);
        transform: translateY(0);
    }

    10%,
    30%,
    50%,
    70% {
        -webkit-transform: translateY(-8px);
        transform: translateY(-8px);
    }

    20%,
    40%,
    60% {
        -webkit-transform: translateY(8px);
        transform: translateY(8px);
    }

    80% {
        -webkit-transform: translateY(6.4px);
        transform: translateY(6.4px);
    }

    90% {
        -webkit-transform: translateY(-6.4px);
        transform: translateY(-6.4px);
    }
}

2 Answers

You can set the object with a slidein animation for 10 seconds and on the animationend event change its class to your shake animation.

Add CSS something like this:

@keyframes slidein {
0% {
  transform: translateX(100vw);
}
100% {
  transform: translateX(50vw);
}
}
   .slidein {
      animation-name:slidein;
      animation-duration:10s;
      animation-fill-mode: follow;
    }

    .shake {
      animation-name: shake-vertical;
      animation-duration: 10s;
      animation-iteration-count: infinite;
    }

}

and JavaScript something like this

  obj.addEventListener("animationend", function () {
    obj.classList.remove('slidein');
    obj.classList.add('shake');
  });

Example with a simple sliding square in the Snippet.

<!DOCTYPE html>
<html>
<head>
<style>
@keyframes slidein {
0% {
  transform: translateX(100vw);
}
100% {
  transform: translateX(50vw);
}
}

@keyframes shake-vertical {
    0%,
    100% {
        -webkit-transform: translateY(0);
        transform: translateY(0);
    }

    10%,
    30%,
    50%,
    70% {
        -webkit-transform: translateY(-8px);
        transform: translateY(-8px);
    }

    20%,
    40%,
    60% {
        -webkit-transform: translateY(8px);
        transform: translateY(8px);
    }

    80% {
        -webkit-transform: translateY(6.4px);
        transform: translateY(6.4px);
    }

    90% {
        -webkit-transform: translateY(-6.4px);
        transform: translateY(-6.4px);
    }
}
#obj {
  position: relative;
  width: 50px;
  height: 50px;
  top: 50px;
  background-color:magenta;
  animation-delay:0s;
}

.slidein {
  animation-name:slidein;
  animation-duration:10s;
}

.shake {
  left: 50vw;
  animation-name:shake-vertical;
  animation-duration: 10s;
  animation-iteration-count: infinite;
}

</style>
</head>
<div id="obj" class="slidein"></div>
<script>
  var obj = document.getElementById('obj');
  obj.addEventListener("animationend", function () {
    obj.classList.remove('slidein');
    obj.classList.add('shake');
  });
</script>
</html>

Considering your image has a class of ball. You can add this CSS to your Existing CSS:

@keyframes slide-in {
    from{
        margin-right: -100px;
    }
    to{
        margin-right: 0;
    }
}
.ball{
    width: 100px;
    height: 100px;
    border-radius: 50%;
    background-color: red;
    float: right;
    animation:  slide-in 10s forwards,/*forwards keeps the ball at final position*/
                shake-vertical 15s infinite 10s both;
                /*
                 * Two animations applied
                 * comma separated
                 * shake-vertical has a 10 second delay specified by '10s'
                 * the delay should be same as the duration of first animation
                */
}

I have added comments for explanation but if you need more, feel free to comment.

Related