How does JQuery do animations? - javascript

JQuery is written in Javascript. As someone who knows a little of each, I have to wonder how they wrote some of it. How do you animate HTML elements in pure Javascript? Is it just repeatedly updating the CSS property that is to be animated, using standard DOM manipulation, with callbacks to make it asynchronous? Or is it something more sophisticated?

jQuery animations are just updating CSS properties on a recurring timer (which makes it asynchronous).
They also implement a tweening algorithm which keeps track of whether the animation is ahead of schedule or behind schedule and they adjust the step size in the animation at each step to catch up or slow down as needed. This allows the animation to finish in the time specified regardless of how fast the host computer is. The downside is that slow or busy computers will show more choppy animations.
They also support easing functions which control the time/shape of the acceleration of the animation. Linear means a constant speed. Swing is a more typical, start slow, accelerate to max speed in the middle and then end slowly.
Because animations are asynchronous, jQuery also implements an animation queue so that you can specify multiple animations that you want to see execute one after the other. The 2nd animation starts when the first animation finishes and so on. jQuery also offers a completion function so if you want some of your own code to run when an animation is complete, you can specify a callback function that will get called when the animation completes. This allows you to carry out some operation when the animation is complete such as start the animation of some other object, hide an object, etc...
FYI, the jQuery javascript source code is fully available if you want more details. The core of the work is in a local function called doAnimation(), though much of the work is done in functions called step and update which can be found with the definition of jQuery.fx.prototype.

That's it : a plain old setInterval and some DOM manipulation.
Of course, the code is a bit more complex than that.
Look : http://code.jquery.com/jquery-latest.js , near the end of the file. Search for jQuery.fx.prototype .

When inspecting element during a jQuery animation almost always it changes your CSS code, which is assigned to the element through jQuery that is not really assigned from HTML you write. Get a FireBug if you don't have it for firefox and inspect what's going on while the animations execute.

Without having read the code myself, from what I understand it is indeed using standard Javascript methods and properties to update the DOM elements and CSS styles at regular intervals ("ticks"), which it accomplishes using standard setInterval() and setTimeout() methods.

Related

How multiple scripts run without webworkers?

I am learning web-workers and found that we can run multiple scripts now on web pages. This is quite interesting but one thing again came in to my mind was If we can't run multiple scripts before html web-workers, How did I run several slideshows on a single html page without using above technology.
I may not properly understand this concept. Can anyone explain how I ran several slideshows which was designed from only JavaScript without web-workers?
Slideshows will typically use a setTimeout() to show the next slide. You can simply have multiple slideshows each using their own setTimeout().
The first slideshow shows it's initial image, then sets a setTimeout() for a particular time in the future when it wants to switch to the next slide. The second slideshow then shows it's initial image and set a setTimeout() for a particular time in the future when it wants to switch to the next slide.
Then, both slideshow are done executing for now until one of their setTimeout() fires. They never technically "execute at the same time". Only one ever actually has code running at a time. Using short enough timer intervals, it may appear they are both operating at the same time, but technically they aren't.
Javascript without WebWorkers is single threaded. There is only ever one thread of execution running at a time. Timers are often used to simulate multiple things happening at the same time (such as multiple javascript-based animations running at the same time). But, that is only a simulation (sometimes a very effective one).
Slideshows may also use CSS3 animations or transitions to show slide transitions from one slide to the next which are controlled by the browser and don't use javascript to execute the animations (they use native code which may or may not be multi-threaded or may even use the GPU - that's browser implementation dependent).
You may find this answer and the references it contains helpful in understanding the javascript event model and single threading: How does JavaScript handle AJAX responses in the background?.

When to use requestAnimationFrame?

Having discovered requestAnimationFrame just a moment ago, I have dived into all the information I could find about it. To name just a few of the resources I came across in case there are others looking for more info about it:
http://creativejs.com/resources/requestanimationframe/ - explains the basics about it.
http://www.html5rocks.com/en/tutorials/speed/animations/ - explains how to use it.
Anyway, all of these resources tell me something about how requestAnimationFrame works or how it could/should be used, but none of them tell me when it is right to use it.
Should I use it for animations (repeated changes to the style of an element, much like CSS animations)?
Should I use it when an automated event wants to change the css/classes of one or multiple elements?
Should I use it when an automated event wants to change the text value of one or multiple elements? (e.g. updating the value of a clock once every second)
Should I use it when an automated event wants to modify the DOM?
Should I use it when an automated event needs values like .offsetTop, .offsetLeft and then wants to change styles such as top and left a few lines further?
Should I use it when a user generated event causes any of the above changes?
TL;DR: When is it right to use requestAnimationFrame?
You shouldn't yet. Not really, at least. This is still experimental and may or may not reach full recommendation (it is still a working draft at this point). That said, if you don't care about older browsers, or willing to work with the polyfill available the best time to use it is when you are looking to draw things to the screen that will require the browser to repaint (most animations).
For many simple modifications of the DOM, this method is overkill. This only becomes useful when you are doing animations when you will be drawing or moving items quickly and need to make sure that the browser repainting is keeping up enough to make it smooth. It will allow you to ensure that every frame you calculate will be drawn to the screen. It also provides a utility for more accurate time measurements to your animations. The first argument is the time at which the paint will occur, so you can ensure that you are where you should be at that moment.
You should not use it when you are doing many simple modifications to the DOM, or things that don't need to be smoothly transitioned. This will be more expensive on your users' computers so you want to limit this to making things smoother in transitions, movements and animations. Forcing a frame redraw is not needed every time you make a change on the page, since the response will be fast enough most of the time you don't need to worry about that extra couple milliseconds between draws.
As the previous answer says, you should not use it in the discontinuous animation because that don't need to be smoothly transitioned. In most cases, it's used for properties which vary continuously with time.

Javascript sleep ....setTimeout from within setInterval javascript

Does setTimeout work from WITHIN setInterval?
I'm writing some JavaScript to animate some DOM elements for a strange artistic project.
The best way for me to explain my question is to give an example:
I have 50 different divs that I need to animate by changing their position on screen, using setInterval. I need each div to be moving at a different rate.
The solution I planned to use was to have a sleep function within my larger changePosition function, so that I could pass a different sleep value for each div. This way, I could assign a unique rate of movement for each div via a dictionary.
The issue that I'm having is that JavaScript does not have "sleep". It only has setTimeout, which does not seem to be working from within my setInterval loop.
setTimeout() works perfectly inside of setInterval(), but since you're trying to emulate sleep() which javascript does not do or have, it sounds to me like you are trying to write synchronous code when setTimeout() works asynchronously. You will need to rethink how you write your code to do this.
Post some of your code and we can help a lot more specifically.
I'm not entirely sure I follow what you're trying to do, but it's probably easiest to animate N different things each at a different rate by just using a separate timer for each object. Each object's timer can then be set at it's own rate and detect it's own completion and you don't have to manage them all from some central timer.
In addition, if you're writing animation routines from scratch in javascript, you're doing a lot more work than you need to. This problem has been solved thousands of times already and there's no reason you have to invent it yourself all over again. A simple Google search for "javascript animation examples" will show all sorts of samples and plenty of code you can base yours off of. Here's a good tutorial: http://javascript.info/tutorial/animation.
The popular libraries like jQuery have all sorts of built-in functions for animation that do a lot of the dirty work for you also. Animation can also be done using CSS3 in modern browsers (other than IE).
Maybe you are looking for jQuery delay() function?
http://api.jquery.com/delay/
And here: Can I use .delay() together with .animate() in jQuery? you can see how delay() and animate() functions works together.

How does jQuery have asynchronous functions?

I'm surprised I can't find a clear answer to this. So, in jQuery, you can do this:
$(someElements).fadeOut(1000);
$(someElements).remove();
Which, will start a fadeOut animation, but before it finishes executing in the 1 second duration, the elements are removed from the DOM. But how is this possible? I keep reading the JavaScript is single threaded (see also: Is JavaScript guaranteed to be single-threaded?). I know I can do either:
$(someElements).fadeOut(1000).promise().done(function() {
$(someElements).remove();
});
or even better:
$(someElements).fadeOut(1000, function() {
$(this).remove();
});
What I don't understand is how JavaScript runs in a "single thread" but I'm able to use these jQuery functions that execute asynchronously and visibly see the DOM change in different places at the same time. How does it work? This question is not: "How do I fix this".
jQuery animations (and pretty much all javascript-based animations) use timers to run their animations. The call to .fadeOut() just STARTS the animation and it doesn't complete until some time later when a series of timer operations are done.
This is all still single-threaded. .fadeOut() does the first step of the animation, it sets a timer for the next step and then the rest of your javascript (including the .remove()) runs until completion. When that javascript thread finishes and the time elapses for the timer, the timer fires and the next step of the animation happens. Finally when all steps of the animation have completed, jQuery calls the completion function for the animation. That is a callback that allows you to do something when the animation is done.
That is how you fix this issue:
$(someElements).fadeOut(1000, function() {
$(this).remove();
});
You use the animation completion function and only remove the item when the animation is done.
There is a setInterval handler in jQuery that performs transformations on all registered animation properties. If you're coming from as3, think of it as an EnterFrame handler, or like a Draw method in OpenGL
You ca use delay() to wait for a certain time or use a callback for the animation, changing the fadeOut with animate.
jQuery uses setTimeout to animate and queues.
In much the same way that operating systems 20 years ago did multi-tasking. There were no threads, there were just a list of things that needed attention and a controller that would give attention to things based on the list.
A single thread just iterates through the list over and over services all the things that need servicing. The only difference here is that some things have a wait period associated. They are in the list, but are flagged to service only after a certain period. It's a very basic scheduler implementation essentially. The kernel on a computer does the same thing. Your CPU can only execute a few programs concurrently, and even then, only somewhat. The operating system kernel has to decide who gets attention on a millisecond by millisecond basis (see jiffies). Javascript's "kernel" or runtime does the same thing, but essentially like it's running on a CPU with only one core.
This doesn't talk about things like interrupt queues and such which a CPU can cope with, and I'm not sure Javascript has any analogue, but at a simple level, I think it's a fair representation.
Single Threading has nothing to do with Asynchronous programming. http://social.msdn.microsoft.com/Forums/uk/csharplanguage/thread/3de8670c-49ca-400f-a1dc-ce3a3619357d
If you have only one thread on which you can execute instructions, it won't /always/ be executing. During those empty spots, that's opportunity for more work. Asynchronous programming just breaks up the work into re-entry capable blocks and the thread jumps around to where it's needed. (Conceptual explanation)
In this case, your question might more appropriately be: Why isn't this a blocking call? In which case the answer is pretty clear that it's to separate the UI animations from data calls. The whole JS environment shouldn't block for 1 second while taking small slices to animate an element which it could be retrieving or transforming data, queuing up animation for other elements, etc.

Calling jQuery effects too fast breaks my plugin

I'm wring a custom jQuery plugin based on the awesome jGrowl plugin. I just need it to do a few more things than it already does.
Basically everything is working as I need it to (only tested in Firefox so far) except that if you call the plugin too many times too fast it stops and breaks everything
http://jsbin.com/ofejo/edit
Any ideas about what might cause this?
sounds like you need to implement a callback feature and put the additional calls into callbacks to ensure that the plugin processes before other executions occur.
It's rendering and trying to calculate where to place the block but failing because there's an animation already taking place. (often an animation changes the type of display style being used in order to create the effect and this causes oddities with calculations such as these)
You need to queue the effect, but I'm not precisely sure how you would go about it because you're creating new elements, and there's more source code than I am willing to look through at the moment. Let me know if this helps.
http://docs.jquery.com/Effects/queue

Categories

Resources