我如何创建类似于动画数字计数器工作方式的给定单词的动画字母增量?

How can I create animated letter increments of a given word similar to the way animated number counters work?

我正在创建一个 "animated letter incrementer",它接受任何给定的单词并从 A 开始递增该单词的每个字母。

示例:

Word = Dog

D - Increments from A to D [A, B, C, D]
O - Increments from A to O [A, B, C, D, E, F, G, H, I, J, K, L, M, N, O]
G - Increments from A to G [A, B, C, D, E, F, G]

我想要实现的效果与此类似 jQuery animated number counter,只是我将递增字母而不是计算数字。另外,单词的每个字母应该独立递增,但它们应该同时到达目的地字母。

JS:

var wordToIncrement = 'DOG';
var alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ '.split('');

for (var i = 0, len = wordToIncrement.length; i < len; i++) {

    var letterToIncrementTo = wordToIncrement[i];

    var arrayLength = alphabet.length;
    for (var z = 0; z < arrayLength; z++) {

        var alphabetLetter = alphabet[z];

        if (alphabetLetter == letterToIncrementTo) {

            console.log('MATCH FOUND!');
            console.log('Word Letter: ' + letterToIncrementTo);
            console.log('Alphabet Letter: ' + alphabetLetter);

            alphabetPositionValue = z;
            console.log('VALUE: ' + alphabetPositionValue);

            function incrementToLetter(letterToIncrementTo,alphabetPositionValue) {

                // This is where I'm stuck

                var div = document.getElementById('#word_block');
                div.innerHTML = div.innerHTML + 'Extra stuff';


            }

        }

    }

}

HTML:

<div id="work_block"></div>

我如何完成上面的代码来实现与动画数字计数器示例类似的功能并递增单词的每个字母?我正在寻找基于 javascript 的解决方案。

我会构建一个字母对象来维护字母和时间。通过这种方式,您可以在对象上提供简单的更新功能,并且对象本身将确保它生成正确的当前字母。

例如:

function Letter(table, letter, duration) {
  this.table = table;                          // lookup-table
  this.letter = letter;                        // target letter
  this.current = 0;                            // index in table
  this.delay = duration / tbl.indexOf(letter); // ms
  this.time = Date.now();                      // current (start) time
  this.done = false;                           // status
}

然后是一个常见的原型update()方法:

Letter.prototype.update = function() {
  if (this.done) return;                       // if done, do no more
  var time = Date.now();                       // get current time
  if (time - this.time >= this.delay) {        // exceeded delay?
    this.time = time;                          // store current time
    if (this.letter === this.table[this.current] || 
        this.current === this.table.length) {  // target reached? unknown letter
      this.done = true;                        // we're done
    }
    else {
      this.current++;                          // next in table
    }
  }
};

然后我们可以从字符串中生成对象:

var letters = [];
word.toUpperCase().split("").forEach(function(l) {
  letters.push(new Letter(tbl, l, 2500));  // 2.5s duration
});

然后制作动画:

(function loop() {
   var txt = "", isDone = true;
   letters.forEach(function(l) {
     l.update();
     if (!l.done) isDone = false;
     txt += l.table[l.current];
   });

   // output txt
   if (!isDone) requestAnimationFrame(loop);
   else { /* done */ }
})();

演示

function Letter(table, letter, duration) {
  this.table = table;
  this.letter = letter;
  this.current = 0;
  this.delay = duration / tbl.indexOf(letter);   // ms
  this.time = Date.now();
  this.done = false;
}
Letter.prototype.update = function() {
  if (this.done) return;
  var time = Date.now();
  if (time - this.time >= this.delay) {
    this.time = time;
    if (this.letter === this.table[this.current] || 
        this.current === this.table.length) {
      this.done = true;
    }
    else {
      this.current++;
    }
  }
};

var word = "hello there";
var tbl = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var letters = [];
word.toUpperCase().split("").forEach(function(l) {
  letters.push(new Letter(tbl, l, 2500))
});

(function loop() {
  var txt = "", isDone = true;
  letters.forEach(function(l) {
    l.update();
    if (!l.done) isDone = false;
    txt += l.table[l.current];
  });

  // output txt
  d.innerHTML = txt;
  
  if (!isDone) requestAnimationFrame(loop);
  else { /* done */ }
})();
#d {font:bold 32px monospace}
<div id=d></div>

其他

如果延迟低于 16.7 毫秒,它可能不会增加足够快。它可以通过将当前相对时间除以持续时间来解决。将此归一化值与 table 中目标字母的索引相乘得到当前值,只需将结果四舍五入为整数值即可。

您可以提供不同的table来获得randomness/variation。