119 lines
2.8 KiB
JavaScript
119 lines
2.8 KiB
JavaScript
|
var SLIDE_PUZZLE = window.SLIDE_PUZZLE || {};
|
||
|
|
||
|
SLIDE_PUZZLE.Stopwatch = function(tickMillis) {
|
||
|
var self = this;
|
||
|
|
||
|
this._tickMillis = tickMillis;
|
||
|
this._startTime = null;
|
||
|
this._intervalID = null;
|
||
|
this._priorElapsed = 0;
|
||
|
this._currentElapsed = 0;
|
||
|
|
||
|
this._listeners = [];
|
||
|
|
||
|
this.__defineGetter__("isRunning", function() {
|
||
|
return self._intervalID !== null;
|
||
|
});
|
||
|
|
||
|
this.__defineGetter__("elapsedMillis", function() {
|
||
|
return self._priorElapsed + self._currentElapsed;
|
||
|
});
|
||
|
|
||
|
function divideInt(a, b) {
|
||
|
return Math.floor(a/b);
|
||
|
}
|
||
|
|
||
|
this.__defineGetter__("elapsedString", function() {
|
||
|
var totalMillis = self._priorElapsed + self._currentElapsed;
|
||
|
|
||
|
var seconds = divideInt(totalMillis, 1000) % 60;
|
||
|
var minutes = divideInt(totalMillis, 60000) % 60;
|
||
|
var hours = divideInt(totalMillis, 3600000);
|
||
|
|
||
|
var showHours = hours > 0;
|
||
|
var showMinutes = minutes > 0 || showHours;
|
||
|
var fixMinutes = showHours;
|
||
|
var fixSeconds = showMinutes;
|
||
|
|
||
|
var hoursString;
|
||
|
if (showHours) {
|
||
|
hoursString = hours + ':';
|
||
|
} else {
|
||
|
hoursString = '';
|
||
|
}
|
||
|
|
||
|
var minutesString;
|
||
|
if (showMinutes) {
|
||
|
if (fixMinutes && minutes < 10) {
|
||
|
minutesString = '0' + minutes + ':';
|
||
|
} else {
|
||
|
minutesString = minutes + ':';
|
||
|
}
|
||
|
} else {
|
||
|
minutesString = '';
|
||
|
}
|
||
|
|
||
|
var secondsString;
|
||
|
if (fixSeconds && seconds < 10) {
|
||
|
secondsString = '0' + seconds;
|
||
|
} else {
|
||
|
secondsString = seconds.toString();
|
||
|
}
|
||
|
|
||
|
return hoursString + minutesString + secondsString;
|
||
|
});
|
||
|
};
|
||
|
|
||
|
SLIDE_PUZZLE.Stopwatch.prototype.start = function() {
|
||
|
if (!this.isRunning) {
|
||
|
var self = this;
|
||
|
|
||
|
function tick() {
|
||
|
self._currentElapsed = window.performance.now() - self._startTime;
|
||
|
self._dispatchTickEvent();
|
||
|
}
|
||
|
|
||
|
this._startTime = window.performance.now();
|
||
|
this._intervalID = window.setInterval(tick, this._tickMillis);
|
||
|
} else {
|
||
|
throw new Error("can't start a started stopwatch");
|
||
|
}
|
||
|
};
|
||
|
|
||
|
SLIDE_PUZZLE.Stopwatch.prototype.stop = function() {
|
||
|
if (this.isRunning) {
|
||
|
window.clearInterval(this._intervalID);
|
||
|
this._intervalID = null;
|
||
|
this._startTime = null;
|
||
|
|
||
|
this._priorElapsed += this._currentElapsed;
|
||
|
this._currentElapsed = 0;
|
||
|
} else {
|
||
|
throw new Error("can't stop a stopped stopwatch");
|
||
|
}
|
||
|
};
|
||
|
|
||
|
SLIDE_PUZZLE.Stopwatch.prototype.reset = function() {
|
||
|
if (!this.isRunning) {
|
||
|
this._priorElapsed = 0;
|
||
|
this._currentElapsed = 0;
|
||
|
this._dispatchTickEvent();
|
||
|
} else {
|
||
|
throw new Error("can't reset a started stopwatch");
|
||
|
}
|
||
|
};
|
||
|
|
||
|
SLIDE_PUZZLE.Stopwatch.prototype.addEventListener = function(type, listener) {
|
||
|
if (type === 'tick') {
|
||
|
this._listeners.push(listener);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
SLIDE_PUZZLE.Stopwatch.prototype._dispatchTickEvent = function() {
|
||
|
var event = document.createEvent('CustomEvent');
|
||
|
event.initCustomEvent('tick', false, false, null);
|
||
|
for (var i = 0; i < this._listeners.length; i++) {
|
||
|
this._listeners[i](event);
|
||
|
}
|
||
|
}
|