444 lines
12 KiB
JavaScript
444 lines
12 KiB
JavaScript
/*! FPSMeter 0.3.1 - 9th May 2013 | https://github.com/Darsain/fpsmeter */
|
|
;(function (m, j) {
|
|
function s(a, e) {
|
|
for (var g in e)
|
|
try {
|
|
a.style[g] = e[g]
|
|
} catch (j) {}
|
|
return a
|
|
}
|
|
function H(a) {
|
|
return null == a
|
|
? String(a)
|
|
: 'object' === typeof a || 'function' === typeof a
|
|
? Object.prototype.toString
|
|
.call(a)
|
|
.match(/\s([a-z]+)/i)[1]
|
|
.toLowerCase() || 'object'
|
|
: typeof a
|
|
}
|
|
function R(a, e) {
|
|
if ('array' !== H(e)) return -1
|
|
if (e.indexOf) return e.indexOf(a)
|
|
for (var g = 0, j = e.length; g < j; g++) if (e[g] === a) return g
|
|
return -1
|
|
}
|
|
function I() {
|
|
var a = arguments,
|
|
e
|
|
for (e in a[1])
|
|
if (a[1].hasOwnProperty(e))
|
|
switch (H(a[1][e])) {
|
|
case 'object':
|
|
a[0][e] = I({}, a[0][e], a[1][e])
|
|
break
|
|
case 'array':
|
|
a[0][e] = a[1][e].slice(0)
|
|
break
|
|
default:
|
|
a[0][e] = a[1][e]
|
|
}
|
|
return 2 < a.length
|
|
? I.apply(null, [a[0]].concat(Array.prototype.slice.call(a, 2)))
|
|
: a[0]
|
|
}
|
|
function N(a) {
|
|
a = Math.round(255 * a).toString(16)
|
|
return 1 === a.length ? '0' + a : a
|
|
}
|
|
function S(a, e, g, j) {
|
|
if (a.addEventListener)
|
|
a[j ? 'removeEventListener' : 'addEventListener'](e, g, !1)
|
|
else if (a.attachEvent) a[j ? 'detachEvent' : 'attachEvent']('on' + e, g)
|
|
}
|
|
function D(a, e) {
|
|
function g(a, b, d, c) {
|
|
return y[0 | a][Math.round(Math.min(((b - d) / (c - d)) * J, J))]
|
|
}
|
|
function r() {
|
|
f.legend.fps !== q &&
|
|
((f.legend.fps = q), (f.legend[T] = q ? 'FPS' : 'ms'))
|
|
K = q ? b.fps : b.duration
|
|
f.count[T] = 999 < K ? '999+' : K.toFixed(99 < K ? 0 : d.decimals)
|
|
}
|
|
function m() {
|
|
z = A()
|
|
L < z - d.threshold &&
|
|
((b.fps -= b.fps / Math.max(1, (60 * d.smoothing) / d.interval)),
|
|
(b.duration = 1e3 / b.fps))
|
|
for (c = d.history; c--; )
|
|
(E[c] = 0 === c ? b.fps : E[c - 1]),
|
|
(F[c] = 0 === c ? b.duration : F[c - 1])
|
|
r()
|
|
if (d.heat) {
|
|
if (w.length)
|
|
for (c = w.length; c--; )
|
|
w[c].el.style[h[w[c].name].heatOn] = q
|
|
? g(h[w[c].name].heatmap, b.fps, 0, d.maxFps)
|
|
: g(h[w[c].name].heatmap, b.duration, d.threshold, 0)
|
|
if (f.graph && h.column.heatOn)
|
|
for (c = u.length; c--; )
|
|
u[c].style[h.column.heatOn] = q
|
|
? g(h.column.heatmap, E[c], 0, d.maxFps)
|
|
: g(h.column.heatmap, F[c], d.threshold, 0)
|
|
}
|
|
if (f.graph)
|
|
for (p = 0; p < d.history; p++)
|
|
u[p].style.height =
|
|
(q
|
|
? E[p]
|
|
? Math.round((O / d.maxFps) * Math.min(E[p], d.maxFps))
|
|
: 0
|
|
: F[p]
|
|
? Math.round((O / d.threshold) * Math.min(F[p], d.threshold))
|
|
: 0) + 'px'
|
|
}
|
|
function k() {
|
|
20 > d.interval
|
|
? ((x = M(k)), m())
|
|
: ((x = setTimeout(k, d.interval)), (P = M(m)))
|
|
}
|
|
function G(a) {
|
|
a = a || window.event
|
|
a.preventDefault
|
|
? (a.preventDefault(), a.stopPropagation())
|
|
: ((a.returnValue = !1), (a.cancelBubble = !0))
|
|
b.toggle()
|
|
}
|
|
function U() {
|
|
d.toggleOn && S(f.container, d.toggleOn, G, 1)
|
|
a.removeChild(f.container)
|
|
}
|
|
function V() {
|
|
f.container && U()
|
|
h = D.theme[d.theme]
|
|
y = h.compiledHeatmaps || []
|
|
if (!y.length && h.heatmaps.length) {
|
|
for (p = 0; p < h.heatmaps.length; p++) {
|
|
y[p] = []
|
|
for (c = 0; c <= J; c++) {
|
|
var b = y[p],
|
|
e = c,
|
|
g
|
|
g = (0.33 / J) * c
|
|
var j = h.heatmaps[p].saturation,
|
|
m = h.heatmaps[p].lightness,
|
|
n = void 0,
|
|
k = void 0,
|
|
l = void 0,
|
|
t = (l = void 0),
|
|
v = (n = k = void 0),
|
|
v = void 0,
|
|
l = 0.5 >= m ? m * (1 + j) : m + j - m * j
|
|
0 === l
|
|
? (g = '#000')
|
|
: ((t = 2 * m - l),
|
|
(k = (l - t) / l),
|
|
(g *= 6),
|
|
(n = Math.floor(g)),
|
|
(v = g - n),
|
|
(v *= l * k),
|
|
0 === n || 6 === n
|
|
? ((n = l), (k = t + v), (l = t))
|
|
: 1 === n
|
|
? ((n = l - v), (k = l), (l = t))
|
|
: 2 === n
|
|
? ((n = t), (k = l), (l = t + v))
|
|
: 3 === n
|
|
? ((n = t), (k = l - v))
|
|
: 4 === n
|
|
? ((n = t + v), (k = t))
|
|
: ((n = l), (k = t), (l -= v)),
|
|
(g = '#' + N(n) + N(k) + N(l)))
|
|
b[e] = g
|
|
}
|
|
}
|
|
h.compiledHeatmaps = y
|
|
}
|
|
f.container = s(document.createElement('div'), h.container)
|
|
f.count = f.container.appendChild(
|
|
s(document.createElement('div'), h.count)
|
|
)
|
|
f.legend = f.container.appendChild(
|
|
s(document.createElement('div'), h.legend)
|
|
)
|
|
f.graph = d.graph
|
|
? f.container.appendChild(s(document.createElement('div'), h.graph))
|
|
: 0
|
|
w.length = 0
|
|
for (var q in f) f[q] && h[q].heatOn && w.push({ name: q, el: f[q] })
|
|
u.length = 0
|
|
if (f.graph) {
|
|
f.graph.style.width =
|
|
d.history * h.column.width + (d.history - 1) * h.column.spacing + 'px'
|
|
for (c = 0; c < d.history; c++)
|
|
(u[c] = f.graph.appendChild(
|
|
s(document.createElement('div'), h.column)
|
|
)),
|
|
(u[c].style.position = 'absolute'),
|
|
(u[c].style.bottom = 0),
|
|
(u[c].style.right =
|
|
c * h.column.width + c * h.column.spacing + 'px'),
|
|
(u[c].style.width = h.column.width + 'px'),
|
|
(u[c].style.height = '0px')
|
|
}
|
|
s(f.container, d)
|
|
r()
|
|
a.appendChild(f.container)
|
|
f.graph && (O = f.graph.clientHeight)
|
|
d.toggleOn &&
|
|
('click' === d.toggleOn && (f.container.style.cursor = 'pointer'),
|
|
S(f.container, d.toggleOn, G))
|
|
}
|
|
'object' === H(a) && a.nodeType === j && ((e = a), (a = document.body))
|
|
a || (a = document.body)
|
|
var b = this,
|
|
d = I({}, D.defaults, e || {}),
|
|
f = {},
|
|
u = [],
|
|
h,
|
|
y,
|
|
J = 100,
|
|
w = [],
|
|
W = 0,
|
|
B = d.threshold,
|
|
Q = 0,
|
|
L = A() - B,
|
|
z,
|
|
E = [],
|
|
F = [],
|
|
x,
|
|
P,
|
|
q = 'fps' === d.show,
|
|
O,
|
|
K,
|
|
c,
|
|
p
|
|
b.options = d
|
|
b.fps = 0
|
|
b.duration = 0
|
|
b.isPaused = 0
|
|
b.tickStart = function () {
|
|
Q = A()
|
|
}
|
|
b.tick = function () {
|
|
z = A()
|
|
W = z - L
|
|
B += (W - B) / d.smoothing
|
|
b.fps = 1e3 / B
|
|
b.duration = Q < L ? B : z - Q
|
|
L = z
|
|
}
|
|
b.pause = function () {
|
|
x && ((b.isPaused = 1), clearTimeout(x), C(x), C(P), (x = P = 0))
|
|
return b
|
|
}
|
|
b.resume = function () {
|
|
x || ((b.isPaused = 0), k())
|
|
return b
|
|
}
|
|
b.set = function (a, c) {
|
|
d[a] = c
|
|
q = 'fps' === d.show
|
|
;-1 !== R(a, X) && V()
|
|
;-1 !== R(a, Y) && s(f.container, d)
|
|
return b
|
|
}
|
|
b.showDuration = function () {
|
|
b.set('show', 'ms')
|
|
return b
|
|
}
|
|
b.showFps = function () {
|
|
b.set('show', 'fps')
|
|
return b
|
|
}
|
|
b.toggle = function () {
|
|
b.set('show', q ? 'ms' : 'fps')
|
|
return b
|
|
}
|
|
b.hide = function () {
|
|
b.pause()
|
|
f.container.style.display = 'none'
|
|
return b
|
|
}
|
|
b.show = function () {
|
|
b.resume()
|
|
f.container.style.display = 'block'
|
|
return b
|
|
}
|
|
b.destroy = function () {
|
|
b.pause()
|
|
U()
|
|
b.tick = b.tickStart = function () {}
|
|
}
|
|
V()
|
|
k()
|
|
}
|
|
var A,
|
|
r = m.performance
|
|
A =
|
|
r && (r.now || r.webkitNow)
|
|
? r[r.now ? 'now' : 'webkitNow'].bind(r)
|
|
: function () {
|
|
return +new Date()
|
|
}
|
|
for (
|
|
var C = m.cancelAnimationFrame || m.cancelRequestAnimationFrame,
|
|
M = m.requestAnimationFrame,
|
|
r = ['moz', 'webkit', 'o'],
|
|
G = 0,
|
|
k = 0,
|
|
Z = r.length;
|
|
k < Z && !C;
|
|
++k
|
|
)
|
|
M =
|
|
(C =
|
|
m[r[k] + 'CancelAnimationFrame'] ||
|
|
m[r[k] + 'CancelRequestAnimationFrame']) &&
|
|
m[r[k] + 'RequestAnimationFrame']
|
|
C ||
|
|
((M = function (a) {
|
|
var e = A(),
|
|
g = Math.max(0, 16 - (e - G))
|
|
G = e + g
|
|
return m.setTimeout(function () {
|
|
a(e + g)
|
|
}, g)
|
|
}),
|
|
(C = function (a) {
|
|
clearTimeout(a)
|
|
}))
|
|
var T =
|
|
'string' === H(document.createElement('div').textContent)
|
|
? 'textContent'
|
|
: 'innerText'
|
|
D.extend = I
|
|
window.FPSMeter = D
|
|
D.defaults = {
|
|
interval: 100,
|
|
smoothing: 10,
|
|
show: 'fps',
|
|
toggleOn: 'click',
|
|
decimals: 1,
|
|
maxFps: 60,
|
|
threshold: 100,
|
|
position: 'absolute',
|
|
zIndex: 10,
|
|
left: '5px',
|
|
top: '5px',
|
|
right: 'auto',
|
|
bottom: 'auto',
|
|
margin: '0 0 0 0',
|
|
theme: 'dark',
|
|
heat: 0,
|
|
graph: 0,
|
|
history: 20,
|
|
}
|
|
var X = ['toggleOn', 'theme', 'heat', 'graph', 'history'],
|
|
Y = 'position zIndex left top right bottom margin'.split(' ')
|
|
})(window)
|
|
;(function (m, j) {
|
|
j.theme = {}
|
|
var s = (j.theme.base = {
|
|
heatmaps: [],
|
|
container: {
|
|
heatOn: null,
|
|
heatmap: null,
|
|
padding: '5px',
|
|
minWidth: '95px',
|
|
height: '30px',
|
|
lineHeight: '30px',
|
|
textAlign: 'right',
|
|
textShadow: 'none',
|
|
},
|
|
count: {
|
|
heatOn: null,
|
|
heatmap: null,
|
|
position: 'absolute',
|
|
top: 0,
|
|
right: 0,
|
|
padding: '5px 10px',
|
|
height: '30px',
|
|
fontSize: '24px',
|
|
fontFamily: 'Consolas, Andale Mono, monospace',
|
|
zIndex: 2,
|
|
},
|
|
legend: {
|
|
heatOn: null,
|
|
heatmap: null,
|
|
position: 'absolute',
|
|
top: 0,
|
|
left: 0,
|
|
padding: '5px 10px',
|
|
height: '30px',
|
|
fontSize: '12px',
|
|
lineHeight: '32px',
|
|
fontFamily: 'sans-serif',
|
|
textAlign: 'left',
|
|
zIndex: 2,
|
|
},
|
|
graph: {
|
|
heatOn: null,
|
|
heatmap: null,
|
|
position: 'relative',
|
|
boxSizing: 'padding-box',
|
|
MozBoxSizing: 'padding-box',
|
|
height: '100%',
|
|
zIndex: 1,
|
|
},
|
|
column: { width: 4, spacing: 1, heatOn: null, heatmap: null },
|
|
})
|
|
j.theme.dark = j.extend({}, s, {
|
|
heatmaps: [{ saturation: 0.8, lightness: 0.8 }],
|
|
container: {
|
|
background: '#222',
|
|
color: '#fff',
|
|
border: '1px solid #1a1a1a',
|
|
textShadow: '1px 1px 0 #222',
|
|
},
|
|
count: { heatOn: 'color' },
|
|
column: { background: '#3f3f3f' },
|
|
})
|
|
j.theme.light = j.extend({}, s, {
|
|
heatmaps: [{ saturation: 0.5, lightness: 0.5 }],
|
|
container: {
|
|
color: '#666',
|
|
background: '#fff',
|
|
textShadow:
|
|
'1px 1px 0 rgba(255,255,255,.5), -1px -1px 0 rgba(255,255,255,.5)',
|
|
boxShadow: '0 0 0 1px rgba(0,0,0,.1)',
|
|
},
|
|
count: { heatOn: 'color' },
|
|
column: { background: '#eaeaea' },
|
|
})
|
|
j.theme.colorful = j.extend({}, s, {
|
|
heatmaps: [{ saturation: 0.5, lightness: 0.6 }],
|
|
container: {
|
|
heatOn: 'backgroundColor',
|
|
background: '#888',
|
|
color: '#fff',
|
|
textShadow: '1px 1px 0 rgba(0,0,0,.2)',
|
|
boxShadow: '0 0 0 1px rgba(0,0,0,.1)',
|
|
},
|
|
column: { background: '#777', backgroundColor: 'rgba(0,0,0,.2)' },
|
|
})
|
|
j.theme.transparent = j.extend({}, s, {
|
|
heatmaps: [{ saturation: 0.8, lightness: 0.5 }],
|
|
container: {
|
|
padding: 0,
|
|
color: '#fff',
|
|
textShadow: '1px 1px 0 rgba(0,0,0,.5)',
|
|
},
|
|
count: { padding: '0 5px', height: '40px', lineHeight: '40px' },
|
|
legend: { padding: '0 5px', height: '40px', lineHeight: '42px' },
|
|
graph: { height: '40px' },
|
|
column: {
|
|
width: 5,
|
|
background: '#999',
|
|
heatOn: 'backgroundColor',
|
|
opacity: 0.5,
|
|
},
|
|
})
|
|
})(window, FPSMeter)
|