Friday, 5 April 2013

jQuery: Slideshow Shuffle Letters


In this short tutorial we will be making a jQuery plugin that will shuffle the text content of any DOM element – an interesting effect that can be used in headings, logos and slideshows.
Updated on 10 Sep 2011: The plugin was slightly improved by including a callback function, called when the animation is complete. Just pass it as a property of the arguments object: $(‘#el’).shuffleLetters({callback:function(){}});

The Code

The first step is to write the backbone of our jQuery plugin. We will place the code inside a self-executing anonymous function, and extend $.fn.

assets/js/jquery.shuffleLetters.js

01(function($){
02 
03    $.fn.shuffleLetters = function(prop){
04 
05        // Handling default arguments
06        var options = $.extend({
07            // Default arguments
08        },prop)
09 
10        return this.each(function(){
11            // The main plugin code goes here
12        });
13    };
14 
15    // A helper function
16 
17    function randomChar(type){
18        // Generate and return a random character
19    }
20 
21})(jQuery);
Next we will turn our attention to the randomChar() helper function. It will take a type argument (one of “lowerLetter“, “upperLetter” or “symbol“) and return a random character.
01function randomChar(type){
02    var pool = "";
03 
04    if (type == "lowerLetter"){
05        pool = "abcdefghijklmnopqrstuvwxyz0123456789";
06    }
07    else if (type == "upperLetter"){
08        pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
09    }
10    else if (type == "symbol"){
11        pool = ",.?/\\(^)![]{}*&^%$#'\"";
12    }
13 
14    var arr = pool.split('');
15    return arr[Math.floor(Math.random()*arr.length)];
16}
We could have used a single pool string for all types of characters, but this will do for a better effect.
The Plugin In Action
The Plugin In Action
Now lets write the body of the plugin!
01$.fn.shuffleLetters = function(prop){
02 
03    var options = $.extend({
04        "step"  : 8,    // How many times should the letters be changed
05        "fps"   : 25,   // Frames Per Second
06        "text"  ""    // Use this text instead of the contents
07    },prop)
08 
09    return this.each(function(){
10 
11        var el = $(this),
12            str = "";
13 
14        if(options.text) {
15            str = options.text.split('');
16        }
17        else {
18            str = el.text().split('');
19        }
20 
21        // The types array holds the type for each character;
22        // Letters holds the positions of non-space characters;
23 
24        var types = [],
25            letters = [];
26 
27        // Looping through all the chars of the string
28 
29        for(var i=0;i<str.length;i++){
30 
31            var ch = str[i];
32 
33            if(ch == " "){
34                types[i] = "space";
35                continue;
36            }
37            else if(/[a-z]/.test(ch)){
38                types[i] = "lowerLetter";
39            }
40            else if(/[A-Z]/.test(ch)){
41                types[i] = "upperLetter";
42            }
43            else {
44                types[i] = "symbol";
45            }
46 
47            letters.push(i);
48        }
49 
50        el.html("");           
51 
52        // Self executing named function expression:
53 
54        (function shuffle(start){
55 
56            // This code is run options.fps times per second
57            // and updates the contents of the page element
58 
59            var i,
60                len = letters.length,
61                strCopy = str.slice(0); // Fresh copy of the string
62 
63            if(start>len){
64                return;
65            }
66 
67            // All the work gets done here
68            for(i=Math.max(start,0); i < len; i++){
69 
70                // The start argument and options.step limit
71                // the characters we will be working on at once
72 
73                if( i < start+options.step){
74                    // Generate a random character at this position
75                    strCopy[letters[i]] = randomChar(types[letters[i]]);
76                }
77                else {
78                    strCopy[letters[i]] = "";
79                }
80            }
81 
82            el.text(strCopy.join(""));
83 
84            setTimeout(function(){
85 
86                shuffle(start+1);
87 
88            },1000/options.fps);
89 
90        })(-options.step);
91 
92    });
93};
The plugin will take either the contents of the DOM element it was called on, or the text property of the object passed as an argument. It then splits the string into characters and determines the type of each one. The shuffle function then uses setTimeout() to call itself and randomize the string, updating the DOM element on each step.
When you head on to the demo you will see that you are able to type your own text and test it out. Here is how I did it:

assets/js/script.js

01$(function(){
02 
03    // container is the DOM element;
04    // userText is the textbox
05 
06    var container = $("#container")
07        userText = $('#userText');
08 
09    // Shuffle the contents of container
10    container.shuffleLetters();
11 
12    // Bind events
13    userText.click(function () {
14 
15      userText.val("");
16 
17    }).bind('keypress',function(e){
18 
19        if(e.keyCode == 13){
20 
21            // The return key was pressed
22 
23            container.shuffleLetters({
24                "text": userText.val()
25            });
26 
27            userText.val("");
28        }
29 
30    }).hide();
31 
32    // Leave a 4 second pause
33 
34    setTimeout(function(){
35 
36        // Shuffle the container with custom text
37        container.shuffleLetters({
38            "text""Test it for yourself!"
39        });
40 
41        userText.val("type anything and hit return..").fadeIn();
42 
43    },4000);
44 
45});
The fragment above also shows how you can use the plugin and the custom text parameter.

Done

I hope you find this plugin useful and have fun with it. It is released under the MIT license.

No comments:

Post a Comment