jQuery and JavaScript Phrasebook (2014)

12. Animation and Other Special Effects

One of the most important features of jQuery is the ability to add animations to changes you are making to elements. This gives the user the feel of a slick, well-developed application rather than a clunky, traditional web page.

This is especially true if you are moving, resizing, or dynamically adding elements to the web page. It is frustrating as a user to all of the sudden have a bunch of new things appear or disappear. Using transitions gives the user a chance to see where elements are expanding from, shrinking to as well as the direction of movement so he can adjust his mind-set to accept the changes.

Understanding jQuery Animation

jQuery animation is the process of modifying the property of an HTML element from one value to another in an incremental fashion that’s visible to the user. This section describes that process and how to implement animations on CSS attributes.

Animating CSS Settings


$("img").animate({height:100, width:100});
$("p").animate({margin-left:30});


Most animation in jQuery is done via the .animate() method. The .animate() jQuery method allows you to implement animations on one or more CSS properties. Keep in mind that the .animate() method acts on all elements in the jQuery object set at the same time. Often, you only want to act on a single element, so you need to filter the set down to one.

The .animate() method accepts a CSS property object mapping as the first argument. You can specify more than one property in the object to animate multiple properties at the same time. For example, the following code animates the height and width properties for <img> elements:


$("img").animate({height:100, width:100});



By the way

The .animate() method can only animate properties that have a numerical value. For example, you cannot animate a border style, but you can animate a border size.


There are a couple of different ways to call the .animate() method. The following shows the syntax of both:


.animate(properties [, duration] [, easing] [, complete])
.animate(properties, options)


The first method allows you to specify the duration, easing, and complete functions as optional arguments. The second method allows you to specify the options as a single option map object. For example, the following calls .animate() with a duration and easing object map:


$("img").animate({height:100, width:100},
  {duration:1000, easing:"linear"});



Did you know?

You cannot animate color changes using the color names, but you can animate color changes using hex values, such as #ff0000.


Table 12.1 describes the different options available for the .animate() method. These options are also available on some of the other animation methods that will be discussed later in this chapter.

Image

Image

Table 12.1 Animation Options

Image

Figure 12.1 jQuery and jQuery UI easing functions.

Understanding Animation Queues

Animations happen asynchronously with code executing, meaning that the code continues to execute while the animation is happening. So what happens if you specify another animation for an object before the first one completes? The answer is that jQuery queues up the animations and then executes them in order one after another until all are competed. That is, unless you specify queue:false in the animation options.

You need to understand the animation queue because if you allow user interactions to queue up too many animations by moving the mouse or clicking, the animations will be sluggish and behind the users’ actions.


Watch out!

You need to pay attention to where you trigger your animations from. Remember that events will bubble up. If you execute the same animation from all levels during the bubble up phase, you can have some seriously undesired results. To prevent this, you can use thestopPropagation() and stopImmediatePropagation() methods.


Stopping Animation


$("*").stop();
$("#img1").stop(true);
$("img").stop(true, true);


jQuery allows you to stop the animations currently executing on elements contained in the jQuery object set. The .stop([clearQueue] [, jumpToEnd]) method allows you stop animations in a few different ways.

Calling .stop() with no parameters simply pauses the animations that are in the queue. The next animation that starts begin executing the animations in the queue again. For example, the following code pauses all animations:


$("*").stop();


Calling .stop(true), with the cleareQueue option set to true stops animations at the current point and removes all animations from the queue. For example, the following stops all animations on images and removes the animations from the queue:


$("img").stop(true);


Calling .stop(true, true), with the jumpToEnd option set to true, causes the currently executing animation to jump to the end value immediately, clear the queue, and then stop all animations. For example, the following stops all animations on images but finishes the adjustment made by the current animation and then removes the animations from the queue:


$("img").stop(true, true);


The .stop()  method returns the jQuery object, so you can chain additional methods onto the end. For example, the following code stops all animations on images and then starts a new one to set the opacity to .5:


$("img").stop(true, true).animate({opacity:.5}, 1000);


Delaying Animation


$("img").animate({width:500},
  1000).delay(2000).animate({
    opacity:1} 1000);


A great option when implementing animations is adding a delay before the animation is added to the queue. You can use this to provide animations in a more advanced way because you delay the execution of the animation queue, giving the user a better visual experience.

The .delay(duration, [, queueName]) method allows you to specify the delay duration in milliseconds as well as an optional queueName that specifies which queue to apply the delay to. For example, the following code adds a size animation to images. Once the size is complete, there is a delay of 2 seconds, and the opacity animates up to 1:


$("img").animate({width:500}, 1000).delay(2000).animate({opacity:1} 1000);



By the way

The .delay() method is great for delaying between queued jQuery effects; however, it is not a replacement for the JavaScript setTimeout() function, which may be more appropriate for certain use cases—especially when you need to be able to cancel the delay.


Animating Visibility

jQuery also provides animation capability in fade methods attached to the jQuery objects. In the end, the fade methods are equivalent to using .animate() on the opacity property.

The following sections describe applying animation to the various fading methods.

Fading Elements In


$("img").fadeIn(1000, "swing");


The .fadeIn( [duration] [, easing] [, callback]) method provides the optional duration, easing, and callback options that allow you to animate fading the opacity of an element from its current value to 1.

For example, the following code applies an animation of 1 second with swing easing to all image elements:


$("img").fadeIn(1000, "swing");


Fading Elements Out


$("img").fadeOut(1000, "swing", function() {
  $(this).fadeIn(1000);});


The .fadeIn( [duration] [, easing] [, callback]) method provides the optional duration, easing, and callback options, allowing you to animate fading the opacity of an element from its current value to 0.

For example, the following code applies an animation of 1 second with swing easing to all image elements. Then, when completed, it fades them back in again:


$("img").fadeOut(1000, "swing", function() {
$(this).fadeIn(1000);});


Toggling Element Visibility On and Off


$("img").fadeToggle(3000, "swing");


The .fadeToggle( [duration] [, easing] [, callback]) method provides the optional duration, easing, and callback options, allowing you to animate fading the opacity of an element from its current value to 0, depending on its current value.

For example, the following code applies an animation of 3 seconds with swing easing to all image elements. Images that are currently visible are faded out, and images that are currently transparent are faded in:


$("img").fadeToggle(3000, "swing");


Fading to a Specific Level of Opacity


$("img").fadeTo(2000, .5);
$("img").fadeTo(2000, 1);
$("img").fadeTo(2000, .1);


The .fadeTo( duration, opacity [, easing] [, callback]) method provides the duration and opacity options that specify a specific opacity to end at and how long to animate the transition. It also provides optional easing and callback arguments.

For example, the following code applies an animation of 2 seconds for all images to transition from the current opacity to .5:


$("img").fadeTo(2000, .5);


Adding a Transition When Changing Images


. . . jQuery . . .
$("img").on("click", function(){
  $("#top").fadeToggle(2000);
});
. . . HTML . . .
<img id="bottom" src="lake.jpg" />
<img id="top" src="volcano.jpg" />


You cannot directly animate the transition from one image to another so that one image is fading in while the other is fading out. The way to overcome that challenge is to have two images—one on top of the other—and then animate fading the top one out.

The following code does just that. There are two images with fixed positioning. When you click on the top image, it toggles the image opacity in and out, as shown in Figure 12.2.


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-2.0.3.min.js"></script>
07   <script type="text/javascript"
08     src="../js/jquery-ui-1.10.3.min.js"></script>
09   <link rel="stylesheet" type="text/css"
10     href="../js/css/jquery-ui-1.10.3.min.css">
11   <script>
12     $(document).ready(function(){
13       $("img").on("click", function(){
14         $("#top").fadeToggle(2000);
15       });
16     });
17   </script>
18   <style>
19     img { position:fixed; height:300px;
20        border:3px ridge white;
21        box-shadow:5px 5px 5px #888888;
22        margin:10px; background-color:black;}
23   </style>
24   </head>
25   <body>
26     <div>
27       <img id="bottom" src="lake.jpg" />
28       <img id="top" src="volcano.jpg" />
29     </div>
30   </body>
31 </html>


ch1201.html

Image

Figure 12.2 Animating transitions between images using jQuery code in ch1201.html.

Making an Element Slide Back to Disappear


$("span").mouseover(function(){
  var i = $(this).index("span");
  $("img").eq(i).animate({height:100}, 1000); });
$("span").mouseout(function(){
  var i = $(this).index("span");
  $("img").eq(i).animate({height:.1}, 1000); });
$("#container").mouseenter(function(e){
    e.stopPropagation();
    $("#images").stop(true).slideToggle(1000); });
$("#container").mouseleave(function(e){
    e.stopPropagation();
    $("#images").stop(true).slideToggle(1000); });


The .fadeTo( duration, opacity [, easing] [, callback]), .fadeTo( duration, opacity [, easing] [, callback]), and .fadeTo( duration, opacity [, easing] [, callback]) methods provide the duration, easing, andcallback arguments that allow you to animate sliding effects in the vertical direction.

For example, the following code applies an animation of 1 second to slide an element down and then a delay of 3 seconds to slide the element back up:


$("#menu").slideDown(1000).delay(3000).slideUp(1000);


You can animate the .slideToggle() method in a similar fashion. For example, the following code animates visibility of a <div> element using a slide animation:


$("div").slideToggle(1000);


I like to use the width and height properties to create a sliding element. You can create a vertical slide animation by animating the height and a horizontal slide animation by animating the width.

There are a couple of tricks. You need to provide both a width and a height value for the element if you want to have the full slide effect and not just a resize effect. Also, if you want the element to maintain space on the page, you cannot animate the value all the way down to 0. However, you can animate down to .1 and the other dimension will retain its space.

The following example shows a slide down animation by changing the height to 100 and then back up by changing the height to .1:


$("img").animate({height:100}, 1000);
$("img").animate({height:.1}, 1000);


The following code creates a simple web page with a title bar that has a sliding effect revealing an image menu, as shown in Figure 12.3. As you hover over each item in the menu, an image slides down and then slides back up as you leave the menu:


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-2.0.3.min.js"></script>
07   <script type="text/javascript"
08     src="../js/jquery-ui-1.10.3.min.js"></script>
09   <link rel="stylesheet" type="text/css"
10     href="../js/css/jquery-ui-1.10.3.min.css">
11   <script>
12     $(document).ready(function(){
13       $("div div").hide();
14       $("span").mouseover(function(){
15         var i = $(this).index("span");
16         $("img").eq(i).animate({height:100}, 1000); });
17       $("span").mouseout(function(){
18         var i = $(this).index("span");
19         $("img").eq(i).animate({height:.1}, 1000); });
20       $("#container").mouseenter(function(e){
21           e.stopPropagation();
22           $("#images").stop(true).slideToggle(1000); });
23       $("#container").mouseleave(function(e){
24           e.stopPropagation();
25           $("#images").stop(true).slideToggle(1000); });
26     });
27   </script>
28   <style>
29     img{ display:inline-block; width:100px; height:.1px;
30       margin:0px; padding:0px; float:left;}
31     p, span { display:inline-block; width:400px;
32       background-color:black; color:white;
33       margin:0px; padding:0px; text-align:center;
34     }
35     span {width:100px; margin:-1px; float:left;
36       border:1px solid; background-color:blue; }
37     #container { width:410px; }
38   </style>
39   </head>
40   <body>
41     <div id="container">
42       <p>Images</p>
43       <div id="images">
44         <span>Image 1</span><span>Image 2</span>
45         <span>Image 3</span><span>Image 4</span><br>
46         <img src="img1.jpg" /><img src="img3.jpg" />
47         <img src="img5.jpg" /><img src="img7.jpg" />
48       </div>
49     </div>
50   </body>
51 </html>


ch1202.html

Image

Figure 12.3 Animating expanding and collapsing menus using sliding techniques in jQuery code in ch1202.html.

Animating Show and Hide

You have already seen the .show() and .hide() methods in action in Chapter 9, “Dynamically Working with Form Elements.” It is common practice to animate this functionality, so jQuery has nicely provided animation options for these methods to make your life easier.

Animating hide()


$("#box").hide(1000, "linear", function() {
  $("#label").html("Hidden!") });


The .hide( [duration] [, easing] [, callback]) method provides the optional duration, easing, and callback options allowing you to animate the hide effect, making less of a jump when the element disappears.

For example, the following code applies an animation of 1 second with linear easing and executes a simple callback function when hiding an element:


$("#box").hide(1000, "linear", function() {
   $("#label").html("Hidden!") });


Animating show()


$("#box").show(1000, "linear", function() {
   $("#label").html("Shown!") });


The .show( [duration] [, easing] [, callback]) method provides the optional duration, easing, and callback options, allowing you to animate the show effect and make an easier transition as an element appears.

For example, the following code applies an animation of 1 second with linear easing and executes a simple callback function when showing an element:


$("#box").show(1000, "linear", function() {
   $("#label").html("Shown!") });


Animating toggle()


if ($("#handle").html() == '+'){
  $("#photo").show(1000, function(){
    $("#footer").toggle();});
  $("#handle").html('-');
} else {
  $("#footer").toggle();
  $("#photo").hide(1000);
  $("#handle").html('+'); }


The .toggle( [duration] [, easing] [, callback]) method provides the optional duration, easing, and callback options, allowing you to animate the toggle between the show and hide effect.

For example, the following code applies an animation of 1 second with linear easing and executes a simple callback function when toggling an element between hidden and shown:


$("#switch").show(1000, "linear", function() {
  $("#label").html("Switch Toggled!") });


The following code implements the .hide(), .show(), and .toggle() and creates a simple web element that provides a title bar with a collapse and expand button on the left so you can expand and collapse an image. Figure 12.4 illustrates the animation.


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-2.0.3.min.js"></script>
07   <script type="text/javascript"
08     src="../js/jquery-ui-1.10.3.min.js"></script>
09   <link rel="stylesheet" type="text/css"
10     href="../js/css/jquery-ui-1.10.3.min.css">
11   <script>
12     function toggleImage(){
13       if ($("#handle").html() == '+'){
14         $("#photo").show(1000, function(){
15           $("#footer").toggle();});
16         $("#handle").html('-');
17       } else {
18         $("#footer").toggle();
19         $("#photo").hide(1000);
20         $("#handle").html('+');
21       }
22     }
23     $(document).ready(function(){
24       $("#handle").click(toggleImage);
25     });
26   </script>
27   <style>
28     div{ width:200px; text-align:center; }
29     #bar, #handle, #footer{ font-weight:bold;
30       background-color:blue; color:white; }
31     #handle{ display:inline-block; cursor:pointer;
32       background-color:black; width:15px; float:left; }
33     #footer{ font-size:10px; background-color:black; }
34   </style>
35   </head>
36   <body>
37     <div>
38       <div id="bar"><span id="handle">-</span>
39         <span>Image</span></div>
40       <img id="photo" src="img3.jpg" width="200px"/>
41       <div id="footer">Image Ready</div>
42     </div>
43   </body>
44 </html>


ch1203.html

Image

Figure 12.4 Animating showing and hiding image elements in jQuery code in ch1203.html.

Animating Resizing an Image


$("img").mouseover(function(){
    $(this).animate(
      {width:"200px", opacity:1}, 1000); });
$("img").mouseout(function(){
    $(this).animate(
      {width:"100px", opacity:.3}, 1000); });


Similar to the way you use the height and width to create a sliding effect, you can use them to create a resize animation. The difference between a slide and a resize is that the aspect ratio of the image is maintained on a resize, so the element appears to be growing or shrinking rather than being unfolded or untucked.

To create a resize animation, you need to specify both height and width in the .animate() statement, or one of them has to be auto in the CSS settings and you can only animate the one that has a value.

The following code shows a resize animation of an image up to 500 pixels over 1 second and then slowly over 5 seconds back down to 400 pixels:


$("img").animate({height:500, width:500}, 1000).animate(
  {height:500, width:500}, 5000);


The following code creates a basic image gallery view that resizes images and applies opacity changes in the same animation as the mouse enters and leaves the image (see Figure 12.5).


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-2.0.3.min.js"></script>
07   <script type="text/javascript"
08     src="../js/jquery-ui-1.10.3.min.js"></script>
09   <link rel="stylesheet" type="text/css"
10     href="../js/css/jquery-ui-1.10.3.min.css">
11   <script>
12     $(document).ready(function(){
13       $("img").mouseover(function(){
14           $(this).animate(
15             {width:"200px", opacity:1}, 1000); });
16       $("img").mouseout(function(){
17           $(this).animate(
18             {width:"100px", opacity:.3}, 1000); });
19     });
20   </script>
21   <style>
22     div{ padding:0px; }
23     img{ opacity:.3; width:100px; float:left; }
24   </style>
25   </head>
26   <body>
27     <div id="photos">
28       <img src="img1.jpg"/><img src="img2.jpg"/>
29       <img src="img3.jpg"/><img src="img4.jpg"/>
30       <img src="img5.jpg"/>
31     </div>
32   </body>
33 </html>


ch1204.html

Image

Figure 12.5 Animating resizing an image using jQuery code in ch1204.html.

Animating Moving an Element


var position = $("#element").offset();
$("#element").animate({top:position.top+10,
    top:position.left+100}, 1000);


Another dynamic that is good to animate is repositioning of elements—specifically, moving an element from one location to another. Users hate it when they do something and page elements suddenly appear in a different location. Animating the move allows users to see where things go and make the necessary adjustments in their thinking.

To apply move animations, you will be animating changes to the top and left CSS properties. To animate movement vertically, you use top, and to animate horizontally, you use left. For example, the following statements animate moving an element to the right 10 pixels and then down 10 pixels:


var position = $("#element").offset();
$("#element").animate({top:position.top+10}, 1000);
$("#element").animate({top:position.left+10}, 1000);


You can also animate in a diagonal direction by animating both top and left at the same time. For example, the following animates movement down 10 pixels and to the right 100 pixels in the same animation:


var position = $("#element").offset();
$("#element").animate({top:position.top+10,
top:position.left+100}, 1000);


The following code shows an example of employing a move animation for a pointless purpose, although it does illustrate the use of this phrase. When the button, shown in Figure 12.6, is hovered over, a move animation moves the element to a new location on the screen, making it impossible to click on:


01 <html>
02   <head>
03   <title>Python Phrasebook</title>
04   <meta charset="utf-8" />
05   <script type="text/javascript"
06     src="../js/jquery-2.0.3.min.js"></script>
07   <script type="text/javascript"
08     src="../js/jquery-ui-1.10.3.min.js"></script>
09   <link rel="stylesheet" type="text/css"
10     href="../js/css/jquery-ui-1.10.3.min.css">
11   <script>
12   function randInt(max, min) {
13       return Math.floor((Math.random()*max)+min); }
14     $(document).ready(function(){
15       $("span").mouseover(function(){
16           var newTop = randInt(500,10);
17           var newLeft = randInt(700,10);
18           $(this).animate(
19             {top:newTop, left:newLeft}, 200); });
20     });
21   </script>
22   <style>
23     span {border:3px ridge blue; padding:5px; position:fixed;
24       border-radius: 30px 10px; background-color:blue; color:white;
25       font:bold italic 22px cursive, serif; }
26   </style>
27   </head>
28   <body>
29     <span>Click Here</span>
30   </body>
31 </html>


ch1205.html

Image

Figure 12.6 Animating moving and element using jQuery code in ch1205.html.