D3.js tips - タイプライターのようにテキストを1文字ずつ表示させる方法

phi phi on D3.js

オレの Advent Calendar 2015 - Adventar の 3 日目です.

First

D3.js を使えば, タイプライターのような一文字ずつ表示といった表現がカンタンにできます.

今回はサンプルを交えてその方法を紹介したいと思います.

Runstant

デモです. 一文字ずつ表示されるのが分かるかと思います. 画面をタッチするとテキストが変わります.

Code

html

<!doctype html>

<html>  
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />

    <title>${title}</title>
    <meta name="description" content="${description}" />

    <script src='https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.js'></script>

    <style>${style}</style>
    <script>${script}</script>
  </head>
  <body>
    <h1></h1>
  </body>
</html>  

javascript

window.onload = function() {  
  typing('Hello, world!');

  d3.select('body').on('mousedown', function() {
    typing('こんにちは, 世界!');
  })
  ;
};

var typing = function(word) {  
  var header =  d3.select('body').select('h1');
  var span = header
    .selectAll('span')
    .data(word)
  // enter
  span
    .enter()
    .append('span')
    .style({
      opacity: 0.0,
      color: function(d, i) {
        var angle = (360/word.length)*i;
        return 'hsl(' + angle + ',80%, 60%)';
      }
    })
    ;
  // eixt
  span
    .exit()
    .remove()
    ;
  // update
  span
    .text('')
    .transition()
    .text(function(d) { return d; })
    .delay(function(d, i) { return i*100; })
    .style({
      opacity: 1.0,
    })
    ;
};

Tips

transition でアニメーション

transition 実行後に設定したプロパティは
アニメーションしてくれます.

  span
    .style('color', 'blue') // 一瞬で変わる
    .transition()
    .style('color', 'red')  // アニメーションしながら変わる
    ;

opacity と delay で遅延表示

enter 時に opacity を 0 にしておき,

    .style({
      opacity: 0.0,

update 時に delay に関数を指定し, index に応じた時間だけ
待つように設定します.

    .transition()
    .text(function(d) { return d; })
    .delay(function(d, i) { return i*100; })
    .style({
      opacity: 1.0,
    })

こうすることで先頭から1文字ずつフェードイン表示されるようになります.

Last

D3.js 便利ですね♪
よくグラフまわりがフューチャーされがちですが, 普通に jQuery の代わりとして dom 操作するのにも優れいます!!

今後も, 色々な可能性をさぐっていきたいと思います♪