Generador de texto giratorio

Estoy en el proceso de construir un generador de texto giratorio. El generador combina oraciones (texto) de un número de arreglos, los 'recorre' visualmente y los agrega. Pensé que era mejor crear un violín con un versión básica del generador como lo he construido ahora:

Explicación

El funcionamiento básico es el siguiente:

  1. Las oraciones se definen en matrices separadas (Array1, Array2 y Array3 en el violín)
  2. Se define un segundo conjunto de matrices, que contiene las matrices que se pueden combinar (combo0 y combo1 en el violín)
  3. Al pulsar el botón 'Generar', la función Generate se llama, que cicla visualmente las oraciones de una matriz de oraciones (combo0[0] en el violín)
  4. Esta función se repite hasta que la oración se repite 8 veces (var times = 8 en el violín)
  5. Cuando se hace esto, la función llama a la función de devolución de llamada que se proporcionó. En esta devolución de llamada, se ejecuta Generate de nuevo, esta vez con la segunda matriz (combo0[1] en el violín)

El motivo de la devolución de llamada es que necesito 'esperar' a que se complete el efecto de ciclo y luego continuar.

La cuestión

Si bien esto hace exactamente lo que necesito (y además del hecho de que dudo mucho si esta es la forma de hacerlo; siempre me siento un poco extraño cuando escribo una función que se repite), tengo el siguiente problema:

En la pestaña combo arreglos, defino cuáles de los arreglos de 'oraciones' pueden ser combinaciones posibles. Esto funciona bien si hay dos combinaciones, pero con mas de dos, tengo un problema:

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

Tendría que reescribir recursivamente esto para acomodar la posibilidad de un combo matriz que consta de 3 o incluso 4 opciones. Y probablemente esto romperá el guión si un combo matriz contiene solo 2 (o 1) matrices.

Aquí es donde estoy atascado. El problema principal es que si hago un bucle sobre el combo matriz, por ejemplo, con un .each();, el generate La función se llama varias veces sincrónicamente, por lo que se pierde todo el efecto de 'ciclado'.

He intentado escribir varios bucles, que tienen en cuenta la longitud de la matriz de la dada combo array, pero hoy he fallado más navegadores que nunca y no sé qué hacer.

preguntado el 27 de julio de 12 a las 14:07

Entonces, ¿necesita una secuencia de comandos que pueda pasar por varias matrices, un elemento a la vez, hasta que llegue a un determinado elemento en la matriz, y luego avance a la siguiente matriz y presente cada paso visualmente? -

Bueno, no un artículo determinado; un elemento aleatorio de una matriz. Necesita imprimir un elemento de matriz x veces, luego, finalmente, escribir uno y continuar con la siguiente matriz. Básicamente, todo lo que necesita hacer es trabajar en Fiddle (ver mi publicación), excepto una matriz que contiene más de 2 matrices. -

Pensé que era mejor crear un violín - ¡sí! +1 -

2 Respuestas

Esto debería funcionar:

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

Respondido 27 Jul 12, 16:07

Wow, esto funciona, solo que parece 'inestable'; no 'cicla' de manera constante en cada matriz (me di cuenta de que dejó caer la variable 'tiempos'). A veces, el primer elemento de la matriz solo se mostrará, el segundo realizará un ciclo 5 veces, el tercero 2 veces. Echaré un vistazo y averiguaré cómo lo lograste y veré si puedo resolverlo. ¡Gracias! - Klaas Leussink

Por desgracia, no puedo averiguar cómo solucionarlo; Necesito que sea estable (siempre ciclando una cantidad determinada para cada elemento de la matriz). ¡Gracias de nuevo por tu sugerencia! - Klaas Leussink

Traté de investigarlo disminuyendo la velocidad a 1 tic por segundo (velocidad = 1000), y no vi ninguna regularidad, simplemente puede deberse a una velocidad demasiado alta. - Luka

Bueno, traté de hacerlo a alta velocidad, revisa tu código en este violín: (intenta varias veces) jsfiddle.net/qC2T6. ¡Mientras tanto, parece que lo he descifrado yo mismo! Publicaré una respuesta a mi propia pregunta en unos minutos. - Klaas Leussink

He conseguido arreglarlo. Algún tiempo lejos de la pantalla es algo bueno.

Lo que hice fue agregar un contador 'n' que aumenta si el múltiplo de la times se alcanza la variable, lo que hace que la función continúe con la iteración, pero emitiendo (consulte la penúltima línea) desde la siguiente matriz (lists[n]). Finalmente, una verificación para ver cuántas matrices quedan determinará si hemos terminado. Si lo hace, escriba la oración por última vez, ejecute la devolución de llamada opcional y devuelva falso. De esta forma, la función aceptará todo el arreglo, y no solo el subarreglo (combo en contraposición a combo[0]):

//Generate from array 'lists', simulating a 'slot machine
function Generate(lists, n, i, callbackFnk) {
    if (!(i >= 0)) { i= 0; }
    setTimeout((function(msg){
        i++;
        return function(){
            if (i % times != 0){
                //We haven't reached a multiple of the times variable yet, keep going.
                Generate(lists, n, i, callbackFnk);
            } else if (i % times === 0 && i != 0 && n < (lists.length-1)) {
                //Multiple reached, increase n
                n++;
                Generate(lists, n, i, callbackFnk);
            } else if (n == (lists.length-1)) {
                //we are done as there are no more arrays to go over
                showMessage(msg, i);
                if (callbackFnk) callbackFnk.call(this, i);
                return false;
            }
            showMessage(msg, i);
        }
    })(
        //output using the given n value
        lists[n][Math.floor(Math.random() * lists[n].length)]
    ), speed);
}

Vea el violín de trabajo aquí: http://jsfiddle.net/c_kick/kuNrA/1/

¡Espero que esto ayude a otros!

Respondido 27 Jul 12, 22:07

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.