Skip to content

Instantly share code, notes, and snippets.

@miya2000
Created July 11, 2010 22:28
Show Gist options
  • Select an option

  • Save miya2000/471900 to your computer and use it in GitHub Desktop.

Select an option

Save miya2000/471900 to your computer and use it in GitHub Desktop.
/**
* Tapper
* tap, step, tap, roll, roll, roll ...
* @see http://d.hatena.ne.jp/brazil/20071030/1193711816
*/
function Tapper() {
this.rolling = false;
this.unbounded = false;
this.tapped = 0;
this.lastTapped = 0;
this.interval = 0;
this.previous = null;
this.defalutGap = 60;
this.minInterval = 16;
this.maxInterval = 3000;
}
(function(member) { member.apply(Tapper.prototype); })(function() {
// method
this. tap = tap; // tick down a interval between tap and tap. (ex: tapper.tap(e.keyCode); //when keydown.)
this.step = step; // call between taps to separate taps. (ex: tapper.step(); //when keyup. )
this. gap = gap; // returns adjusted interval.
this.roll = roll; // repeat given function at a regular interval which returned the gap method.
this.stop = stop; // stop rolling.
// impl
function tap(value) {
if (!this.unbounded) {
this.unbounded = true;
var now = new Date().getTime();
if (this.previous == value) {
this.tapped++;
if (this.tapped >= 2) {
this.interval = now - this.lastTapped;
}
}
else {
this.previous = value;
this.interval = -1;
this.tapped = 1;
}
this.lastTapped = now;
}
else {
if (this.previous != value) { // left tap, right tap (no step).
this.stop();
}
}
}
function step() {
this.stop();
this.unbounded = false;
}
function gap(interval) {
return (interval < 1000) ? Math.max(16, Math.floor(interval + ((interval - 500) * 0.2))) : (interval + 100);
}
function roll(func) {
this.stop();
this.rolling = true;
var ivl = this.interval;
var fromLastTapped = new Date().getTime() - this.lastTapped;
var gap, firstRoll;
if (ivl <= 0 || ivl <= this.minInterval || ivl >= this.maxInterval) {
gap = this.defalutGap;
firstRoll = (fromLastTapped >= gap) ? 0 : (gap - fromLastTapped);
}
else {
gap = this.gap(ivl);
firstRoll = (fromLastTapped >= ivl) ? 0 : (ivl - fromLastTapped);
}
var self = this;
this.rollingTid = setInterval(function() {
func();
if (self.rollingTid) {
clearInterval(self.rollingTid);
self.rollingTid = setInterval(func, gap);
}
}, firstRoll);
this.interval = -1;
this.tapped = 0;
}
function stop() {
this.rolling = false;
if (this.rollingTid) {
clearInterval(this.rollingTid);
this.rollingTid = null;
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment