iPad, iPhone, iPod を振ると、コールバック関数を呼び出す

加速度センサーを利用して、ストップウオッチを作ることにした。
振り戻すと発火!


追記
iPod を刀のように振るときは、遠心力で上方向にもセンサーで感知すると誤動作がすくなさそうな気がする。

(function () {
  
  function SwingBack (cbFunc, swingStrength, backStrength, reactionTime) {
    this.cbFunc        = cbFunc;
    this.swingStrength = swingStrength;
    this.backStrength  = backStrength;
    this.reactionTime  = reactionTime;
    this.state         = 0;
    this.time          = null;
    this.direction     = null;
    this.disabled      = false;
  }
  
  
  function handler (event) {
    var value = event.rotationRate.gamma;
    var time = event.timeStamp;
    var direction = (value < 0) ? -1: 1;
    var strength = Math.abs (value);
    
    if (this.disabled)
      return false;
 
    switch (this.state) {
    case 1: // swing back ?
      if (this.reactionTime > (time - this.time)) {
        if (this.direction === direction) {
          if (this.backStrength < strength) {
            this.state = 0;
            this.cbFunc (time);
            this.time = null;
            this.direction = null;
          }
        }
      }
      else {
        this.state = 0;
      }
      break;
       
    case 0: default : // none
      if (this.swingStrength < strength) { // swing on
        this.state     = 1;
        this.direction = -direction;
        this.time      = event.timeStamp;
      }
      break;
    }
  }


  function create (cbFunc, swingStrength, backStrength, reactionTime) {
    var swingBack;
    
    if (1 > arguments.length)
      throw new Error ('Arguments are invalid.');
    
    if (! swingStrength)
      swingStrength = 400;
    
    if (! backStrength)
      backStrength = swingStrength / 10;
    
    if (! reactionTime)
      reactionTime = 200;//ms
    
    swingBack = new SwingBack (cbFunc, swingStrength, backStrength, reactionTime);
    window.addEventListener ('devicemotion', swingBack, false);
    
    return swingBack;
  }


  SwingBack.prototype.handleEvent = handler;
  
  SwingBack.create     = create;
  
  this.SwingBack       = SwingBack;
  
}) ();

SwingBack.create (function () { alert('ok'); });