How to Write a common JavaScript effect library! (1/2)

Source: Internet
Author: User

The most basic dynamic effect of JavaScript is to dynamically change the size, move the location, change the transparency, change the color, and so on.
Other dazzling effects are nothing more than the combination and application of these basic effects.

There are already many excellent Javascript libraries or performance libraries on the Internet. Do we need to recreate the wheel?
Looking at it, there are many more Yahoo UI, Prototype-based scriptaculous, Rico, JQuery, and Dojo.
These databases have excellent dynamic effects. We can use it directly.
However, for some small and medium-sized projects, if only one or two special effects are used occasionally, there is no need to reference the entire framework.
These guys are not small. prototype. js 50 K, scripttaculous effects. js also has 40-50 k dojo, and yui is bigger.

In most cases, we need a small, independent (less than 300 lines of code), non-invasive performance library .. Even if there are existing wheels,
We should not only learn how to use the wheel, but also learn how to build a wheel.
For the above reason, we will rewrite a flexible, scalable, compact, and cross-browser dynamic performance library.

Considering the extensive user base of prototype. js, some of my code references prototype. js. Of course, as I said, we need to be an independent
Even if prototype. js is not available, the Code should work properly.

Make some preparations first. The following code is essential to any effect library, because it is responsible for some similar location coordinates,
Settings, get the transparency of the element, and so on.

Code:

Copy codeThe Code is as follows:
/*
The code for this function comes from Prototype. js http://prototype.conio.net/
If prototype. js is referenced on the page, you can delete the following function,
Of course, it does not matter even if it is not deleted, because a simple compatibility judgment is made.
*/
(Function (){
If (! ("Prototype" in window )){
Prototype = {emptyFunction: function (){}};
Class = {
Create: function () {return function () {this. initialize. apply (this, arguments )}}
};
$ = Function (element ){
Return typeof (element) = "string "? Document. getElementById (element): element
};
$ A = function (arrLike ){
For (var I = 0, ret = []; I <arrLike. length; I ++) ret [I] = arrLike [I];
Return ret
};

Number. prototype. toColorPart = function () {return String ("00" + this. toString (16). slice (-2 )};
Function. prototype. bind = function (){
Var _ method = this, args = $ A (arguments), object = args. shift ();
Return function () {return _ method. apply (object, args. concat ($ A (arguments )))}
}

Position = {
CumulativeOffset: function (element ){
Var valueT = 0, valueL = 0;
Do {
ValueT + = element. offsetTop | 0;
ValueL + = element. offsetLeft | 0;
Element = element. offsetParent;
} While (element );
Return [valueL, valueT];
}
}
}
})()


/*
1. Read/set transparency,
2. If only one element is passed, the transparency of the element is returned (0 <value <1)
3. If two parameters, element and value, set the transparency of the element to the value range 0-1.
*/
Function Opacity (element, value ){
// By Go_Rush (A Shun) from http://ashun.cnblogs.com/
Var ret;
If (value = undefined) {// read
If (! /Msie/I. test (navigator. userAgent ))
If (ret = element. style. opacity) return parseFloat (ret );
Try {return element. filters. item ('alpha'). opacity/100} catch (x) {return 1.0}
} Else {// settings
Value = Math. min (Math. max (value, 0.00001), 0.999999) // fixed some bugs where opacity cannot be set to 1 in non-ie browsers.
If (/msie/I. test (navigator. userAgent) return element. style. filter = "alpha (opacity =" + value * 100 + ")"
Return element. style. opacity = value
}
}

So how to design this Effect database.
First, its entry should be concise.
1. One element is to use the effect
2. What is the effect to be used? options
Options should be highly scalable and convenient for users. We designed it into a ha-thin structure.
For example, options = {x: 100, y: 100} indicates moving the element to coordinates 100,100.
Options = {w: 200, h: 200} indicates changing the element size to width = 200, height = 200
They can overlap or, for example, save options = {h: 20, y: 20}. This indicates moving the element to the position of top = 20, in addition, in the process of moving, let his size change to height = 20. At the same time, the original left coordinate and width do not change. Is this the sliding effect of QQ?
There are also several key factors to control the effect of duration (the entire effect time), delay (the effect starts after several seconds), fps (frequency speed) are passed in through options

Copy codeThe Code is as follows:
Effect = Class. create ();
Effect. Fn = new Object ();
Effect. Init = new Object ();
// By Go_Rush (A Shun) from http://ashun.cnblogs.com/
Effect. prototype = {
Initialize: function (element, options ){
This. element = $ (element );
This. options = options | {};
This. duration = (this. options. duration | 2) * 1000; // effect execution time
This. fps = this. options. fps | 40; // frequency
// The current step. Note: This variable is decreasing. When it is 0, the entire effect ends.
This. steps = Math. floor (this. duration/this. fps );
This. maxSteps = this. steps; // step size of the entire Effect
This. setting = new Object ();
This. timer = null;

If (this. options. delay) {// latency Processing
Var _ this = this;
SetTimeout (function (){
_ This. setup (_ this );
(_ This. options. onStart | Prototype. emptyFunction) (_ this );
_ This. run ();
}, _ This. options. delay * 1000 );
} Else {
This. setup (this );
(This. options. onStart | Prototype. emptyFunction) (this );
This. run ();
}
},
Run: function (){
If (this. isFinished () return (this. options. onComplete | Prototype. emptyFunction) (this );
If (this. timer) clearTimeout (this. timer );
This. duration-= this. fps;
This. steps --;
Var pos = 1-this.steps/this. maxSteps; // percentage of the total progress
This. loop (this, pos );
(This. options. onUpdate | Prototype. emptyFunction) (this, pos );
This. timer = setTimeout (this. run. bind (this), this. fps );
},
IsFinished: function (){
Return this. steps <= 0;
},
Setup: function (effect) {// initialize and set all effect units
For (var key in Effect. Init ){
If (typeof (Effect. Init [key])! = "Function") continue;
Try {Effect. Init [key] (this)} catch (x ){}
}
},
Loop: function (effect, pos) {// execute all effect units
For (var key in Effect. Fn ){
If (typeof (Effect. Fn [key])! = "Function") continue;
Try {Effect. Fn [key] (effect, pos)} catch (x ){}
}
}
}

When the dynamic effect changes, for example, fade out, we make an element fade down slowly and disappear.
You can only use element. style. display = "none" without using the effect library.
After the results library is used, the transparency opacity, size width, height, and even position left and top of the element. style are changed.
Display = "none" will not disappear until the element size is changed to 0 or opactiy is 0"
Then, how can we restore his original information when he appears again next time. For example, width. height and opacity.

In the above Code, we use effect. setting to save all the element information before the effect occurs.

Note that the above three udfs onStart, onUpdate, and onComplete are all called udfs passed in through options.
Before the effect occurs, when the effect occurs, it is executed after the effect is completed. The input parameters can be used to view all objects of effect.

Seeing this, you may notice that this effect library has not actually done anything, but he just built an empty shelf.
Effect. Init left us with an empty confession setup method call. Effect. Fn is also an empty confession loop method call.
What we need to do below is to extend Effect. Init and Effect. Fn to enrich the Effect library.

First, let's take a look at the fade-in and fade-out that everyone is most familiar.
All member functions in Effect. Init will be executed by effect. setup. This execution action is performed before the Effect starts.
It is suitable for initialization. For example, save some initial information to effect. setting for future use.

All member functions in Effect. Fn will be executed by effect. loop. This execution action is running in Effect.
It is necessary to put the core performance code, such as computing, changing the performance increment, and so on.

Copy codeThe Code is as follows:
If (effect. options. opacity = undefined) return;
Effect. setting. opacity = Opacity (effect. element );
}

Effect. Fn. opacity = function (effect, pos ){
If (effect. options. opacity = undefined) return;
Opacity (effect. element, effect. setting. opacity + (effect. options. opacity-effect.setting.opacity) * pos );
}



The following shows the debugable code (empty result library and Simple plug-in): (you can copy it to an html file to run the test)
<Script language = "javascript">/** // * the code of this function comes from Prototype. js http://prototype.conio.net/If the page references prototype. js, you can delete the following function. Of course, it does not matter even if it is not deleted, because a simple compatibility judgment */(function () {if (! ("Prototype" in window) {Prototype = {emptyFunction: function () {}}; Class = {create: function () {return function () {this. initialize. apply (this, arguments) }};; = function (element) {return typeof (element) = "string "? Document. getElementById (element): element}; $ A = function (arrLike) {for (var I = 0, ret = []; I <button onclick = "javascript: foo1 () "> RUN foo1 </button> <button onclick =" javascript: foo2 () "> RUN foo2 (latency) </button> <button onclick =" javascript: foo3 () "> RUN foo3 (5 seconds) </button> <button onclick =" javascript: foo4 () "> RUN foo4 (custom function) </button> <button onclick = "javascript: foo5 ()"> RUN foo5 (FADE first and then deepen) </button> after each call, click the recovery button <button onclick = "javascript: foo ()"> restore </button> Go_Rush (A Shun) @ http://ashun.cnblogs.com/Go_Rush (A Shun) @ http://ashun.cnblogs.com/
[Ctrl + A select all Note: If you need to introduce external Js, You need to refresh it to execute]
This page is quite long. I will open a new notebook tomorrow, and then paste all the extended plug-ins, such as size, move, zoom, and color. There are also some DEMO code.

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.