====== Effects extensions ======
We haven't written many extensions to the //Fx// group (well, only two so far). This is mostly because the //Fx// group has so much functionality already. Still, we had two things we wanted to add...
===== Fx.Marquee =====
This class is a pretty simple extension of the //Fx.Styles// class designed to let you animate little announcements in to the page with ease. The basic principle is that you create an instance of the class and then just throw messages at it.
Below is our box for messages. The html in it looks like this:
Ok. Now we need to create an instance of //Fx.Marquee//. For this example, I've already declared //var fxmq;// for scope reasons.
fxmq = new Fx.Marquee($('marqueeTest'), {
duration: 500,
showEffect: {
top: [0,0], //reset the top every time to zero
left: [-100, 0],
opacity: [0,1]
},
hideEffect: {
top: 20
},
revertEffect: {
top: [-30, 0],
left: [0,0] //reset the left back to zero on revert
}
});
**Be sure to execute the code above** or none of the other examples will work.
Now we'll make some announcements:
fxmq.announce({
message: 'Yo mama so fat...',
delay: 1200, revert: false
}).chain(function(){
fxmq.announce({
message: 'When I yell "Kool-aid" she comes crashin\' through the wall!',
delay: 2000, revert: false
});
}).chain(function(){
fxmq.announce({
message: 'Oh Yeah? Well, you mamma so poor, I saw her walkin\' down the street the other day kicking an empty can and I asked, "What are you doin\'?" and she said...',
delay: 3000, revert: false
});
}).chain(function(){
fxmq.announce({
message: 'Movin\'',
delay: 1500, revert: true,
showEffect: {
top: [0,0],
left: [500, 0],
opacity: [0,1]
},
hideEffect: {
top: [0,0],
left: [0, 500]
}
});
});
As illustrated in the last chained message above, you can pass in any of the initialization options when you call //.announce()//. This will set the options for the instance to these new settings, allowing you to send message after message along with various transitions for each one.
===== Fx.SmoothShow.js =====
//Fx.SmoothShow// extends //Fx.Styles// to let you transition an element from being hidden to visible in a smooth way. Its //.hide// method calculates the height of the margin, padding, border, and height of the element and transitions these along with the opacity to zero. After the transition, it sets these values back to what they were and sets display to "none". //.show// does the same thing in reverse.
//Element.smoothHide(options)// and //.smoothShow(options)// are just shortcuts to create a new instances of the class (much like //Element.effect// is a shortcut to //Fx.Style//).
I'm a paragraph with padding, margin, and border values. When smoothHide is executed, these values will go to zero, but be restored at the end of the transition when display will be set to "none"
new Fx.SmoothShow($('smoothHide_Show')).hide();
new Fx.SmoothShow($('smoothHide_Show')).show();
This is the same thing as above:
$('smoothHide_Show').smoothHide();
$('smoothHide_Show').smoothShow();
Note that these element extensions return the instance of the effect:
var mySmoothShow = $('smoothHide_Show').smoothHide();
mySmoothShow.toggle.delay(1000, mySmoothShow);
===== Fx.SmoothMove =====
//Fx.SmoothMove// is a lot like //[[cnet-libraries:05-mootoolsextensions:01-native#element.setposition|Element.setPosition]]// in that it allows you to position an element relative to another one. In fact, it takes all the same arguments as //setPosition// (relativeTo, position, edge, and offset) but it also takes all the options of //[[http://clientside.cnet.com/wiki/mootorial/05-effects#fx.styles.js|Fx.Style]]// so you can set a transition or duration, etc.
new Fx.SmoothMove($('setPositionTarget')).start(); //centered in the window
new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget') /*centered over a target*/
}).start();
new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
position: 'upperRight'
}).start();
new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
position: 'upperLeft'
}).start();
new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
position: 'bottomLeft'
}).start();
new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
position: 'upperRight',
offset: {x: 20, y: 20} /*move over and down*/
}).start();
Additionally, you can specify an edge option that allows you to align the specified edge of the element relative to the relativeTo element's edge specified in the position argument. This lets you, for instance, position the upper right corner of the element to the bottom left corner of the relativeTo element.
Examples:
/* upperRight of element aligned to upperRight of relativeTo element*/
new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
position: 'upperRight',
edge: 'upperRight'
}).start();
/* bottomLeft of element aligned to bottomLeft of relativeTo element*/
new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
position: 'bottomLeft',
edge: 'bottomLeft'
}).start();
/* center of element aligned to upperRight of relativeTo element*/
new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
position: 'upperRight',
edge: 'center'
}).start();
==== additional options ====
You can also specify the options available in //Fx.Styles//:
new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
position: 'upperRight',
offset: {x: 20, y: 20},
transition: Fx.Transitions.Elastic.easeOut,
duration: 300
}).start();
==== setting a new destination ====
You can also set new destinations using the same effect:
var mover = new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
position: 'upperRight',
offset: {x: 20, y: 20},
transition: Fx.Transitions.Back.easeInOut,
duration: 800
});
mover.start().chain(function(){
mover.start({
relativeTo: document.body,
position: 'center',
offset: {x: 0, y: 0}
});
}).chain(function(){
mover.start({
relativeTo: $('fxTarget'),
position: 'center',
edge: 'upperLeft',
offset: {x: 0, y: 0}
});
});
Whenever you pass in a destination you will probably want to pass in all the arguments. If you don't the missing option values will be filled in with the options you passed the class when you initialized it. So if you initialize with an offset, then set a new element as a destination but don't specify an offset, then the value you passed in when you created the effect will be used:
var mover = new Fx.SmoothMove($('setPositionTarget'), {
relativeTo: $('fxTarget'),
offset: {x: 50, y: 50} //we define an offset
});
mover.start().chain(function(){
mover.start({
//here we don't specify an offset, so the value
//specified when we created the effect is used
//in this case, x:50 and y:50
relativeTo: document.body
});
}).chain(function(){
//we'll wait half a second and then do that again but this time
//specify no offset so we get the actual center of the window
mover.start.delay(500, mover, {
relativeTo: document.body,
offset: {x:0,y:0}
});
});
==== Element.smoothMove ====
This is just a shortcut for creating the class:
$('setPositionTarget').smoothMove({
relativeTo: $('fxTarget'),
offset: {x: 20, y: 20} //we define an offset
});
===== Fx.Sort =====
This effect will rearrange a group of elements using a transition.
Elements must all be contained by the same parent, and it will work best if these elements are the only children in that parent (for instance, all the list items in a list). Additionally, the effect will set their position to be relative if they are not positioned. Absolutely positioned elements will likely have trouble (I haven't tested that out yet).
Here's what it looks like to create one:
var mySort = new Fx.Sort($$('ul li'));
mySort.sort([3,2,1,0]); //specify a specific order
mySort.forward(); //0,1,2,3,etc.
Here's a quick demo (I've already created the instance of the effect for this demo):
vert.forward(); //0,1,2,3,etc.
vert.backward(); //3,2,1,0
vert.swap(3,1);
vert.reverse(); //reverses the current order
Finally, you can sort a list and then rearrange the DOM so that the new sort is reflected in the body of the document.
vert.backward().chain(vert.rearrangeDOM.bind(vert));