String calculation effect in JavaScript
In one of my posts I wrote about the Strong-Password Plugin. The secret of its attractiveness lays in usage of interesting effect: a new password is being calculated on the eyes of the visitor.
Let’s discuss how to create such an effect. We need a function that will generate our effect of “string calculation”. I named it generate.
var generate = function(str, result, from, delay) {
// Our code will be here....
}
Our function takes four parameters, the first two are required.
str – it’s a string that will be shown at the end (the result of calculations)
result – it’s an html element placed to a jQuery object.
from – it’s a string that contains characters, which paticipate in our animation. The default value is 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz !'
delay – it’s a delay between changes.The default value is 100.
Our function doesn’t return any value, only changes the text on the screen.
First of all, we need an utility function, which will “shuffle” elements of an array:
var shuffle = function(a) {
var i, j, x;
j = void 0;
x = void 0;
i = void 0;
i = a.length;
while (i) {
j = Math.floor(Math.random() * i);
x = a[i - 1];
a[i - 1] = a[j];
a[j] = x;
i -= 1;
}
};
Then we need two functions for recursion.
var outerSort = function() {
var letter, letters, span;
if (strArray.length === 0) {
return;
}
span = $('').appendTo(result);
letter = strArray.shift();
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz !'.split('');
if(from) letters = from.split('');
shuffle(letters);
innerSort(letters, letter, span);
outerSort();
};
var innerSort = function(letters, letter, span) {
var x;
if (!letters || letters.length === 0) {
return;
}
x = letters.shift();
span.html(x);
setTimeout((function() {
if (x === letter) {
span.addClass('sp-generated');
} else {
innerSort(letters, letter, span);
}
}), delay);
};
The outerSort
function uses an outer variable strArray
which stores the string str
, transformed to an array:
strArray = str.split('');
outerSort();
The function takes the first element of the array (by using the shift
method), creates span=$('<span>').appendTo(result)
, makes an array from the from
parameter and shuffles it by using our shuffle
function. Than the outerSort
function calls the innerSort
function and recursively calls itself.
The innerSort function takes every char from the array one by one with the defined delay interval until equality is found.
Now we can call our function to complete our example:
var thanks = $('#thanks');
thanks.click(function(){
$(this).empty();
generate('Thank you a lot!', $(this));
});
var pi = $('#pi');
pi.click(function(){
$(this).empty();
generate('3.1415926535', $(this), '0123456789.', 100);
});
Here it is:
You can see the complete example on Codepen
The code:
var generate = function(str, result, from, delay) {
if(!delay) delay = 50;
var strArray;
var shuffle = function(a) {
var i, j, x;
j = void 0;
x = void 0;
i = void 0;
i = a.length;
while (i) {
j = Math.floor(Math.random() * i);
x = a[i - 1];
a[i - 1] = a[j];
a[j] = x;
i -= 1;
}
};
var outerSort = function() {
var letter, letters, span;
if (strArray.length === 0) {
return;
}
span = $('').appendTo(result);
letter = strArray.shift();
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz !'.split('');
if(from) letters = from.split('');
shuffle(letters);
innerSort(letters, letter, span);
outerSort();
};
var innerSort = function(letters, letter, span) {
var x;
if (!letters || letters.length === 0) {
return;
}
x = letters.shift();
span.html(x);
setTimeout((function() {
if (x === letter) {
span.addClass('sp-generated');
} else {
innerSort(letters, letter, span);
}
}), delay);
};
strArray = str.split('');
outerSort();
};
var thanks = $('#thanks');
thanks.click(function(){
$(this).empty();
generate('Thank you a lot!', $(this));
});
var pi = $('#pi');
pi.click(function(){
$(this).empty();
generate('3.1415926535', $(this), '0123456789.', 100);
});