How to stop velocity.js animation after the animation is finished? - javascript

I am creating a pulsating effect with velocity.js as fallback for IE9, (see box2 for CSS animation )
When mouse leaves the box before the animation has finished ( stay until pulse grows than move out ) the pulsating element stays visible. https://jsfiddle.net/02vu80kc/1/
$(".box").hover(function () {
$(this).find('.effect-holder').velocity({
scale: [1.2, 0.9],
opacity: [1, 0]
}, {
easing: 'ease-out',
duration: 800,
loop: true
}, {
queue: false
}).velocity("reverse");
}, function () {
$(this).find('.effect-holder').velocity("stop");
});
How do I stop the animation on mouseout after the effect has finished ?
I am trying to stay away from .removeAttr('style') and would like the animation to finish and than stop. Any help is appreciated.
If I use this
$(this).find('.effect-holder').velocity('reverse').velocity("stop");
and you move the mouse fast the animation begins again and sometimes pauses in between.

Either use .velocity("finish") instead of .velocity("stop"), or have a different on and off animation, with both animations calling "stop" (ie, catch when the mouse moves properly).
Also note that the {... loop:true ...} means that the first animation never ends, and hence the "stop" will have the "reverse" happen immediately after stopping (call .velocity("stop", true) to prevent that)
edit: Open issue on the "finish" bug - https://github.com/julianshapiro/velocity/issues/495
edit2: Add simple example:
$("box").hover(function() {
// over
this.velocity("stop", true).velocity({
scale: [1.2, 0.9]
}, {
duration: 800,
loop: true
})
}, function() {
// out
this.velocity("stop", true).velocity({
scale: 0.9
}, {
easing: "ease-out",
duration: 800
})
});

Related

How can I stop animation loop, but not mid-animation in Phaser 3?

I have an animation, which usually is supposed to play 3 times, thus the config currently says repeat: 2. However, under a certain condition (the player stops dragging an element) I want the animation to finish and stop without repeating.
By that I mean I don't want it to stop right at the frame it is at the second, but I want it to finish playing to the last frame I assigned in frames and then stop before it repeats.
How would I be able to do this?
// ANIMATION CREATED HERE
this.anims.create({
key: "nom",
frameRate: 12,
frames: this.anims.generateFrameNames("chara", {
prefix: "nom_000",
start: 0,
end: 4}),
repeat: 2,
});
this.input.on('drag', (activePointer, gameObject, dragX, dragY) => {
gameObject.x = dragX;
gameObject.y = dragY;
if(Phaser.Geom.Intersects.RectangleToRectangle(gameObject.getBounds(), character.mouth.getBounds())) {
gameState.snack_cursor.play("fries_cursor", true);
// ANIMATION PLAYED HERE
character.sprite.play("nom", true);
}
});
this.input.on('dragend', (pointer, gameObject, dragX, dragY) => {
if (gameObject.anims.isPlaying)
gameObject.anims.stop();
// ANIMATION STOPS HERE, BUT CURRENTLY AT WHATEVER FRAME IT'S AT
if (character.sprite.anims.isPlaying)
character.sprite.anims.stop();
});
You can use the function stopAfterRepeat (documentation).
Just call it with the parameter 0, and the current animation will be finished, before the animation is stopped. I think this is what you are after.
...
character.sprite.anims.stopAfterRepeat(0);
...

Animation disappears on end LottieJS

I have an animation build with LottieJS which loops like:
var lottieLogo = lottie.loadAnimation({
container: document.getElementById('icon_logo'), // the dom element that will contain the animation
renderer: 'svg',
loop: true,
autoplay: false,
path: 'path-to-json'
});
lottieLogo.play();
Then after animation is done I want to pause for 10 seconds like:
function logoAnimation() {
lottieLogo.pause();
setTimeout(
function()
{
lottieLogo.play();
}, 10000);
}
lottieLogo.addEventListener('loopComplete', logoAnimation);
It works fine but the only problem is that the animation disappears for about 0.2 seconds every time it loads again. Anyone familiar with this problem?
If you set loop to false it should give you the desired effect.

How can I change the speed (duration) of an anime.js event using a slider?

I am using anime.js to animate an element that is being bounced back in forth from the edges of its container. I want to be able to adjust the speed of this animation using a range slider that I have elsewhere on the page.
My problem is that while the duration is adjusted, it appears that the slider instantiates completely and does not continue animating to where it originally was suppposed to. I want it to go from the far left to the far right, but when I resize it the animation will only go from the place where it was resized to the end of the container.
These have been my attempts when calling the onchange method of my slider.
function adjustSpeed() {
alternate.duration = 300;
}
and
function adjustSpeed() {
var alternate = anime({
targets: '#alternate .el',
translateX: width,
direction: 'alternate',
loop: true,
duration: 300,
easing: 'linear',
});
}
Any help would be very much appreciated.
I just came across this issue and I've found a better yet not perfect solution. AnimeJS has another static speed property that is by default set to 1. If you change this speed, the animation speed changes, though the animation "jumps" and it doesn't look smooth.
For example, if you want the speed to be 0.5x the original speed, set anime.speed = 0.5.
I'll update this answer if I come up with a better solution.
When you changed speed or duration, you have to stop and remove current animation. After that, you have to start new animation with new duration value.
Here is example of bouncing from left to right element.
var duration = 500
const animateBLS = () => {
const el = document.getElementById('dot')
anime.remove(el)
animation = anime({
targets: [el],
left: '100%',
direction: 'alternate',
loop: true,
easing: 'linear',
duration: duration
});
}
And there is the code for running new animations, called when durations is changed. It's finish current animation with new speed value, and start our main animation functions "animateBLS"
const el = document.getElementById('dot')
if(animation.reversed) {
anime.remove(el)
animation = anime({
targets: [el],
left: '0%',
direction: 'normal',
loop: false,
easing: 'linear',
duration: duration,
complete: () => {
animateBLS()
}
});
} else {
anime.remove(el)
animation = anime({
targets: [el],
left: '100%',
direction: 'normal',
loop: false,
easing: 'linear',
duration: duration,
complete: () => {
animation = anime({
targets: [el],
left: '0%',
direction: 'normal',
loop: false,
easing: 'linear',
duration: duration,
complete: () => {
animateBLS()
}
});
}
});
}
A dirty solution:
Manage frame manually by anime.tick combining with requestAnimationFrame, here're the demo:
https://codesandbox.io/s/anime-js-speed-adjustment-lm0ui?file=/src/index.js
The code is basically self-explained, if you have any further question, let me know.

Make Slide in Animation JavaScript and HTML

How would one make a slide and fade in animation like in seen in the green and pink boxes on sharethis.com? In particular I like the one in the blue box with the arrows. Are there a set of JavaScript codes or CSS effects?
The easiest would probably be to use a library like this:
http://janpaepke.github.io/ScrollMagic/
I see that for the arrows effect the css-height property is animated when you scroll. This is done in javascript. But you can also achieve this effect through CSS3-transitions.
Update: Slide and wipe effects from the demo page:
// ani
var pinani = new TimelineMax()
// wipe
.add(TweenMax.to("#wipe", 1, {
width: "100%"
}))
// slide
.add(TweenMax.to("#slide", 1, {
top: "0%",
ease: Bounce.easeOut,
delay: 0.2
}));
// pin
new ScrollScene({
triggerElement: "section#pin",
duration: 1100
})
.on("progress", function () {
// keep centered even though width changes
$("#wipe h3").width($("#pin>h3").width());
})
.setTween(pinani)
.setPin("section#pin")
.addTo(controller);

fadeOut() and slideUp() at the same time?

I have found jQuery: FadeOut then SlideUp and it's good, but it's not the one.
How can I fadeOut() and slideUp() at the same time? I tried two separate setTimeout() calls with the same delay but the slideUp() happened as soon as the page loaded.
Has anyone done this?
You can do something like this, this is a full toggle version:
$("#mySelector").animate({ height: 'toggle', opacity: 'toggle' }, 'slow');
For strictly a fadeout:
$("#mySelector").animate({ height: 0, opacity: 0 }, 'slow');
Directly animating height results in a jerky motion on some web pages. However, combining a CSS transition with jQuery's slideUp() makes for a smooth disappearing act.
const slideFade = (elem) => {
const fade = { opacity: 0, transition: 'opacity 400ms' };
elem.css(fade).slideUp();
};
slideFade($('#mySelector'));
Fiddle with the code:
https://jsfiddle.net/00Lodcqf/435
In some situations, a very quick 100 millisecond pause to allow more fading creates a slightly smoother experience:
elem.css(fade).delay(100).slideUp();
This is the solution I used in the dna.js project where you can view the code (github.com/dnajs/dna.js) for the dna.ui.slideFade() function to see additional support for toggling and callbacks.
The accepted answer by "Nick Craver" is definitely the way to go. The only thing I'd add is that his answer doesn't actually "hide" it, meaning the DOM still sees it as a viable element to display.
This can be a problem if you have margin's or padding's on the 'slid' element... they will still show. So I just added a callback to the animate() function to actually hide it after animation is complete:
$("#mySelector").animate({
height: 0,
opacity: 0,
margin: 0,
padding: 0
}, 'slow', function(){
$(this).hide();
});
It's possible to do this with the slideUp and fadeOut methods themselves like so:
$('#mydiv').slideUp(300, function(){
console.log('Done!');
}).fadeOut({
duration: 300,
queue: false
});
I had a similar problem and fixed it like this.
$('#mydiv').animate({
height: 0,
}, {
duration: 1000,
complete: function(){$('#mydiv').css('display', 'none');}
});
$('#mydiv').animate({
opacity: 0,
}, {
duration: 1000,
queue: false
});
the queue property tells it whether to queue the animation or just play it right away
Throwing one more refinement in there based on #CodeKoalas. It accounts for vertical margin and padding but not horizontal.
$('.selector').animate({
opacity: 0,
height: 0,
marginTop: 0,
marginBottom: 0,
paddingTop: 0,
paddingBottom: 0
}, 'slow', function() {
$(this).hide();
});

Categories