user3080392
user3080392

Reputation: 1224

css animation on load and on hover

How do I start a css animation on page load and trigger the same animation on the same element with hover. On page load, the animation will iterate 1 time. Once it stops, I will be able to trigger it repeatedly with hover. I attempted to rework the code at different CSS animation on load and on hover but I was unable to replicate it. I also pieced together the following, but only the on load animation works, not the hover:

img {
    -webkit-animation: anim 10s linear;
    -webkit-animation-iteration-count: 1;    
    animation: anim 10s linear;
    animation-iteration-count: 1; 
    height: 50px;
    width: 50px;
}

img:hover {
    -webkit-animation: anim 10s infinite linear ;           
    animation: anim 10s infinite linear;        
    height: 50px;
    width: 50px;
}

@-webkit-keyframes anim {
    from { -webkit-transform: rotateX(0deg); }
    to { -webkit-transform: rotateX(360deg); }
}

@keyframes anim {
    from { transform: rotateX(0deg); }
    to { transform: rotateX(360deg); }
}

Based on Vitorino Fernandes's suggestion about using a parent div for the hover, I got it to work:

img {
    -webkit-animation: anim 10s linear;
    -webkit-animation-iteration-count: 1;    
    animation: anim 10s linear;
    animation-iteration-count: 1;

    height: 50px;
    width: 50px;
}

div:hover {
    -webkit-animation: anim 10s infinite linear;      
    animation: anim 10s infinite linear;    
    height: 50px;
    width: 50px;
}

@-webkit-keyframes anim {
    from { -webkit-transform: rotateX(0deg); }
    to { -webkit-transform: rotateX(360deg); }
}

@keyframes anim {
    from { transform: rotateX(0deg); }
    to { transform: rotateX(360deg); }
}

the html:

<div>
    <img src="testpic.jpg"/>
</div>

Upvotes: 2

Views: 4377

Answers (4)

Vitorino fernandes
Vitorino fernandes

Reputation: 15951

you can add hover event for the parent and load event for img

img {
  -webkit-animation: anim 10s linear;
  -webkit-animation-iteration-count: 1;
  animation: anim 10s linear;
  animation-iteration-count: 1;
  height: 50px;
  width: 50px;
}
div:hover {
  display: inline-block;
  -webkit-animation: anim 10s infinite linear;
  -webkit-animation-iteration-count: 1;
  animation: anim 10s linear;
  animation-iteration-count: 1;
  height: 50px;
  width: 50px;
}
@-webkit-keyframes anim {
  0%, 100% {
    -webkit-transform: rotateX(0deg);
  }
  50% {
    -webkit-transform: rotateX(360deg);
  }
}
<div>
  <img src="https://via.placeholder.com/350x150" />
</div>

Upvotes: 1

mateostabio
mateostabio

Reputation: 1028

I've put together a CodePen with a CSS-only fix and one with 2 lines of jQuery to fix the on-page load issue. Continue reading to understand the 2 solutions in a simpler version.

https://codepen.io/MateoStabio/pen/jOVvwrM

If you are searching how to do this with CSS only, Xaltar's answer is simple, straightforward, and is the correct solution. The only downside is that the animation for the mouse out will play when the page loads. This happens because to make this work, you style your element with the OUT animation and the :hover with the IN animation.

svg path{
    animation: animateLogoOut 1s;
}
svg:hover path{
    animation: animateLogoIn 1s;
}

@keyframes animateLogoIn {
    from {stroke-dashoffset: -510px;}
    to {stroke-dashoffset: 0px;}
}
@keyframes animateLogoOut {
    from {stroke-dashoffset: 0px;}
    to {stroke-dashoffset: -510px;}
}

Some people found this solution to be useless as it played on page load. For me, this was the perfect solution. But I made a Codepen with both solutions as I will probably need them in the near future.

If you do not want the CSS animation on page load, you will need to use a tiny little script of JS that styles the element with the OUT animation only after the element has been hovered for the first time. We will do this by adding a class of .wasHovered to the element and style the added class with the OUT Animation.

jQuery:

$("svg").mouseout(function() {
    $(this).addClass("wasHovered");
 });

CSS:

svg path{

}

svg.wasHovered path{
    animation: animateLogoOut 1s;
}

svg:hover path{
    animation: animateLogoIn 1s;
}

@keyframes animateLogoIn {
    from {stroke-dashoffset: -510px;}
    to {stroke-dashoffset: 0px;}
}
@keyframes animateLogoOut {
    from {stroke-dashoffset: 0px;}
    to {stroke-dashoffset: -510px;}
}

And voila! You can find all of this and more on my codepen showing in detail the 2 options with an SVG logo hover animation.

https://codepen.io/MateoStabio/pen/jOVvwrM

Upvotes: 0

Hassen Ch.
Hassen Ch.

Reputation: 1751

If there is anyone wants to use this for an animation that should run when you open the page, hover it, when you scroll and run again when you scroll back, here is how I solved it.

I made this fiddle for this https://jsfiddle.net/hassench/rre4qxhf/

So there you go:

var $window = $(window);
var $elem = $(".my-image-container");
var $gotOutOfFrame = false;

function isScrolledIntoView($elem, $window) {
  var docViewTop = $window.scrollTop();
  var docViewBottom = docViewTop + $window.height();

  var elemTop = $elem.offset().top;
  var elemBottom = elemTop + $elem.height();

  return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop) && $gotOutOfFrame);
}

function isScrolledOutView($elem, $window) {
  var docViewTop = $window.scrollTop();
  var docViewBottom = docViewTop + $window.height();

  var elemTop = $elem.offset().top;
  var elemBottom = elemTop + $elem.height();

  return ((elemBottom < docViewBottom) && (elemTop < docViewTop));
}
$(document).on("scroll", function() {
  if (isScrolledIntoView($elem, $window)) {
    $gotOutOfFrame = false;
    $elem.addClass("animate");
    $(function() {
      setTimeout(function() {
        $elem.removeClass("animate");

      }, 1500);
    });
  }
  if (isScrolledOutView($elem, $window)) {
    $gotOutOfFrame = true;
    $elem.removeClass("animate");
  }
});
.my-image-container {
  top: 50px;
  max-width: 22%;
}

.my-image-container:hover {
  animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;
}

.my-image-container .my-image {
  animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
  -moz-animation-delay: 1s;
  -webkit-animation-delay: 1s;
  -o-animation-delay: 1s;
  animation-delay: 1s;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;
  width: 100%;
}

.animate {
  animation: shake 0.82s cubic-bezier(0.36, 0.07, 0.19, 0.97) both;
  -moz-animation-delay: 0.5s;
  -webkit-animation-delay: 0.5s;
  -o-animation-delay: 0.5s;
  animation-delay: 0.5s;
  transform: translate3d(0, 0, 0);
  backface-visibility: hidden;
  perspective: 1000px;
}

@keyframes shake {
  10%,
  90% {
    transform: translate3d(-1px, 0, 0);
  }
  20%,
  80% {
    transform: translate3d(2px, 0, 0);
  }
  30%,
  50%,
  70% {
    transform: translate3d(-4px, 0, 0);
  }
  40%,
  60% {
    transform: translate3d(4px, 0, 0);
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
The animation will run when you firt open the page,<br> 

and when you hover it,<br> 

and when you scroll out then in. <br>

<div class="my-image-container">
  <img class="my-image" 
  src="http://www.lifeofpix.com/wp-content/uploads/2017/05/img-5831.jpg">
</div>
<br> Scroll down then back up
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br>
scroll up

Upvotes: 0

Rami Awar
Rami Awar

Reputation: 750

You can use javacsript or even jquery to make it easier, and add a class that has these animations then remove it when theyre over. Good idea?

$(document).ready(function(){
    $("#id").animate({
        whatever:whatev
        etc... here go the css properties
    })
})

This is javascript after referencing jquery ofc

Upvotes: 0

Related Questions