I've tired of several solutions and this is the closest I've gotten. But I'm still not happy with how it turned out, because when the mouse leaves the element, the element reverts to its original rotation. The idea is that if you go over the element, it will trigger the animation even if the mouse leaves the element. If you hover over the element, it will animate and stay at 0 degrees, and once the mouse leaves, another animation will play and rotate 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 for your help.
Once the mouse leaves the element, there is a smooth animation back to the original rotation.
P粉3223196012024-04-02 00:03:49
You don’t need JS or any fancy classes. transform
and transition-duration
will do.
Let's start with the HTML; this is still your code, but simplified:
Just a basic explanation of the picture.
Now, the main part: CSS. Since your card is rotated by -8 degrees by default, we've added a rule to do this:
.rotate_left { transform: rotate(-8deg); transition-duration: 1s; transition-delay: 0.25s; }
If you hover . Polaroid
over it, it will rotate back to 0 degrees. This means we can use the pseudo class :hover
:
.polaroid:hover { transform: rotate(0deg); }
Once you move the mouse away from .poloid
, the :hover
rules no longer apply. This means it will revert to the previous rule within 1 second, starting 0.25 seconds after the mouse is gone.
try it:
.rotate_left { transform: rotate(-8deg); transition-duration: 1s; transition-delay: 0.25s; } .polaroid:hover { transform: rotate(0deg); } /* Demo only */ .polaroid { border: 1px solid #bfbfbf; border-radius: 2%; padding: 10px 15px; height: 200px; width: 280px; box-shadow: 10px 10px 5px #aaa; }
Just a basic explanation of the picture.
To prevent recovery from stalling, some JS is required.
First, we declare some constants:
const card = document.querySelector('.rotate_left'); const duration = 1000; // Duration of animation, in milliseconds. const delay = 250; // Delay before animation, in milliseconds. const keyframes = [ { transform: 'rotate(-8deg)' }, { transform: 'rotate(0deg)' }, ]; const options = { duration, delay, fill: 'forwards' };
Then we create a handler:
const handler = () => { // New mouse over & leave should not mess with current animation. if (card.classList.contains('rotating')) { return; } // Let ourselves know that an animation is playing. card.classList.add('rotating'); let animation; if (card.classList.contains('not_rotated')) { // Rotated to 0 degree, reverting. animation = card.animate([...keyframes].reverse(), options); } else { animation = card.animate(keyframes, options); } // Make sure we clean after ourselves after animation. animation.finished.then(() => { card.classList.remove('rotating'); card.classList.toggle('not_rotated'); }); };
Add this as an event handler for 'mouseover'
/'mouseleave'
and we're done:
card.addEventListener('mouseover', handler); card.addEventListener('mouseleave', handler);
try it:
const card = document.querySelector('.rotate_left'); const duration = 1000; // Duration of animation, in milliseconds. const delay = 250; // Delay before animation, in milliseconds. const keyframes = [ { transform: 'rotate(-8deg)' }, { transform: 'rotate(0deg)' }, ]; const options = { duration, delay, fill: 'forwards' }; const handler = () => { if (card.classList.contains('rotating')) { return; } card.classList.add('rotating'); let animation; if (card.classList.contains('not_rotated')) { animation = card.animate([...keyframes].reverse(), options); } else { animation = card.animate(keyframes, options); } animation.finished.then(() => { card.classList.remove('rotating'); card.classList.toggle('not_rotated'); }); }; card.addEventListener('mouseover', handler); card.addEventListener('mouseleave', handler);
.rotate_left { transform: rotate(-8deg); } /* Demo only */ .polaroid { border: 1px solid #bfbfbf; border-radius: 2%; padding: 10px 15px; height: 200px; width: 280px; box-shadow: 10px 10px 5px #aaa; }
Just a basic explanation of the picture.