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

(function($){ $.fn.shuffleLetters = function(prop){ // Handling default arguments var options = $.extend({ // Default arguments },prop) return this.each(function(){ // The main plugin code goes here }); }; // A helper function function randomChar(type){ // Generate and return a random character } })(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.

function randomChar(type){ var pool = ""; if (type == "lowerLetter"){ pool = "abcdefghijklmnopqrstuvwxyz0123456789"; } else if (type == "upperLetter"){ pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; } else if (type == "symbol"){ pool = ",.?/\\(^)![]{}*&^%$#'\""; } var arr = pool.split(''); return arr[Math.floor(Math.random()*arr.length)]; }

We could have used a single pool string for all types of characters, but this will do for a better effect.

Now lets write the body of the plugin!

$.fn.shuffleLetters = function(prop){ var options = $.extend({ "step" : 8, // How many times should the letters be changed "fps" : 25, // Frames Per Second "text" : "" // Use this text instead of the contents },prop) return this.each(function(){ var el = $(this), str = ""; if(options.text) { str = options.text.split(''); } else { str = el.text().split(''); } // The types array holds the type for each character; // Letters holds the positions of non-space characters; var types = [], letters = []; // Looping through all the chars of the string for(var i=0;i<str.length;i++){ var ch = str[i]; if(ch == " "){ types[i] = "space"; continue; } else if(/[a-z]/.test(ch)){ types[i] = "lowerLetter"; } else if(/[A-Z]/.test(ch)){ types[i] = "upperLetter"; } else { types[i] = "symbol"; } letters.push(i); } el.html(""); // Self executing named function expression: (function shuffle(start){ // This code is run options.fps times per second // and updates the contents of the page element var i, len = letters.length, strCopy = str.slice(0); // Fresh copy of the string if(start>len){ return; } // All the work gets done here for(i=Math.max(start,0); i < len; i++){ // The start argument and options.step limit // the characters we will be working on at once if( i < start+options.step){ // Generate a random character at this position strCopy[letters[i]] = randomChar(types[letters[i]]); } else { strCopy[letters[i]] = ""; } } el.text(strCopy.join("")); setTimeout(function(){ shuffle(start+1); },1000/options.fps); })(-options.step); }); };

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

$(function(){ // container is the DOM element; // userText is the textbox var container = $("#container") userText = $('#userText'); // Shuffle the contents of container container.shuffleLetters(); // Bind events userText.click(function () { userText.val(""); }).bind('keypress',function(e){ if(e.keyCode == 13){ // The return key was pressed container.shuffleLetters({ "text": userText.val() }); userText.val(""); } }).hide(); // Leave a 4 second pause setTimeout(function(){ // Shuffle the container with custom text container.shuffleLetters({ "text": "Test it for yourself!" }); userText.val("type anything and hit return..").fadeIn(); },4000); });

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.