Shuffle Letters Effect: a jQuery Plugin

Demo Download

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.

jquery-shuffle-letters.jpg

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.

Bootstrap Studio

The revolutionary web design tool for creating responsive websites and apps.

Learn more

Related Articles

Ralph Almeida

woooo veeeery great!

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

WOOW!! Awesome!

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

Awesome.

e11world

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

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

Praveen Gowda I V

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

Martin Angelov

Can you give a screenshot?

really cool I was looking for it,

Paul Santosh

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

Abdullah Al Mamun

WOW! simple and awesome :)

Beben Koben

it's a cool and attractive ☺
thanks^^

Codeforest

Thanks for this, Martin.

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

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

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

Martin Angelov

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.

Aneek Mukhopadhyay

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.

damienfaivre.fr

Amazing ! Great plugin, thanks :)

Créer un site internet

Nice effect !

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

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

devzonefr

Very good plugin!

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

  • +
Martin Angelov

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

Ankabout

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.

Martin Angelov

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.

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!

Darren Ratcliffe

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

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?

another great plugin, thanks man

Nice! :D

Francisc

Well done.

Very Nice jQuery Tutorial!

Private Identity

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 ;)

vrushank

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

Web development companies

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

Very cool, thanks!

Does not seem to work on IE 8?

AngryObject

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.

I need same effect on mouse hover is that possible?

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

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

how to make it repeat?

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

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

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?

Créateur de site

I think you're a genius guy

Great! thank you for sharing this.

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

Cool. I am using it

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?

hey real cool,

What to do when i want two input fields?

nice work!!!

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

Kishan Sharma

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

Awais Raza

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.

Martin Conrad

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.

Joseph paulino

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

Mike Pickett

Great script!

I am wondering if there would be a way to implement this on hover to unscramble text in navigation?

As an example the navigation would start as "cevreiss" and then when hovered over it would read "services"?

Michael Trythall

I needed to update this to do a few things and given the MIT license I put it on Github here:

https://github.com/lincolnloop/jquery.shuffleLetters

This is a great bit of code that helped me out in a bind. Please feel free to fork or submit patches.

Hi!

Awesome plugin!

I just wondered why the DOM objects which are treated with letter shuffle don't take CSS attributes or other jquery effects in anymore? For example, now only CSS code for <body> affects text size and stuff.

To be specific, I'm trying to use Glitch jQuery plugin by Hyperglitch (http://hyperglitch.com/dev/glitch-jquery-plugin) to shuffled texts but it only works if I remove the text shuffler script. And of course it would be nice to be able to manipulate shuffled objects in CSS too.

Is there any means to fix it? Thank you in advance!

Ok, solved it by loading the glitcher script only after the shuffle had loaded. CSS works fine too, there was just some minor negligence.

Callback doesn't work for me.
i.e.
$(p).shuffleLetters({
callback: function () {
console.log("shuffle complete")
}
});