Ease function requestanimationframe Better implementation of browser through animation _ Basic knowledge

Source: Internet
Author: User
Tags setinterval time interval

Write easing function to use the Requestanimationframe function, know some before, but always feel not very understand, so translate a foreigner's article, in order to learn to share.

What is Requestanimationframe?
We used to do animations that required a timer, and a few milliseconds to make some changes every interval. Here's the good news: browser vendors have decided to provide a dedicated animation method, Requestanimationframe (), and can be better optimized on a browser-based level. However, this is just an animation of the underlying API, that is, not based on the DOM elements of style changes, nor based on canvas, or WebGL. So, specific animation details need to be written by ourselves.

Why do we use it?
For the simultaneous n animation, the browser can optimize, the original need n times reflow and repaint optimization into 1 times, so that the implementation of high-quality animation. For example, there are now JS based animations, as well as CSS based transitions, or SVG SMIL. Plus, if a browser's tab is running an animation and then you cut to another tab, or simply minimizes it, you can't see it, and the browser stops the animation. This would mean less cpu,gpu and less memory consumption, and the battery life would be much longer.

How do I use it?

Copy Code code as follows:

Shim layer with settimeout fallback
Window.requestanimframe = (function () {
return Window.requestanimationframe | |
Window.webkitrequestanimationframe | |
Window.mozrequestanimationframe | |
Window.orequestanimationframe | |
Window.msrequestanimationframe | |
function (/* function/callback,/* DomElement/Element) {
Window.settimeout (callback, 1000/60);
};
})();
Usage
Instead of SetInterval (Render, 16) ....
(function Animloop () {
Render ();
Requestanimframe (animloop, Element);
})();

Note: I use "requestanimframe" here because the specification is still changing and I don't want to be at the mercy of the spec.
Requestanimationframe API
Copy Code code as follows:

Window.requestanimationframe (function (/* time/time) {
Time ~= +new Date//The Unix time
},/* Optional bounding Elem * * elem);

Give the Chrome and Firefox versions first.
Copy Code code as follows:

Window.mozrequestanimationframe ([callback]); Firefox
Window.webkitrequestanimationframe (callback[, element]); Chrome

Parameters:
Callback: (FF optional, chrome required)
The next repaint called function, the first parameter of the function is the current time
element: (ff None)
Paraphrase: In fact, is the canvas, and the ' painting ', is animation. (the element that visually bounds the entire animation). For canvas and WebGL, it's the <canvas> element, and for the DOM node, you can ignore it, and if you want to do a little bit of optimization, you can also pass in a parameter.

does it really count?
Now that WebKit implementations (Nightly Safari and Chrome Dev Channel available) and Mozilla implementations (FF4 available) have some differences, Mozilla's implementation has a bug. In fact, the number of frames in the FF animation is this: 1000/(+ N) fps, where N is the execution time of the callback, in milliseconds. If your callback execution time is 1000ms, then the maximum number of frames is only 1fps. If your callback execution time is 1ms, the number of frames is almost 60fps. This bug is definitely going to be fixed, maybe the next version of FF4. CHROME10 has no time parameter (added in M11. Weak weak ask, what is M11?) ), FF does not currently have an element parameter.
I looked at the bug in Firefox, presumably saying:
FF Mozrequestanimationframe () can never reach 60fps, even if your callback execution time is less than 1000/60 milliseconds. As an example:
Copy Code code as follows:

function callback (time) {
Window.mozrequestanimationframe (callback);
DoWork ();
}

If DoWork () takes 1000/60 milliseconds, the frame number is approximately 30fps, and the same animation uses settimeout (callback, 16), and the frame rate is 60fps. It seems that callback always start again at approximately 16ms after callback execution, instead of starting at 16ms after callback begins execution, and if it is the latter, and fast enough, it can produce 60fps frames.
If you are regulated, the portal is here



say not much, first of all, a classic animation function
Copy Code code as follows:

function animate (element, name, from, to, time) {
Time = Time | | 800; Default 0.8 seconds
var style = Element.style,
Latency = 60,//per 60ms change
Count = time/latency,//number of changes
Step = Math.Round ((to-from)/count),//The amount of change
now = from;
function Go () {
count--;
Now = count? Now + step:to;
Style[name] = now + ' px ';
if (count) {
SetTimeout (go, latency);
}
}
Style[name] = from + ' px ';
SetTimeout (go, latency);
}

Regardless of the limitations of the design of this function, you can only modify the style in PX. Only from the realization of the function, this can be a very classic animation concept, its basic logic consists of the following parts:
Gets the starting point value from and the endpoint value to, calculates the number of changes in the value by the time it needs to be performed, and the requirements for each latency interval, and the amount of step for each change.
Open settimeout (FN, latency), step forward to the next detection.

In the next reconnaissance, set the property step one at a time, and if the animation is not finished, go back to step 2nd and continue with the next one.
This function works very well, serving tens of thousands of sites and systems, in fact the core of the animate function of jquery is nothing more than a setinterval function.
However, with the steady increase in the complexity of the system now, the animation effect is more and more, at the same time the fluency of the animation also has more attention, which causes the above function will appear some problems. For example, turning on 100 animations at the same time, according to the above function, it is clear that there will be 100 timers running at the same time, the scheduling between these timers will have a slight effect on performance. Although in the normal environment, these Xu's influence does not have any relation, but in the animation this is very high to the fluency request environment, any slight influence may produce the bad user experience.

In this case, some developers have invented a unified frame management based animation framework, he used a timer to trigger animation frames, different animations to register these frames, in each frame to handle multiple animation property changes. The benefit is to reduce the cost of timer scheduling, but for the animation framework developers, unified frame management, provide monitoring of the frame of the API, are needed to develop and maintain.

direct support for browsers
Eventually, the browser vendors found that they could do it, and there were more optimizations based on the browser level, such as:
Only one layout and paint for all operations of the DOM in one reconnaissance.
If the animated element is hidden, then no longer goes to paint.
So, the browser began to launch an API, called Requestanimationframe, about this function, MDC related pages have a more detailed introduction, in simple terms, this function has 2 ways to use:
Call the Requestanimationframe function and pass a callback argument, and the callback is invoked when the next animation frame.
Calls the function directly without passing parameters, launches the animation frame, and triggers the Window.onmozbeforepaint event when the next frame is triggered, which can be animated by registering the event.

The 2nd approach is not recommended because it relies on Firefox's own events and the Beforepaint event has not yet entered the standard, so it is better to use the 1th method. At this point, our animation logic can become this way:
Record the current time starttime as the time the animation started.
Requests the next frame with a callback function.
When the next frame is triggered, the first parameter of the callback function is the current time and then compared to StartTime to determine the time interval ellapsetime.
Determine if the ellapsetime has exceeded the previously set animation time, or end the animation if it is exceeded.
Calculates the difference of the animation attribute change differ = To-from, and then determines how many step = differ/time * Ellapsetime should be changed at ellapsetime time.
Calculates the position that should now be changed to Math.Round (from + step) and assigns the style to the value again.
Continue to request the next frame.

New animation function
The following is a completely new animation function:
Copy Code code as follows:

function animate (element, name, from, to, time) {
Time = Time | | 800; Default 0.8 seconds
var style = Element.style,
StartTime = new Date;
function Go (timestamp) {
var progress = Timestamp-starttime;
if (progress >= duration) {
Style[name] = to + ' px ';
Return
}
var now = (to-from) * (progress/duration);
Style[name] = now.tofixed () + ' px ';
Requestanimationframe (GO);
}
Style[name] = from + ' px ';
Requestanimationframe (GO);
}

To this point, there is still one problem, that is not every browser supports the Requestanimationframe function, so make a simple correction.
According to the characteristics of Firefox, its mozrequestanimationframe provides a maximum fps of 60, and will be based on the calculation of each frame time to adjust, such as the calculation of each frame 1s, then he will only provide 1FPS animation effect.
And Chrome's high version also implements this function, called Webkitrequestanimationframe, It can be foreseen that there will be opera's orequestanimationframe and IE's msrequestanimationframe in the future, so here's a simple compatibility process:
Copy Code code as follows:

Requestanimationframe = Window.requestanimationframe | |
Window.mozrequestanimationframe | |
Window.webkitrequestanimationframe | |
Window.msrequestanimationframe | |
Window.orequestanimationframe | |
Function (callback) {settimeout (callback, 1000/60);};

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.