Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Revolving text generator

I am in the process of building a revolving text generator. The generator combines sentences (text) from a number of arrays, 'cycles' through them visually and appends them. I thought it best to create a Fiddle with a basic version of the generator as I have constructed it now:

Explanation

The basic workings are as follows:

  1. Sentences are defined in separate arrays (Array1, Array2 and Array3 in the fiddle)
  2. A second set of arrays is defined, containing the arrays that can be combined (combo0 and combo1 in the fiddle)
  3. On pressing the 'Generate' button, the function Generate is called, which visually cycles the sentences from an array of sentences (combo0[0] in the fiddle)
  4. This function loops itself until the sentence has cycled 8 times (var times = 8 in the fiddle)
  5. When this is done, the function calls the callback function that was provided. In this callback, it runs Generate again, this time with the second array (combo0[1] in the fiddle)

The reason for the callback is that I need to 'wait' for the cycling effect to complete, and then move on.

The issue

While this does exactly what I need (and besides the fact that I'm highly doubtful if this is the way to do it; I always feel a bit odd when writing a function that loops itself), I have the following problem:

In the combo arrays, I define which of the 'sentence' arrays can be possible combinations. This works fine if there are two combinations, but with more than two, I have a problem:

Generate(combo0[0], i, function(i) { //generate from first array element of combo0, callback to generating from second array of combo0
    Generate(combo0[1], i, function(i) {
        $('div#status').html('Done!'); //show status
        $('input#generate').removeAttr("disabled"); //enable button
    });
})

I would have to recursively rewrite this to accommodate the possibility of a combo array consisting of 3 or even 4 options. And probably this will break the script if a combo array contains just 2 (or 1) arrays.

This is where I'm stuck. The main issue is that if I loop over the combo array, e.g. with an .each();, the generate function is called multiple times synchronously, so the whole 'cycling' effect is lost.

I have tried writing various loops, which take into account the array length of the given combo array, but I have crashed more browsers today than ever before, and I can't work out what to do.

like image 212
Klaas Leussink Avatar asked Jul 27 '12 13:07

Klaas Leussink


1 Answers

This should do the trick:

var Array1 = new Array("Sentence 1 - A ", "Sentence 1 - B ", "Sentence 1 - C ", "Sentence 1 - D ", "Sentence 1 - E ", "Sentence 1 - F ", "Sentence 1 - G ");
var Array2 = new Array("Sentence 2 - A", "Sentence 2 - B", "Sentence 2 - C", "Sentence 2 - D", "Sentence 2 - E", "Sentence 2 - F", "Sentence 2 - G");
var Array3 = new Array("Sentence 3 - A", "Sentence 3 - B", "Sentence 3 - C", "Sentence 3 - D", "Sentence 3 - E", "Sentence 3 - F", "Sentence 3 - G");

//define acceptable combinations of arrays
var combo0 = new Array(Array1, Array2);
var combo1 = new Array(Array1, Array2, Array3);

//define global vars
var speed = 140;
var content = '';

//write sentence to box. If counter is a multiple of the 'times' var: append instead of write
function showMessage(list, i, e) {
    $('div#generated').html(content + list[i]);
    if ((i + 1) % (e + 1) == 0) content += list[i];
}

//Generate from array 'list', simulating a 'slot machine
function Generate(lists, end, l, i, e) {
    if (l == undefined) l = 0;
    if (i == undefined) i = 0;
    if (e == undefined) e = Math.floor(Math.random() * lists[l].length);
    setTimeout(function() {
        showMessage(lists[l], i, e);
        if ((i + 1) % (e + 1) != 0)
            Generate(lists, end, l, i+1, e);
        else if (lists.length - 1 > l)
            Generate(lists, end, l + 1);
        else end();
    }, speed);
}

$(document).ready(function() {
    $('input#generate').click(function() {
        $(this).attr("disabled", true); //disable button
        content = ''; //reset content
        $('div#status').html('Running..'); //show status
        Generate(combo0, function() {
            $('div#status').html('Done!'); //show status
            $('input#generate').removeAttr("disabled"); //enable button});
        });
    });
});
like image 54
Luka Avatar answered Oct 21 '22 11:10

Luka