Steps in Web Animations API - javascript

I was wondering if there is a way of making a web animation go step by step using the web animation API without having to manually declare offsets for the start and end of each frame. Obviously you can do this in CSS animations.
This is for animating sprite sheets.

Yes, you can use the same approach as in CSS animations. That is, you can specify a timing function using the easing property. Unlike CSS animations you can either apply this to the whole animation or between individual keyframes.
To apply it to the whole animation you can use:
elem.animate(/* ...keyframes ...*/, { duration: 1000, easing: 'steps(5)' });
Alternatively, to apply to individual keyframes you can use one of the following approaches:
// Keyframe array syntax
div.animate(
[
{ opacity: 0, easing: 'steps(2)' },
{ opacity: 0.5, offset: 0.8, easing: 'steps(3)' },
{ opacity: 1 },
],
{
duration: 1000,
}
);
// Object syntax
div.animate(
{
opacity: [0, 0.5, 1],
offset: [0, 0.8, 1],
easing: ['steps(2)', 'steps(3)'],
},
{
duration: 1000,
}
);
Note that CSS animations can only do easing between keyframes. It cannot do easing across the whole animation.
Also, note that when applied to keyframes, the easing is used from the keyframe it is added to until the next keyframe. As a result, it is not necessary to add easing to the last keyframe.
If you are animating sprite sheets, you might find the jump-none keyword useful. It is supported by Firefox and Chrome. For example, use steps(5, jump-none) to see all five frames.

Related

Trying to update a gsap animation on my application in JS, but it does weird stuff when it is pinned

I need to implement a gsap animation timeline and below is the code i have.
https://codepen.io/pranayraj09/pen/eYMKaJw
tl.to('.card', {yPercent: 15, duration: 1 }).to('.card', {yPercent: -100, duration: 2 })
ScrollTrigger.create({
trigger : '.card',
start: "top +=30%",
end: "+=70%",
scrub: 1,
animation: tl,
})
but this adds a white space where on its original DOM place though animation is playing almost fine. I want this white space gone.

How do I make an animation run once? -anime.js and waypoints.js

I'm using waypoints.js to see if an element is visible and then I use anim.js to animate it. Works. The problem is that it's running every time I scroll past the element again. I would like the animation to run only one time. I can't really find how I can achieve that. The anime.js documentation is talking about complete() but I don't understand how to use it. Help!
This is what my code looks like:
$('.sequential').waypoint(function() {
var CSStransforms = anime({
targets: this.element,
opacity: [0, 1],
translateY: [50, 0]
});
}, {
offset: '95%'
});

Scale animations also translating gsap

I have an svg, and I want four of the elements to pop up in place. I am trying this with gsap but they look like they are flying into place. Here's the code I am using for this
gsap.fromTo(
'#ide, #html, #handlebar, #search',
1.5,
{
scale: 0,
},
{
scale: 1,
yoyo: true,
ease: 'none',
repeat: -1,
}
);
Please also check the codepen for current working version: https://codepen.io/prateekkarki/pen/oNxEZxo
I don't want them flying from right, I just want them to scale up from their original position. How can I achieve this in GSAP, please help.
Just remove your CSS that's affecting the transforms:
#ide, #html, #handlebar, #search {
transform-origin: top center;
transform-box: fill-box;
}
Demo.
FYI you're more likely to get a faster response on the GSAP forums.

How to animate correctly a GSAP menu?

Holla, I need to reset the animation when I close menu and open it again. How can I do that? Animation works only the first time when I open menu.
CSSPlugin.defaultTransformPerspective = 600;
TweenMax.staggerFrom('ul#menu li', 1.5, {rotationX:-90, transformOrigin:"50% 0%", ease:Elastic.easeOut}, 0.4);
Here is the code: http://codepen.io/hafsadanguir/pen/qOdaab.
Thanks for help!
Is this the kind of result you were after?
JavaScript:
CSSPlugin.defaultTransformPerspective = 600;
var toggleMenu = $('.menu-toggle');
var logo = $('#logo');
var logotitle = $('#logotitle');
var listItems = $('ul#menu li');
var timeline = new TimelineMax({ paused: true, reversed: true });
timeline.fromTo([logo, logotitle], 0.6, { top: 300 }, { top: -50, ease: Power2.easeInOut });
timeline.staggerFromTo(listItems, 1.2, { autoAlpha: 0, rotationX: -90, transformOrigin: '50% 0%' }, { autoAlpha: 1, rotationX: 0, ease: Elastic.easeOut.config(1, 0.3) }, 0.1, 0.3);
toggleMenu.on('click', function() {
$(this).toggleClass('on');
timeline.reversed() ? timeline.play() : timeline.reverse();
});
A few things have changed so here are the details:
First and foremost, I didn't see the need for the hidden class so I have removed it from my solution.
Plus, the on class toggled on the .menu-section element seemed pretty unnecessary as well. I removed it, but kept the properties defined on the .menu-section CSS rule.
On to the fun part, the JavaScript.
You basically needed a TimelineMax to operate upon.
Judging by the imports you had in the JavaScript settings panel, I am assuming that you have some idea of what TimelineMax (and TimelineLite) are all about. By in any case, TimelineLite is about building and managing sequences of TweenLite, TweenMax, TimelineLite, and/or TimelineMax instances and TimelineMax is an extension of TimelineLite, adding more power to it.
So, what happens in the code is that a TimelineMax instance has been initialised, tweens have been added to it and then, upon clicking of the .menu-toggle button element, this timeline is either played or reversed.
The line timeline.reversed() ? timeline.play() : timeline.reverse(); is basically a shortened, fancy version of an if condition and it comes to down to personal preference more than anything else, no performance gain or anything that I am aware of. In a normal if clause, it would have been written like this:
if (timeline.reversed()) { timeline.play(); } else { timeline.reverse(); }.
The condition that is being checked is .reversed() property of timeline. You would notice that while initialising new TimelineMax(...), I set reversed: true property on it. What it does is that after all the tweens are added to timeline, it would behave as if timeline was immediately reversed such that the orientation of the timeline had been flipped. Read more about it in the TimelineMax documentation link I shared above.
The .play() and .reverse() methods are pretty self-explanatory as they make the timeline go forwards or backwards respectively.
That is about it.
Hope this helps.

jQuery animate - opacity slower than height

Wondering if it's possible to make a jQuery animate property slower than another - here's what I have right now:
$(".thebox").animate({
height: "toggle",
opacity: "toggle"
},250);
When .thebox fades in and slides down simultaneously, I'd like to make opacity part of the animation slower, while making the height part faster.
The whole thing has to work with a button that on click causes the animation. It must be a toggle switch.
Thanks to anyone able to answer this!
Stack the animations on top of each other, and disable the default animation queueing.
$(".thebox")
.animate({height: "toggle"}, {duration: 250, queue:false})
.animate({opacity: "toggle"}, {duration: 500, queue:false}); // Runs twice as slow.
EDIT:
Since the events are triggered twice using toggle, we need a different approach, to detect wheter to hide or show the box. One simple solution would be a helper-class as such:
var theBox = $('.thebox');
if (theBox.hasClass('active')) {
// It is active, then fade it out
thebox
.removeClass('active')
.animate({height: 0}, {duration: 250, queue:false})
.animate({opacity: 0}, {duration: 500, queue:false});
} else {
// It is not active, show it
thebox
.addClass('active')
.animate({height: 'auto'}, {duration: 250, queue:false})
.animate({opacity: 1}, {duration: 500, queue:false});
}
Worth pointing out: The animations can be done using slideUp, slideDown, fadeIn and fadeOut instead of animate(). Also note the above assumes that there is only one element with the class theBox.

Categories