I have tired a couple of solution, and this is the closest i ever got.
But I’m still not happy how it turned out becuse the element snaps back to its original rotation when the mouse leaves the element.
The idea is if u go over the element it triggers the animation even if the mouse leaves the element. if u hover over the element it plays the animation and stays at 0 degree, once the mouse leaves another animation plays where it rotates back to -8 degrees.
const elements = document.getElementsByClassName('rotate_left');
for (let i = 0; i <= elements.length; i++) {
elements[i].addEventListener('animationend', function(e) {
elements[i].classList.remove('animated')
/*elements[i].classList.add('animatedback')*/
});
elements[i].addEventListener('mouseover', function(e) {
elements[i].classList.add('animated')
elements[i].classList.remove('animatedback')
});
}
.rotate_left {
-ms-transform: rotate(-8deg);
-webkit-transform: rotate(-8deg);
transform: rotate(-8deg);
transition-duration: 1s;
transition-delay: 0.25s;
}
.polaroid {
width: 280px;
height: 200px;
padding: 10px 15px 100px 15px;
border: 1px solid #BFBFBF;
border-radius: 2%;
background-color: white;
box-shadow: 10px 10px 5px #aaaaaa;
}
.polaroid:hover {
width: 280px;
height: 200px;
padding: 10px 15px -100px 15px;
border: 1px solid #BFBFBF;
border-radius: 2%;
background-color: white;
box-shadow: 10px 10px 5px #aaaaaa;
-ms-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
transition-duration: 1s;
transition-delay: 0.25s;
}
@keyframes animationBegining {
from {
-ms-transform: rotate(-8deg);
/* IE 9 */
-webkit-transform: rotate(-8deg);
/* Safari */
transform: rotate(-8deg);
}
to {
-ms-transform: rotate(0deg);
/* IE 9 */
-webkit-transform: rotate(0deg);
/* Safari */
transform: rotate(0deg);
}
}
@keyframes animatedBack {
form {
-ms-transform: rotate(0deg);
/* IE 9 */
-webkit-transform: rotate(0deg);
/* Safari */
transform: rotate(0deg);
}
to {
-ms-transform: rotate(-8deg);
/* IE 9 */
-webkit-transform: rotate(-8deg);
/* Safari */
transform: rotate(-8deg);
}
}
.animatedback {
animation: animatedBack 2s;
}
.animated {
animation: animationBegining 2s;
}
<div id="modalWrepper1" class="polaroid rotate_left">
<p class="caption">Just a basic explanation of the picture.</p>
</div>
Thank you very much for the help.
Just a smooth animation back to the original roatation once mouse leaves the element.
2
Answers
Pure CSS solution (second animation subjects to prevention)
You don’t need JS nor any fancy classes.
transform
andtransition-duration
will do just fine.Let’s start with HTML; this is still your code, but simplified:
Now, the main part: CSS. Since your card is rotated by -8 degrees by default, we include a rule to implement that:
If
.polaroid
is hovered over, it rotates back to 0 degree. That means we can use the pseudo-class:hover
:Once you move your mouse away from
.polaroid
, the:hover
rule no longer applies. This means it will revert to the previous rule in 1 second, starting 0.25 seconds after your mouse left it.Try it:
Prevent second animation from being stopped
To prevent the revert from being stopped, a bit of JS is needed.
First, we declare some constants:
We then create a handler:
Add it as event handler for
'mouseover'
/'mouseleave'
and we’re done:Try it:
TLDR I think this is what you want:
Stackblitz Typescript Example: https://stackblitz.com/edit/typescript-bkyk66?file=index.ts
You’re looking for more fine-grained animation control than CSS provides. That means you’ll have to keep track of your own animation state.
In this case there are two types of state: animation state and hover state.
Animation state has four mutually exclusive values: backward, forward, rotating backward, and rotating forward.
Hover state is just true or false.
I find it helps to make a truth table to discern what happens in all these combinations of state. I believe these are the actions you want, but I’m not sure:
In other words, you want the animations to fully complete before starting another one. If that’s not correct, just let me know what you would like to change in this table, or even copy paste the table into your question with updated rows.
In the example, I keep track of animation state with a simple map and string constants, mapping elements to their animation state. I use
element.match(":hover")
to check hover state.You need to update the animation state at
animationstart
andanimationend
events. You can use the animation name to determine the current state. For example if therotate-forward
animation just ended, the state isforward
.Then you just need to perform checks on each state update to see if an action is required. State updates occur on the
animationstart
,animationend
,mouseenter
, andmouseleave
events in this case.I chose to set the animation directly rather than using a class, so the old animation would be overwritten. You may prefer to use classes instead, you’ll just have to remember to remove the other class when starting a new animation.
The
forwards
value foranimation-fill-mode
is also important, so the animation retains the rotation when it is finished.