Shuffle Letters Effect: a jQuery Plugin

Shuffle Letters Effect: a jQuery Plugin

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.

The Plugin In Action

The Plugin In Action

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.

Join our newsletter and get our PSDs!18,969 people learn about HTML5, JS and more. Join them!

by Martin Angelov

Martin is a web developer with an eye for design from Bulgaria. He founded Tutorialzine in 2009 and it still is his favorite side project.

56 Comments

  1. Imran says:

    Really great plugin, I will be going to use it...

  2. Alberto says:

    WOOW!! Awesome!

    I will made a Airport Timetable-like style basing on this script to scroll the letters!!

    Awesome.

  3. e11world says:

    Totally love it! I'm so gonna use this! Thank you very much!

  4. Ashish says:

    Wow, it's cool... I was thinking to make it myself, but thanks god, you done it.
    Great work... thanks!!

  5. Nice effect
    But when we enter some text of our own and hit Return
    the shuffling occurs just once
    can anyone help ?

    1. Martin Angelov says:

      Can you give a screenshot?

  6. Moksha says:

    really cool I was looking for it,

  7. Paul Santosh says:

    It's really Super Awesome and it also works in Blogger(Blogspot) blogs!!!!!

  8. WOW! simple and awesome :)

  9. Beben Koben says:

    it's a cool and attractive ☺
    thanks^^

  10. Codeforest says:

    Thanks for this, Martin.

    It really amazes me how easy it is for you to produce great stuff.

  11. Erik says:

    Oh my god !
    It's so amazing !
    Like call of duty 4 mission briefing.
    I add this to user login effect.
    "System activated" )

  12. A_Minko says:

    Great plugin, I really like the idea.

    In demo, when I fast press Enter button two times result is random sequence of symbols.

    Regards, A_Minko

    1. Martin Angelov says:

      The second time you hit enter, the plugin is run again, taking the current content of the div (shuffled by the previous call to the plugin) and animating it. It is not much of a problem, as the plugin is meant to animate static text and not to be interactive like in the demo. But if you need to, you can set a flag to prevent animations running in parallel.

  13. Hello Martin,

    I must say, nice tutorial indeed. I am following tutorialzine for a long time now.
    This one is great. I often use jQuery a lot in websites. I am going to use this piece of fine code snippet to make a drupal module for my site.

    Thank you again for this awesome piece of jQuery.

  14. Amazing ! Great plugin, thanks :)

  15. egiova says:

    I wonder if there is a way to integrate this effect on a slideshow, or in combination with slide deck

  16. egiova says:

    By the way, I'm amazed by the quantity and the quality of your tuts. And this effect opened great perspectives... Thanks.

  17. devzonefr says:

    Very good plugin!

    Just one question: how to detect the end of the animation ?

    + +

    1. Martin Angelov says:

      The plugin can now take a callback property that is called when the animation is complete.

  18. Ankabout says:

    Can I change this script to loop through certain DOMs within a parent, and shuffle one into the next? So basically one string will shuffle and become the next one, and so on.

    The strings would be children of a certain DOM.

    1. Martin Angelov says:

      Yes this won't be that difficult. If you have an unordered list (each li being a phrase you would shuffle), you can simply call the plugin for each phrase. You can use the text argument and the newly added callback to trigger the plugin with the next string.

      1. Eesur says:

        Hey Martin, am trying to get one word shuffle to fade in to another word after the 4seconds (have made the unordered list with each li as a word).

        What should I change in script.js to remove the user input and feed the pre-set words from the list?

        So they go through the list and stop on the last word.

        Any pointers greatly appreciated and will post the finished bit of play when done, thanks for great example!

        1. Darren Ratcliffe says:

          Hey Eesur, did you manage to get this working? I'm just trying to do the same!

    2. marta says:

      hi... i am having troubles with this code. i am new to jquery.
      did you did that changes to the code. i would like to do the same, i tried a few things and i can't get anywhere. may you help me?

  19. aditia says:

    another great plugin, thanks man

  20. Diego says:

    Nice! :D

  21. Francisc says:

    Well done.

  22. Sanchit says:

    Very Nice jQuery Tutorial!

  23. Just in case, and as nobody appears to be mentioning this..
    The plugin writes in all languages your browser support, try Arabic or Russian for example ;)

  24. vrushank says:

    Looks like seen it before but just decided to use it now. Cool demo!!

  25. Thank you for this magnificent descriptive guide and the provided demo. Will be using this plugin for sure!

  26. JimJ says:

    Very cool, thanks!

  27. Ich says:

    Does not seem to work on IE 8?

  28. AngryObject says:

    Thanks! That one was clean and cool! I really like it.

    But it only shuffles latin chars. If you enter text in some other language - you will end up with shuffling symbols whereas there was a letter. But it's easy to tune with just a couple of extra if statements.

    ...
    else if(/[A-Z]/.test(ch)){
      types[i] = "upperLetter";
    }
    else if(/[а-я]/.test(ch)){
      types[i] = "lowerLetterRus";
    }
    else if(/[А-Я]/.test(ch)){
      types[i] = "upperLetterRus";
    }
    ...
    ...
    else if (type == "upperLetter"){
      pool = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    }
    if (type == "lowerLetterRus"){
      pool = "абвгдеёжзийклмнопрстуфхцчшщъыьэюя0123456789";
    }
    else if (type == "upperLetterRus"){
      pool = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ0123456789";
    }
    ...
    

    That's it for russian letters in case anyone need it.

  29. Peter says:

    I need same effect on mouse hover is that possible?

  30. Shaxine says:

    Great Plugin!
    how can a do this effect with 2 or more lines of text?

  31. Chris says:

    Hi,

    Really like this function you have built. I am fairly new to Jquery and just wanted to know how you could add a delay on page load, so the animation doesn't start until after say 5 seconds after the page has loaded?

    Thanks

  32. choisy says:

    how to make it repeat?

  33. Nera says:

    I make one php script where function call one DB field instead of type text, all work perfectbut i need make to stop animated on click enter or space ,I put
    "step": 500
    "fps" : 40,
    its long raffling but i want to make to someone stop on enter or space .
    Script need random choice one winner from my MySql database
    All working prefect when animation finished i got winner i just need this part with keypress

    Please can you help me with this ?

    Thank you

  34. Nera says:

    Please dude i need this for finish aplication , and i will put you copyright on footer.

  35. Alex says:

    Definitely a cool thing! I've used it for a couple of projects.

    I have a question... I've got this working on the site title of a Worpress site, but the site title no longer functions as a link. Any ideas how to keep this as a link?

  36. I think you're a genius guy

  37. Naomi says:

    Great! thank you for sharing this.

  38. Trying says:

    Hi, Love this shuffle! I am trying to just get 4 lines of text to roll but I can not figure out how to get it done after the first is showed. Can anyone explain how to do that. I am pretty new to jquery.

    Regards

  39. Ankit says:

    Cool. I am using it

  40. Piojos says:

    hi, i would like to include divs inside the paragraph to apear as inline objects.
    i dont expect them to load random characters when a div is loaded, i just want it to apear on the right order. also i would like to include <a>'s within the paragraphs.

    Can you guide me on how to include these?

  41. jeff says:

    hey real cool,

    What to do when i want two input fields?

  42. jhonfx says:

    nice work!!!

  43. Fred says:

    wow, really a nice one ! I'll use it on my personal website as a home page.
    Thanks Martin! I really appreciate it.

  44. great tutorial got much more then technique, its fascinating the one thing that i like the most is the color combibation loved the font and coding

    really Thanks

  45. Awais Raza says:

    Hi,
    I am not very good at JS, but I want some modification in this script. Can anyone please help. I want the text to alternate automatically after a given amount of time. Like ( I do (JS) ( JQUERY ) ) . So first it should display I do JS, then after given amount of time it should say I do Juqery and so on. Thanks in advance.

  46. Martin Conrad says:

    Really nice tutorial. What I'm trying to do is to shuffle one character of the div after another. Now, when the animation starts, the container goes blank an every charakter is written out inj typewriter style. I would love to have an effect like a flight/departure board.

  47. Joseph paulino says:

    I have never seen any tutorial that teaches shuffling letters without using flash before. This is so cool. Thanks!

Add Comment

Add a Reply

HTML is escaped automatically. Surround code blocks with <pre></pre> for readability.
Perks:   **bold**   __italics__   [some text](http://example.com) for links