Shuffle Letters Effect: a jQuery Plugin

Posted by Martin Angelov on Sep 2nd, 2011 in

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.

Sharing is caring

If you enjoyed this post, feel free to
share it with your friends.

Related Tutorials

  • Apple-like Login Form with CSS 3D Transforms
  • Enhance Your Website with the FullScreen API
  • Question of the Day with CodeIgniter and MySQL
  • Making a jQuery Countdown Timer

35 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!

  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.

Subscribe for the comments on this postAdd Comment

Add a Reply

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