Text Scramble Effect

サンプル

ソースコード

// ——————————————————————————————————————————————————
// TextScramble
// ——————————————————————————————————————————————————
 
class TextScramble {
  constructor(el) {
    this.el = el;
    this.chars = "!<>-_\\/[]{}—=+*^?#________";
    this.update = this.update.bind(this);
  }
  setText(newText) {
    const oldText = this.el.innerText;
    const length = Math.max(oldText.length, newText.length);
    const promise = new Promise(resolve => (this.resolve = resolve));
    this.queue = [];
    for (let i = 0; i < length; i++) {
      const from = oldText[i] || "";
      const to = newText[i] || "";
      const start = Math.floor(Math.random() * 40);
      const end = start + Math.floor(Math.random() * 40);
      this.queue.push({ from, to, start, end });
    }
    cancelAnimationFrame(this.frameRequest);
    this.frame = 0;
    this.update();
    return promise;
  }
  update() {
    let output = "";
    let complete = 0;
    for (let i = 0, n = this.queue.length; i < n; i++) {
      let { from, to, start, end, char } = this.queue[i];
      if (this.frame >= end) {
        complete++;
        output += to;
      } else if (this.frame >= start) {
        if (!char || Math.random() < 0.28) {
          char = this.randomChar();
          this.queue[i].char = char;
        }
        output += `<span class="tse_dud">${char}</span>`;
      } else {
        output += from;
      }
    }
    this.el.innerHTML = output;
    if (complete === this.queue.length) {
      this.resolve();
    } else {
      this.frameRequest = requestAnimationFrame(this.update);
      this.frame++;
    }
  }
  randomChar() {
    return this.chars[Math.floor(Math.random() * this.chars.length)];
  }
}
 
// ——————————————————————————————————————————————————
// Example
// ——————————————————————————————————————————————————
 
const phrases = [{$text}];
 
const el = document.querySelector(".tse_text");
const fx = new TextScramble(el);
 
let counter = 0;
const next = () => {
  fx.setText(phrases[counter]).then(() => {
    setTimeout(next, 800);
  });
  counter = (counter + 1) % phrases.length;
};
 
next();
@import url(//fonts.googleapis.com/css?family=Roboto+Mono:100);
 
.tse_text {
    color: #333;
    text-align: left;
    font-weight: normal;
    font-size: 16px;
    font-family: 'Roboto Mono', monospace;
}
.tse_dud {
    color: #999;
}

実装

[[include component:text-scramble-effect
|text-color=#333
|dud-color=#999
|font-weight=bold
|font-size=24px
|text-align=center
|text="Hacker Space","./Research"
]]

特に指定がない限り、このサイトのすべてのコンテンツはクリエイティブ・コモンズ 表示 - 継承3.0ライセンス の元で利用可能です。