run keyframes-animation on click more than once - javascript

i have a div that it have image content .i wanna implement animation when i click in image but it do only with first click and next click in image is Ineffective.what is problem and how can i solve it?
$(function () {
$('div.c').bind('mousedown', function () {
var $elem = $(this);
$elem.stop(true)
.css({ "-webkit-animation-name": "xi",
"-webkit-animation-duration": "3s",
"-webkit-animation-timing-function": "ease",
"-webkit-animation-delay": "1s",
})
})})
and
#-webkit-keyframes xi{ 0% {
left: 100px;
}
40% {
left: 150px;
}
60% {
left: 75px;
}
100% {
left: 100px;
}}

You could reset your animation with a second keyframe block as suggested here:
Css and jQuery: How do I trigger the repositioning of a CSS3-animated element back to where it was before the animation?
Here's also a possible solution on how to reset your animation when it's completed:
Is there a callback on completion of a CSS3 animation?

Related

setTimeout and display none with a fader timer- How to do it chronologically?

I am sitting with a project in need of an overlay which fades out when hovered upon and goes to display: none (not visibility: hidden, it does need to be display: none).
The setup is a big confusing, but I will try to explain it:
The overlay comes up when I hover a menu point under my mega menu. When I move the cursor to the overlay it should naturally dissapear and the menu close.
This works very well with this code:
var element = document.getElementById("overlayed");
function mouseOver() {
element.classList.add("mystyle");
setTimeout(function() {
element.classList.remove("mystyle");
}, 500);
}
push {
position: absolute;
top: 50%;
}
.overlayerstwo {
position: fixed;
width: 100%;
top: 30%;
left: 0;
right: 0;
bottom: 0;
background: #111;
opacity: 0.5;
z-index: 2;
display: block;
visibility: visible;
}
.mystyle {
display: none;
animation-name: fadeOut;
animation-duration: .5s;
}
#keyframes fadeOut {
0% {
opacity: .5
}
100% {
opacity: 0;
}
}
.mystyler {
display: none;
}
<h1>Here is something. Overlay comes back when hovering me!</h1>
<div class="overlayerstwo" id="overlayed" onmouseover="mouseOver()"></div>
<div class="push">
<p>Here is an item being overlayed</p>
</div>
With this setup the overlay dissapears right away. I am trying to merge it with the fadeOut keyframe animation before it goes black. I have tried different tactics, like adding a second timeout event but all it does is loop through and end up showing the overlay permanently after.
So the order I want to achieve is as follows:
Add a class that fires the keyframe animation fadeOut for .5 sec
Remove keyframe animation class
Add display: block class
Remove display: block class (essentially resetting it, so you can get the overlay up again by hovering its triggerpoint)
So my question is, how do I get all of these to fire every time I hover over the overlay?
One of the things I tried was this:
var element = document.getElementById("overlayed");
element.classList.add("mystyle");
setTimeout(function(){
var element = document.getElementById("overlayed");
element.classList.remove("mystyle");
}, 500);
setTimeout(function(){
var element = document.getElementById("overlayed");
element.classList.add("mystyletwo");
}, 500);
setTimeout(function(){
var element = document.getElementById("overlayed");
element.classList.remove("mystyletwo");
}, 510);
With the css
.mystyle{
animation-name: fadeOut;
animation-duration: .5s;
}
.mystyletwo{
display: block;
}
Which did not work. I hope someone can help me figure out how to get it to work!
if the timeline will be like this: visible -> hover -> animation -> opacity to 0 -> display: none
using CSS with JS logic:
element.addEventListener("mouseover", function() {
element.style.opacity = "0";
element.style.transition = "all 0.3s";
// when finish the animation then call display none
setTimeout(function() {
element.style.display = "none";
}, 300); // put the same number (milliseconds) of duration of transition (or more, not less)
});
using this method you don't need to complex your code...
the trick really is because we use element.style
that is only put the CSS, but technically...
if there is a transition Javascript don't know it,
so it will run the setTimeout() directly after adding styles,
so now CSS will do the animation but javascript will quietly continue the code (which in our case, says that after 300 seconds add display: none;)

How to make an element reset its position after mouseout event in javascript

trying to make a button like this: https://gyazo.com/9afbd559c15bb707a2d1b24ac790cf7a. The problem with the code right now is that it works as it is supposed to on the first time; but after that, instead of going from left to right as intented, it goes from right to left to right.
HTML
<div class="btn-slide block relative mx-auto" style="overflow: hidden; width: 12rem;">
<span class="z-10">View Pricing</span>
<span class="slide-bg block absolute transition" style="background-color: rgba(0,0,0,.1); z-index: -1; top: 0; left:-10rem; width: 10rem; height: 3rem;"></span>
</div>
Javascript
const btns = document.querySelectorAll(".btn-slide");
const slide = document.getElementsByClassName('slide-bg');
btns.forEach(function(btn) {
btn.addEventListener('mouseout', function () {
slide[0].style.transform = 'translateX(230%)';
slide[0].style.transform = 'none';
})
btn.addEventListener('mouseover', function() {
slide[0].style.transform = 'translateX(80%)';
}, true)
})
Unless you have to compute a value in JavaScript (like the height of an element).
Use CSS classes as modifiers (is-hidden, is-folded, is-collapsed, ...).
Using JavaScript, only add/remove/toggle the class
yourElement.addEventListener(
"mouseenter",
function (event)
{
yourElement.classList.remove("is-collapsed");
}
);
yourElement.addEventListener(
"mouseleave",
function (event)
{
yourElement.classList.add("is-collapsed");
}
);
is-collapsed is only an exemple, name it according to your class naming standard.
You're probably going to need a bit more code than what you're showing, as you have two mutually exclusive CSS things you want to do: transition that background across the "button" on mouseenter/mouseout, which is animated, and then reset the background to its start position, which should absolutely not be animated. So you need to not just toggle the background, you also need to toggle whether or not to animation those changes.
function setupAnimation(container) {
const fg = container.querySelector('.label');
const bg = container.querySelector('.slide-bg');
const stop = evt => evt.stopPropagation();
// step one: make label text inert. This is critical.
fg.addEventListener('mouseenter', stop);
fg.addEventListener('mouseout', stop);
// mouse enter: start the slide in animation
container.addEventListener('mouseenter', evt => {
bg.classList.add('animate');
bg.classList.add('slide-in');
});
// mouse out: start the slide-out animation
container.addEventListener('mouseout', evt => {
bg.classList.remove('slide-in');
bg.classList.add('slide-out');
});
// when the slide-out transition is done,
// reset the CSS with animations _turned off_
bg.addEventListener('transitionend', evt => {
if (bg.classList.contains('slide-out')) {
bg.classList.remove('animate');
bg.classList.remove('slide-out');
}
});
}
setupAnimation(document.querySelector('.slide'));
.slide {
position: relative;
overflow: hidden;
width: 12rem;
height: 1.25rem;
cursor: pointer;
border: 1px solid black;
text-align: center;
}
.slide span {
display: block;
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.slide-bg {
background-color: rgba(0,0,0,.1);
transform: translate(-100%, 0);
transition: none;
z-index: 0;
}
.slide-bg.animate {
transition: transform 0.5s ease-in-out;
}
.slide-bg.slide-in {
transform: translate(0%, 0);
}
.slide-bg.slide-out {
transform: translate(100%, 0);
}
<div class="slide">
<span class="label">View Pricing</span>
<span class="slide-bg"></span>
</div>
And thanks to browsers being finicky with rapid succession mouseenter/mouseout events, depending on how fast you move the cursor this may not even be enough: you might very well still need a "step" tracker so that your JS knows which part of your total animation is currently active, and not trigger the mouseout code if, by the time the slide-in transition ends, the cursor is in fact (still) over the top container (or, again).
I advice you use the .on event listener
$('').on("mouseentre","elem",function(){$('').toggleclass('.classname')})
$('').on("mouseleave","elem",function(){$('').toggleclass('.classname')})
Then you can toggle css classes to your element in the function
toggle class adds the css of a class to your jquery selection, you can do it multiple times and have keyframes for animation in the css class
Keyframes are great way to implement animation and are supported on every browers

How to use Angular to activate CSS Animation on button click?

I want to use an Angular function to activate a Css animation. I have searched for ways to do this but Im really confused on how to do it in my case. I wish to have the div "slide1" to slide horizontally to the right when one of the buttons "B1" OR "B2" is clicked.
This is my Angular function:
directive('click2', () => {
return{
restrict: 'A',
link: (scope) => {
scope.clicked = () => {
}
}
}
})
My slide div css is:
.slide1 {
bottom: -500px;
width: 30%;
//min-width: 275px;
height: 50%;
min-height: 390px;
box-sizing: border-box;
position: relative;
content: '';
background: #a2e0f7;
animation:nudge 5s linear alternate;
}
#keyframes nudge {
0%{
right: 500px;
};
100% {
transform: translate(500px);
}
50% {
transform: translate(0,0);
}
}
Any help with how I can get the Slide1 div to move on click with my Angular function?
An easy way to do this is to add the class to the div dynamically.
And one way to do that would be something like:
<div ng-controller="MyCtrl">
<button ng-click="doSlide = !doSlide">A</button>
<button ng-click="doSlide = !doSlide">B</button>
<div ng-class="{'slide1': doSlide}">Click a button to move me</div>
</div>
Clicking either button will toggle the doSlide value. When doSlide is true the slide1 class is added to the div.
Note: it is not necessary to define doSlide in the controller, Angular will automatically add it to the scope.

JQuery animate() - stopping all animations

I have a question regarding the stopping of more than one animation, I have some pseudo code code below to show my situation:
CSS
#aDiv
{
position: absolute;
background-image: url("gfx/nyancat.png");
width: 46px;
height: 50px;
background-size: 55%;
background-position: center center;
background-repeat: no-repeat;
}
JQUERY
function doAnimate(aDiv)
{
$(aDiv).animate({ //do stuff for first animation
height: (H*2)+"px",
width: (W*2)+"px",
left: "-="+(W*0.5)+"px",
top: "-="+(W*0.5)+"px",
opacity: 1
}, 500 , "linear", function()
{ $(aDiv).animate( //do stuff for second animation
{
height: H+"px",
width: W+"px",
left: "+="+(W*0.5)+"px",
top: "+="+(H*0.5)+"px",
opacity: 0.01
}, 500, function()
{ //call itself
doAnimate( aDiv );
}
);
}
);
}
//somewhere else in the code
doAnimate(aDiv);
When I call the stop() function on the aDiv ( $(aDiv).stop() ), does this stop both animations? The reason I'm asking is because that I have an animating div that is called upon window load, but upon calling stop and then restarting the animation - the animation doesn't run as it previously did so I have to refresh the page. Thanks
edit: fiddle added
Just using .stop() fulfils my requirement. I'm using JQuery 1.7 so the .finish() functionality isn't available to me. For my problem, changing the background size css value from auto to the original value (55% in my case) seemed to have fixed it.

Adding Flag to javascript (hasClass)

So I have images where when you click they expand (via css). However, I also want it so that when you click, the image will be pushed to the top of the page. From what I've heard is that if I use the toggleClass function then I need to have a flag before I initiate the animation, however, I can't seem to get it to function right.
$("img").on("click", function (){
$(this).toggleClass("selected");
if ($("img").hasClass("selected")) {
found = true;
}
var timeout = setTimeout(function () {
$('html,body').animate({
scrollTop: $('.selected').offset().top - 60
}, 100);
}, 5);
});
You should consider using CSS3 transition rather than monitoring using timers. You set transition to transition the top property. Then have the selected class alter the top by toggling it. The change will cause the animation to kick in. See this example:
HTML:
<div class="bar">weee!</div>
CSS:
.bar{
width: 100px;
height: 100px;
background: red;
position: relative;
transition: top 1s ease 0;
top: 100px;
}
.bar.selected{
top : 0px;
}
JS:
$('.bar').on('click',function(){
$(this).toggleClass('selected');
});

Categories

Resources