Question

I'm trying to make a random text effect kinda like the one at the end of the movie War Games (Matthew Broderick). The idea is to have individual letters change randomly when ever the user hovers over one of the letters in the word. Eventually after a short time the letter would end up being "decoded" meaning that it would end up on the right letter or number. I have built basic effect but the part I am struggling with is setting the timer. I want to create a small delay between the hover-out event and the actual display of the decoded character. When i add a settimeout however. The script breaks and seems to stack timers. I'm not sure what I'm doing wrong. Below is the code I've got so far.. any help would be great.

function setDecodedChar(object){
    var decodedMessage = "HELLO WORLD";
    var index = object.attr('class').substring(4);
    console.log(index);
    object.html(decodedMessage[index]);


}

function changeChar(object){
    var randomchar = getrandomChar();
    object.html(randomchar);
}

function getrandomChar(){
    var char = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    char = possible.charAt(Math.floor(Math.random() * possible.length));
    return char;
}

$(function() {
    typesetting.letters('.title-text');

    var target = $(".title-text").children();
    console.log(target);

    var timer;
    var gate = true; 
    $(target).hover(function(){
            var charChar = $(this);
            //on hover-over
            if(gate){
                gate = false;
                timer=setInterval(function(){
                    changeChar(charChar);
                },100);
            }
        },function(){
            //on hover-out
            setTimeout(function(){ //<-- breaks here
                                clearInterval(timer) 
                setDecodedChar($(this));
                            },1000);
            gate = true;
        }
    );

});

Here is a jsfiddle of the effect as I currently have it working. http://jsfiddle.net/thesnooker/htsS3/

Was it helpful?

Solution

I really like your idea, and I worked on it. I got it working.

First, here a fiddle : http://jsfiddle.net/htsS3/2/

I must say, i don't know if its the optimal way, but it still working!

The problem with you method is that you have 1 timer for every character, they override themselves, so some letters wont stop.

How i solve it:

I set the timer in the data of every letter like that :

$(this).data('timer', setInterval(function () {
    changeChar(charChar);
}, 100));

Not every span have their own timer.

On hover out, i ad to save the $(this) reference into a `var since you lost it in the timeout. I alos saved the timeout into the data so i could stop it when you hover it and it's still changing. Well it look like that now :

var $this = $(this);
$this.data('timeout', setTimeout(function(){
    clearInterval($this.data('timer'));
    setDecodedChar($this);
},1000))

And finally, on hover, i had to clear timeout and interval:

clearInterval($(this).data('timer'));
clearTimeout($(this).data('timeout'));

Well, I find it hard to explain in my own word, so take a good look at the code and enjoy!

OTHER TIPS

setsetTimeout(function(){ //<-- breaks here
                            clearInterval(timer) 
            setDecodedChar($(this));
                        },1000);

You have an extra 'set'

setTimeout(function(){ //<-- breaks here
                            clearInterval(timer) 
            setDecodedChar($(this));
                        },1000);

So the issue could be related to the timer. It changes every time the setInterval is called. If you were to store the interval on the hover object then clear it by using the stored reference it works.

Cool concept by the way.

$(function () {
     var target = $(".text").children();
     var timer;

     $(target).hover(function () {
         var charChar = $(this);

         if($(this).data("timer") == void(0)) {
             if($(this).data("timeout") != void(0)) {
                 clearTimeout($(this).data("timeout"));
             }

             $(this).data("timer", setInterval(function () {
                 changeChar(charChar);
             }, 100));
         }
     }, function () {
         //on hover-out
         var timerObject = $(this);
         timerObject.data("timeout", setTimeout(function() {
             clearInterval(timerObject.data("timer")); 
             setDecodedChar(timerObject); 
             timerObject.removeData("timer");
         }, 1000));             
     });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top