Estoy intentando crear una animación personalizada que tomará el valor inicial deseado de un texto y lo animará para que parezca que se está escribiendo.

Como un campo de búsqueda: "Empiece aquí ..."

function typeAnimation(val){
  let valArray = val.split('');

  console.log("valArray", valArray);
  console.log("val", val);


  let newChar = "";
  var i = 0;
  function display() {
    if(i < valArray.length) {
      console.log("valArray[i]", valArray[i]);

      newChar += valArray[i];
      i++;

      setTimeout(display, 100);

      console.log("newChar", newChar);
      return newChar;
    }
  };

  display()
}

initialSearchFormValues.search_term = typeAnimation(initialSearchFormValues.search_term);

Esto es lo que hice, pero el texto no se actualiza y el valor devuelto aparece vacío en el campo

Último ejemplo http://jsfiddle.net/ojnfL1hs/2/

Necesito que sea algo así como una preadolescente

var self = this;
var newText = "hellob"//d.value;
var textLength = newText.length;
return function(t) {
    self.textContent = newText.slice(0, Math.round(t * textLength));
};
0
The Old County 24 sep. 2020 a las 15:51

2 respuestas

La mejor respuesta

Esto funcionó para mí - estas dos funciones.

  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

  async typeAnimation(text, timing, callback) {
    let concatStr = "";
    for (const char of text) {
        concatStr += char;
        await this.sleep(timing);
        callback(concatStr);
    }  
  }

Y luego en el constructor react

  constructor(props, context) {
    super(props, context);
    this.state = {open: false, initial_search_term: {"search_term": "Start typing..."}};

    var self = this;
    this.typeAnimation(this.state.initial_search_term.search_term, 100, function(msg){
      self.setState({
        initial_search_term: {"search_term": msg}
      });
    });
  }
0
The Old County 25 sep. 2020 a las 00:10

Aquí hay una versión que devuelve un iterable asincrónico. Esto luego se puede consumir en una función asíncrona con for await (... of ...).

const sleep = timing =>
    new Promise(resolve => setTimeout(resolve, timing))

const typeAnimation = (text, timing) => ({
    async *[Symbol.asyncIterator]() {
        let concatStr = ''

        yield concatStr

        for (const char of text) {
            await sleep(timing)

            yield (concatStr = concatStr + char)
        }

        await sleep(timing)
    }
})

const animation = typeAnimation('Start typing...', 100)

;(async () => {
    // consumed like this
    for await (const str of animation) {
        document.querySelector('input').value = str
        // in React, you'd use something like
        // setStr(str) or setState({ str }) here
    }
})()
<input>
0
Lionel Rowe 25 sep. 2020 a las 14:03