Animando caracteres con Javascript

PENTIUM4HT

Capo
Se incorporó
26 Junio 2021
Mensajes
106
Buenas, esto lo implemente en mi sitio para intercambiar el texto entre 2 inputs y hacerlo letra por letra (puede ser cualquier elemento), es un sitio que aun estoy desarrollando donde utilizo React. La logica la pueden ocupar para cualquier cosa ya que basicamente se toma un elemento desde el DOM y la animacion se realiza ejecutando la funcion exe() multples veces junto con un timer.

El codigo:
JavaScript:
function swapTxt() {
    const input1 = document.querySelector('.input-1');
    const input2 = document.querySelector('.input-2');
    let t1 = input1.value.split('');
    let t2 = input2.value.split('');
    const lengthDiff = t1.length > t2.length ? t1.length : t2.length;
    let i = 0;
    function exe() {
      [t1[i], t2[i]] = [t2[i], t1[i]];
      input1.value = t1.join('');
      input2.value = t2.join('');
      i++;
      if (i === lengthDiff) {
        clearInterval(interval);
      }
    }
    const interval = setInterval(exe, 15);
  }

Con estas lineas tomo los elementos desde el DOM:
JavaScript:
const input1 = document.querySelector('.input-1');
const input2 = document.querySelector('.input-2');

Aqui creo 2 variables que basicamente toman el texto que esta en los inputs y lo transforman en un array, por ejemplo el string "hola" quedaria como ["h", "o", "l", "a"].
Código:
let t1 = input1.value.split('');
let t2 = input2.value.split('');

En esta linea lo que hago es asignarle un digito a lengthDiff, este digito es el largo del input que tenga mas caracteres. Si no hacen esto, al intercambiar el texto la animacion podria terminar cuando el input con menos texto termine de traspasar su texto:
Código:
const lengthDiff = t1.length > t2.length ? t1.length : t2.length;

Cuento cuantas veces se ha ejecutado la funcion exe():
JavaScript:
let i = 0;

Aqui comienza el intercambio, utilizo ES6 para intercambiar el texto entre los 2 input. Ojo con este paso ya que al terminar de procesar esta linea, javascrip solo ha intercambiado una sola letra (la primera de cada input). Recuerden que t1 y t2 son arrays de strings:
JavaScript:
function exe() {
    [t1[i], t2[i]] = [t2[i], t1[i]];

Aqui grafico el cambio y le asigno el resultado de ambos arrays a ambos inputs en el DOM con la funcion join que transforma un array en un string:
Código:
input1.value = t1.join('');
input2.value = t2.join('');

Las siguientes lineas son basicamente para chequear si detener el timer o no. La variable i++ me indica lo siguiente: si tiene el mismo largo que el input con mas caracteres, detiene el intervalo y termina la ejecucion de exe(). Como veran la logica de esto es ejecutar multiples veces la funcion exe() y dar la impresion de que hay una animacion, osea la funcion exe() la pensé para realizar 1 cambio a la vez o en cada iteracion:
JavaScript:
i++;
if (i === lengthDiff) {
    clearInterval(interval);
}

Ultimo acto, inicio la ejecucion del intervalo asignandole el intervalo a la variable (para despues detener el intervalo con el if):
Código:
const interval = setInterval(exe, 15);

La velocidad de la animacion al final es la velocidad con la que ejecutan la funcion exe, osea 15ms, si quieren una animacion mas lenta lo pueden hacer incrementando este numero.

Y eso seria todo, es super simple. Si tienen una forma mas facil de hacerlo dejen un comentario me encantaria saber ya que con un timer se bloquea el callstack(igual ni se nota).

Saludos
 
Subir