1

I'm making an application with Electon js that needs to validate a determinist finite automaton and then show the process with a diagram and status.

In order to show the changes from one status to another in the diagram I have 5 images, one with each status highlighted and am using this function:

function animarDiagrama(){
            document.getElementById("blanco").style.display = "none";
            document.getElementById("q1").style.display = "block";
            var cadenaLength = cadena.length;
            var estado = "q1";

            for (var i = 0; i < cadenaLength; i++){
                var j = i + 1;
                        if (estado == 'q1'){
                            if(cadena.substring(i,j) == 'a'){
                                estado = 'q2';
                                document.getElementById("blanco").style.display = "none";
                                document.getElementById("q1").style.display = "none";
                                document.getElementById("q2").style.display = "block";
                                document.getElementById("q3").style.display = "none";
                                document.getElementById("q4").style.display = "none";
                            }else if (cadena.substring(i,j) == 'b'){
                                estado = 'q3';
                                document.getElementById("blanco").style.display = "none";
                                document.getElementById("q1").style.display = "none";
                                document.getElementById("q2").style.display = "none";
                                document.getElementById("q3").style.display = "block";
                                document.getElementById("q4").style.display = "none";
                            }
                        }else if (estado == 'q2'){
                            if(cadena.substring(i,j) == 'a'){
                                estado = 'q4';
                                document.getElementById("blanco").style.display = "none";
                                document.getElementById("q1").style.display = "none";
                                document.getElementById("q2").style.display = "none";
                                document.getElementById("q3").style.display = "none";
                                document.getElementById("q4").style.display = "block";
                            }else if (cadena.substring(i,j) == 'b'){
                                estado = 'q3';
                                document.getElementById("blanco").style.display = "none";
                                document.getElementById("q1").style.display = "none";
                                document.getElementById("q2").style.display = "none";
                                document.getElementById("q3").style.display = "block";
                                document.getElementById("q4").style.display = "none";
                            }
                        }else if (estado == 'q3'){
                            if(cadena.substring(i,j) == 'a'){
                                estado = 'q2';
                                document.getElementById("blanco").style.display = "none";
                                document.getElementById("q1").style.display = "none";
                                document.getElementById("q2").style.display = "block";
                                document.getElementById("q3").style.display = "none";
                                document.getElementById("q4").style.display = "none";
                            }else if (cadena.substring(i,j) == 'b'){
                                estado = 'q4';
                                document.getElementById("blanco").style.display = "none";
                                document.getElementById("q1").style.display = "none";
                                document.getElementById("q2").style.display = "none";
                                document.getElementById("q3").style.display = "none";
                                document.getElementById("q4").style.display = "block";
                            }
                        }else if (estado == 'q4'){
                            if(cadena.substring(i,j) == 'a'){
                                estado = 'q4';
                                document.getElementById("blanco").style.display = "none";
                                document.getElementById("q1").style.display = "none";
                                document.getElementById("q2").style.display = "none";
                                document.getElementById("q3").style.display = "none";
                                document.getElementById("q4").style.display = "block";
                            }else if (cadena.substring(i,j) == 'b'){
                                estado = 'q4';
                                document.getElementById("blanco").style.display = "none";
                                document.getElementById("q1").style.display = "none";
                                document.getElementById("q2").style.display = "none";
                                document.getElementById("q3").style.display = "none";
                                document.getElementById("q4").style.display = "block";
                            }
                        }

            }
        }

The function is called via a button but the problem is that when it is called I can only see the last status as it is made immediatly.

Is there any way to make the images change slowly?

Here's the HTML:

<p>La cadena: </p>  <ul></ul>   <p> es válida. </p>
<p>Diagrama:</p>
<button type="submit" onclick="animarDiagrama();">Ver movimiento en diagrama</button>
<!-- Contenedor del diagrama -->
<img src="images/blanco.png" alt="Diagrama en Blanco" id="blanco" style="display: block;">
<img src="images/q1.png" alt="Estado Q1" id="q1" style="display: none;">
<img src="images/q2.png" alt="Estado Q2" id="q2" style="display: none;">
<img src="images/q3.png" alt="Estado Q3" id="q3" style="display: none;">
<img src="images/q4.png" alt="Estado Q4" id="q4" style="display: none;">

Edit: this is the function that validates the data entered by user in my main window:

function validarCadena(){
        //Obtener cadena
        cadenaValue = document.getElementById("cadena").value;
        //Guardar cadena como String
        cadenaString = String(cadenaValue);
        //Obtener longitud de la cadena para ciclo
        cadenaLength = cadenaString.length;

        valid = false; //Var para validez de la cadena
        //If cadena vacia
        if(cadenaLength == 0){
            valid = true;
        }else{
            //If cadena no vacia
            for (var i = 0; i < cadenaLength; i++){
                //Variables para metodo substring(j,k) <- obtiene un
                //substring desde j (incluido) hasta k (no incluido)
                var j = i+1;
                var k = j+1;
                //if cadena de un solo caracter
                if (cadenaLength == 1){
                    //a o b son validas, otra cosa no
                    if (cadenaString.substring(0,1) == 'a' || 
                    cadenaString.substring(0,1) == 'b'){
                        valid = true;
                    }else {
                        valid = false;
                    }
                }else {
                    //cadenas de mas de un caracter
                    if(cadenaString.substring(i,j) == 'a'){
                        if(cadenaString.substring(j,k) == 'b' || 
                        cadenaString.substring(j,k) == ''){
                        valid = true;
                        }else {
                        valid = false;
                        break;
                        }
                    }else if (cadenaString.substring(i,j) == 'b'){
                        if(cadenaString.substring(j,k) == 'a' ||
                        cadenaString.substring(j,k) == ''){
                            valid = true;
                        } else {
                            valid = false;
                            break;
                        }
                    }else {
                        valid = false;
                    }
                }
            }
        }
        //Enviar cadena a main.js
        const item = document.querySelector('#cadena').value;
        ipcRenderer.send('item:add', item, valid);
    }

And here's how that is handled:

ipcMain.on('item:add', function(e, item, item2){
cadena = item;
valid = item2;
if(valid == true){
    createValidWindow();
}else if (valid == false){
    createInvalidWindow();
}
enviarCadena(cadena);

});

wason
  • 13
  • 3
  • 1
    Just attach a transition to the image, so `display:none` to `display:block` you can have it fade in / out or have it delay: https://stackoverflow.com/a/6943704/11700321 – EGC Nov 01 '19 at 00:55
  • @EGC so I would somehow have to add a delay inside the style parameter of the img tags? – wason Nov 01 '19 at 01:11
  • @MisterJojo that value is passed from my main.js – wason Nov 01 '19 at 02:24
  • @MisterJojo Sorry, it can be any number, it's the length of the string introduced by the user to be tested. Should I post all my code? It's my first time posting here – wason Nov 01 '19 at 02:35
  • Okay, *cadena* means string in spanish. I have an html with an input type text. This value is sent to my main.js via electron's ipcRenderer. Next, a new window where the diagram will be shown is created and this *cadena* value is sent to the html we are currently working on. Here i use cadena.length and get the length of the string. – wason Nov 01 '19 at 02:47
  • oh i got it now, sorry. i have a function that only accepts 'abababab...' or 'babababa...' it can be any length but no 'aa' nor 'bb' together – wason Nov 01 '19 at 02:57
  • @MisterJojo I edited the question and added some more code. Is it useful? – wason Nov 01 '19 at 03:06

1 Answers1

1

So I think requestAnimationFrame is your solution
see : https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame

you can also use a delay with the code look like this ( not tested ) I just made it more readable

<p>La cadena: </p>  <ul></ul>   <p> es válida. </p>
<p>Diagrama:</p>
<button id="Bt-Diag-Anim">Ver movimiento en diagrama</button>
<!-- Contenedor del diagrama -->
<img src="images/blanco.png" alt="Diagrama en Blanco" id="blanco" style="display: block;">
<img src="images/q1.png" alt="Estado Q1" id="q1" style="display: none;">
<img src="images/q2.png" alt="Estado Q2" id="q2" style="display: none;">
<img src="images/q3.png" alt="Estado Q3" id="q3" style="display: none;">
<img src="images/q4.png" alt="Estado Q4" id="q4" style="display: none;">
const status= 
        { q1: { a: 'q2', b: 'q3'} 
        , q2: { a: 'q4', b: 'q3'} 
        , q3: { a: 'q2', b: 'q4'} 
        , q4: { a: 'q4', b: 'q4'}
        }
    , E_Img= 
        { Bl : document.getElementById('blanco')
        , q1 : document.getElementById('q1')
        , q2 : document.getElementById('q2')
        , q3 : document.getElementById('q3')
        , q4 : document.getElementById('q4')
        }

document.getElementById('Bt-Diag-Anim').onclick=_=>
  {
  E_Img.Bl.style.display = 'none'
  E_Img.q1.style.display = 'block'

  let estado = 'q1'
    , p      = 0
    , pMax   = cadena.length

  function anim() 
    {
    estado = status[estado][cadena.charAt(p)]
    for (zImg in E_Img )
      {
      E_Img[zImg].style.display = (zImg === estado) ? 'block' : 'none'
      }
    if(++p<pMax)
      { requestAnimationFrame(anim) }
    }
  requestAnimationFrame(anim) 
  }

(WhiteSmith style)

Bonus:

function validarCadena()
  {
  let cadenaValue  = document.getElementById("cadena").value  // Obtener cadena
    , cadenaString = String(cadenaValue)                     // Guardar cadena como String
    , valid        = true                                   // Var para validez de la cadena

  for(let p=0, pMax=cadenaString.length; p<pMax;p++)
    {
    if (!/^[a-b]/.test(cadenaString.charAt(p))
    || cadenaString.charAt(p)===cadenaString.charAt(p+1) )
      {
      valid = false
      break
      }
    }

  //Enviar cadena a main.js
  ipcRenderer.send('item:add', cadenaValue, valid);
  }
ipcMain.on('item:add', function(e, item, valid)
  {
  cadena = item;
  if(valid)
    {
    createValidWindow();
    }
  else
    {
    createInvalidWindow();
    }
  enviarCadena(cadena);
  });
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40