-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimer.js
135 lines (119 loc) · 3.77 KB
/
timer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
(function (root, factory) {
'use strict'
if (typeof define === 'function' && define.amd) define([], factory)
else if (typeof exports === 'object') module.exports = factory()
else root.Timer = factory()
}(this, function () {
'use strict'
var defaultOptions = {
tick : 1,
onstart : null,
ontick : null,
onpause : null,
onstop : null,
onend : null
}
var Timer = function (options) {
if (!(this instanceof Timer)) return new Timer(options)
this._ = {
id : +new Date,
options : {},
duration : 0,
status : 'initialized',
start : 0,
measures : []
}
for (var prop in defaultOptions) this._.options[prop] = defaultOptions[prop]
this.options(options)
}
Timer.prototype.start = function (duration) {
if (!+duration && !this._.duration) return this
duration && (duration *= 1000)
if (this._.timeout && this._.status === 'started') return this
this._.duration = duration || this._.duration
this._.timeout = setTimeout(end.bind(this), this._.duration)
if (typeof this._.options.ontick === 'function')
this._.interval = setInterval(function () {
trigger.call(this, 'ontick', this.getDuration())
}.bind(this), +this._.options.tick * 1000)
this._.start = +new Date
this._.status = 'started'
trigger.call(this, 'onstart', this.getDuration())
return this
}
Timer.prototype.pause = function () {
if (this._.status !== 'started') return this
this._.duration -= (+new Date - this._.start)
clear.call(this, false)
this._.status = 'paused'
trigger.call(this, 'onpause')
return this
}
Timer.prototype.stop = function () {
if (!/started|paused/.test(this._.status)) return this
clear.call(this, true)
this._.status = 'stopped'
trigger.call(this, 'onstop')
return this
}
Timer.prototype.getDuration = function () {
if (this._.status === 'started')
return this._.duration - (+new Date - this._.start)
if (this._.status === 'paused') return this._.duration
return 0
}
Timer.prototype.getStatus = function () {
return this._.status
}
Timer.prototype.options = function (option, value) {
if (option && value) this._.options[option] = value
if (!value && typeof option === 'object')
for (var prop in option)
if (this._.options.hasOwnProperty(prop))
this._.options[prop] = option[prop]
return this
}
Timer.prototype.on = function (option, value) {
if (typeof option !== 'string' || typeof value !== 'function') return this
if (!(/^on/).test(option))
option = 'on' + option
if (this._.options.hasOwnProperty(option))
this._.options[option] = value
return this
}
Timer.prototype.off = function (option) {
if (typeof option !== 'string') return this
option = option.toLowerCase()
if (option === 'all') {
this._.options = defaultOptions
return this
}
if (!(/^on/).test(option)) option = 'on' + option
if (this._.options.hasOwnProperty(option))
this._.options[option] = defaultOptions[option]
return this
}
Timer.prototype.measureStart = function (label) {
this._.measures[label || ''] = +new Date
return this
}
Timer.prototype.measureStop = function (label) {
return +new Date - this._.measures[label || '']
}
function end () {
clear.call(this)
this._.status = 'stopped'
trigger.call(this, 'onend')
}
function trigger (event) {
var callback = this._.options[event],
args = [].slice.call(arguments, 1)
typeof callback === 'function' && callback.apply(this, args)
}
function clear (clearDuration) {
clearTimeout(this._.timeout)
clearInterval(this._.interval)
if (clearDuration === true) this._.duration = 0
}
return Timer
}))