Infinite CSS3 Animation when hover ends - css

I have some arrows image which are linked to kind of "Back to previous page".
I want to animate those arrows with a slight translation when hover it.
My trouble is when hover ends, the arrow instantly goes back to his initial state without any "transition".
Do you know how to do that ?
Thanks.
Here's my code :
#keyframes movingArrow {
0% {
transform: translateX(0);
}
50% {
transform: translateX(-10%);
}
100% {
transform: translateX(0);
}
}
.moving-arrow:hover img {
animation: movingArrow 1s infinite;
}

I tried to show demo for you at codepen https://codepen.io/navdeepsingh/pen/oEwyqP Have a look
const movingArrow = document.querySelector('.moving-arrow');
movingArrow.addEventListener('mouseover', function() {
this.classList.remove('no-animation');
});
.moving-arrow {
border: 1px solid;
border-color: #000 transparent #000 #000;
border-radius: 50%;
width: 100px;
height: 100px;
}
#keyframes movingArrow {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
#keyframes movingArrowReset {
0% {
transform: rotate(360deg);
}
100% {
transform: rotate(0);
}
}
/* This you need */
.moving-arrow {
animation: movingArrowReset 1s;
}
.moving-arrow:hover {
animation: movingArrow 1s infinite;
}
.no-animation {
-webkit-animation: none !important;
animation: none !important;
}
<div class="moving-arrow no-animation"></div>

Thanks for your help !
A friend helped me by pausing the animation when hover ends, it's not exactly what was targeted but this state is alright for me.
Using anime.js & this codepen
<body>
<h3 class="moving-arrow">← Back</h3>
<script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/2.2.0/anime.js"></script>
</body>
--
const movingArrow = document.querySelector('.moving-arrow');
let animation = anime({
targets: movingArrow,
translateX: '-1%',
direction: 'alternate',
duration: 500,
loop: true,
easing: 'easeInCubic',
autoplay: false
});
movingArrow.addEventListener('mouseover', () => {
console.log("mouseover")
animation.play()
})
movingArrow.addEventListener('mouseleave', () => {
console.log("onmouseleave", animation)
animation.pause()
})

Related

Finish animation on hover even mouse leave

I'm using CSS keyframes to rotate an element on its hover state.
How do I make the element finish its animation even the mouse leave the element before it actually end?
For example, if I move my mouse out of the element(stop hovering) while the element only rotating to 180 degree (the full animation is 360 degree), it immediately stop the animation and go back to its original state instead of finish the animation.
#rotate {
width: 120px;
height: 120px;
background-color: orange;
}
#rotate:hover {
animation: rotating 1s ease 0s 1 normal forwards;
}
#keyframes rotating {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
<div id="rotate"></div>
You need to use Javascript for this, the following snippet is shown using some jQuery, a working example:
$("#rotate").on({
mouseenter() {
$(this).addClass("animated");
},
animationend() {
$(this).removeClass("animated");
},
});
#rotate {
width: 120px;
height: 120px;
background-color: orange;
}
.animated {
animation: rotating 1s ease 0s 1 normal forwards;
}
#keyframes rotating {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="rotate"></div>
Make sure that the class animated is with the animation, and #rotate is the box you want to spin.
This worked for my situation as it pauses and starts from where it left off. For simple rotation, this feels nicer than the jump you usually get from hovering in and out.
#keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.name-star {
right: 5px;
top: 15px;
animation: 5s rotate infinite;
animation-play-state: paused;
animation-timing-function: ease-in;
}
.mat-grid-tile:hover .name-star {
animation-play-state: running;
}

CSS - remove box shadow with keyframes animation

I have an icon that initially has a box shadow set. I am animating the icon and scaling it, but I would also like to remove the shadow while I am doing it. I have tried it like this:
.loading-icon {
width: 80px;
height: 80px;
animation-name: earth;
animation-timing-function: ease-in-out;
animation-duration: 3s;
}
#keyframes earth {
0% {
transform: scale(1);
}
100% {
transform: scale(1.5) { box-shadow: none; };
}
}
But, this is not working, how can I do that?
In keyframes you've extra {} surrounding box-shadow which is not needed.
#keyframes earth {
0% {
transform: scale(1);
}
100% {
transform: scale(1.5);
box-shadow: none;
}
}

Animation Display Block to Display None - CSS

Display None to Display Block animation is working
but I need the animation to work this way also
- Animation Display Block to Display None
the animations is not working when action go from block to Display None
have an idea what can be the problem?
#dboldDiv,#dbnewDiv {
animation: anim .4s ease-in-out;
}
#keyframes anim {
0% {
display: none;
opacity: 0;
}
1% {
display: block;
opacity: 0;
transform: scale(0.8);
}
100% {
opacity: 1;
transform: scale(1);
}
}
display is not animatable property
There are two category of properties animatable and not animatable
you can check animated properties list from here :
https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_animated_properties
display:none won't work smooth.
For fluent disappearing try using visibility:hidden, or if just keep 0 opacity and add pointer-events:none, so the object doesn't catch any mouse events.
document.getElementById('hide').addEventListener('click', function(){
document.getElementById('link').className = 'hide';
});
document.getElementById('show').addEventListener('click', function(){
document.getElementById('link').className = 'show';
});
document.getElementById('link').addEventListener('click', function(){
alert('clicked');
});
#link {
display:block;
}
#link.show {
animation: anim1 .4s;
animation-fill-mode: forwards;
}
#link.hide {
animation: anim2 .4s;
animation-fill-mode: forwards;
animation-direction: reverse;
}
#keyframes anim1 {
0% {
opacity: 0.3;
pointer-events:none;
}
100% {
opacity: 1;
pointer-events:all;
}
}
#keyframes anim2 {
0% {
opacity: 0.3;
pointer-events:none;
}
100% {
opacity: 1;
pointer-events:all;
}
}
<button id="hide">Hide</button>
<button id="show">Show</button>
hidding & showing

Sass mixins: having issues with translateX and translateY

I created a mixin to animate opacity and horizontal/vertical position. I've read through the documentation on SASS site. The mixin currently animates the opacity but fails to move elements -- translateX and translateY.
#mixin keyframes($animation-name, $axis, $start, $end) {
#keyframes #{$animation-name} {
0% {
opacity: 0;
transform: #{$axis}(#{$start});
}
50% {
opacity: 1;
}
100% {
opacity: 1;
transform: #{$axis}(#{$end});
}
}
}
#include keyframes(slideLeft, translateX, 0, 200px);
.slide-left {
animation: slideLeft 2s ease .1s forwards;
}
.redbox {
opacity: 0;
height: 100px;
width: 100px;
background: red;
}
<div class="redbox slide-left">
</div>
Here is a link to the JS fiddle that supports SCSS: enter link description here
I've been banging my head for a while trying to figure out what I'm doing wrong. Any help appreciated.
The problem is how Sass is compiling the code. You need to use a literal string for the definition of the transform value (the translate function). So you need to create the value of the property as a string and then use the unquote function to output the value:
#mixin keyframes($animation-name, $axis, $start, $end) {
#keyframes #{$animation-name} {
0% {
opacity: 0;
transform: unquote("#{$axis}(#{$start})");
}
50% {
opacity: 1;
}
100% {
opacity: 1;
transform: unquote("#{$axis}(#{$end})");
}
}
}
Demo here.
Hope it helps.

How can I create an infinite scale mouseover animation with a smooth mouseout effect with css?

I'm coding a CSS3 effect fired on mouseover; this effect simply animate an inner div scaling it endlessly.
All works great, but when I move the mouse away the div suddenly return to its original size. I would like to add a smooth effect to scale the div back.
I already checked the suggestion of this post:
Make CSS Hover state remain after "unhovering"
Unfortunately the code posted doesn't work :(
In my opinion my issue could be related with the "infinite" loop of the scale effect.
THe goal I would like to gain is the on mouse-out the image could return to its original size smoothly.
Here's the code: https://jsfiddle.net/9dtqpsLa/1/
CSS
#keyframes imageZoom{
0% { transform: scale(1); }
50% { transform: scale(1.24); }
100% { transform: scale(1);}
}
#-moz-keyframes imageZoom{
0% { -moz-transform: scale(1);}
50% { -moz-transform: scale(1.24); }
100% { -moz-transform: scale(1); }
}
#-webkit-keyframes imageZoom{
0% { -webkit-transform: scale(1); }
50% {-webkit-transform: scale(1.24); }
100% { -webkit-transform: scale(1); }
}
#-ms-keyframes imageZoom{
0% { -ms-transform: scale(1); }
50% { -ms-transform: scale(1.24); }
100% { -ms-transform: scale(1); }
}
.article:hover .imageWrapper {
animation: imageZoom linear 10s;
animation-iteration-count: infinite;
-webkit-animation: imageZoom linear 10s;
-webkit-animation-iteration-count: infinite;
-moz-animation: imageZoom linear 10s;
-moz-animation-iteration-count: infinite;
-ms-animation: imageZoom linear 10s;
-ms-animation-iteration-count: infinite;
transform-origin: 50% 80%;
}
.article {
background-color: #e6e6e6;
overflow: hidden;
width: 300px;
height: 300px;
}
.imageWrapper {
background-image: url('http://www.astutegraphics.com/images/blog/tutorials/widthscribe_patterns_18_mar_2013/floral-seamless-pattern.png');
width: 300px;
height: 300px;
}
HTML
<div class="article">
<div class="imageWrapper">
</div>
</div>
Please, could you help me?
Thanks so much
GOALS:
1. Have the image animate expansion and contraction on hover
2. Have the image animate to original state on mouseleave
PROBLEMS:
With CSS, I don't know how to use both an animation and a transition. The animation is the pulsing on hover. The transition is the return to default animation. The only way I could envision doing it is with JS. See each section for notes
https://jsfiddle.net/Bushwazi/9dtqpsLa/5/
HTML:
notes: same as example provided
<div class="article">
<div class="imageWrapper"></div>
</div>
CSS:
notes:
1. animation removed.
2. The scale is only fired with the existence of [data-dir='expand'].
3. transform-origin and transition moved into the default state of .imageWrapper
4. need to add prefixes
.article[data-dir='expand'] .imageWrapper {
transform:scale(1.24)
}
.article {
background-color: #e6e6e6;
overflow: hidden;
width: 300px;
height: 300px;
}
.imageWrapper {
background-image: url('http://www.astutegraphics.com/images/blog/tutorials/widthscribe_patterns_18_mar_2013/floral-seamless-pattern.png');
width: 300px;
height: 300px;
transform-origin: 50% 80%;
transition:all 10.0s linear 0.0s;
}
JAVASCRIPT:
notes:
1. all new
/*
1. on hover aka 'mouseenter' start the animation
2. 10 seconds in, change direction of the animation based on the `isHovering` variable
3. on exit aka 'mouseleave', return to default
*/
var thisArticle = document.querySelector('.article'),
thisTimer = '',
isHovering = false;
thisArticle.addEventListener('mouseenter', function(){
console.log('mouseenter');
thisArticle.setAttribute('data-dir', 'expand');
thisTimer = setInterval(fireAnimation, 10000);
isHovering = true
}, false);
thisArticle.addEventListener('mouseleave', function(){
console.log('mouseleave');
thisArticle.removeAttribute('data-dir');
isHovering = false;
clearInterval(thisTimer);
}, false);
var fireAnimation = function(){
if(isHovering){
if(thisArticle.getAttribute('data-dir') === 'expand'){
thisArticle.removeAttribute('data-dir');
} else {
thisArticle.setAttribute('data-dir', 'expand');
}
} else {
clearInterval(thisTimer);
}
alert('change direction');
}
MORE IDEAS
1. I used a data attribute, but I would prefer to use classList. Wasn't sure how to incorporate that into the fiddle in 30 seconds, so skipped it.
2. The return to default animation has no awareness of the scale when you leave, so it takes 10 seconds no matter what. I'm sure there is a way to make this better.
Once you the mouse is moved away from the element, the styles in the :hover pseudo class gets removed from your element, effectively putting it back where it started.
What you want to do is start and pause the animation:
Here is your fiddle, I edited it a bit and exploded the short-hand and removed -webkit, -ms, etc:
https://jsfiddle.net/9dtqpsLa/4/
#keyframes imageZoom {
100% {
transform: scale(4);
}
}
.article:hover .imageWrapper {
animation-play-state: running;
}
.article {
background-color: #e6e6e6;
overflow: hidden;
width: 300px;
height: 300px;
}
.imageWrapper {
background-image: url('http://www.astutegraphics.com/images/blog/tutorials/widthscribe_patterns_18_mar_2013/floral-seamless-pattern.png');
width: 300px;
height: 300px;
transform-origin: 50% 80%;
animation-name: imageZoom;
animation-duration: 2s;
animation-delay: 0s;
animation-iteration-count: 1;
animation-direction: both;
animation-timing-function: ease-in;
animation-fill-mode: forwards;
animation-play-state: paused;
}
Notice that all the animation logic has moved to the base class, and the :hover only kicks off the animation.

Resources