├── src
├── dist
├── Description.js
├── Header.js
├── styles.css
├── index.js
├── helpers.js
└── vendor
│ └── fpsmeter.min.js
├── .vscode
└── settings.json
├── public
├── favicon.ico
├── manifest.json
└── index.html
├── .gitignore
├── README.md
└── package.json
/src/dist:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "eslint.enable": false,
3 | "cSpell.enabled": false
4 | }
5 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/philipp-spiess/scheduletron3000/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": ".",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ScheduleTron 3000
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | An example app used to demonstrate the new React features Concurrent React and the Scheduler.
10 |
11 | [Read more in this blog post about Scheduling in React.](https://philippspiess.com/scheduling-in-react/)
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "scheduletron3000",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "react": "^16.7.0",
7 | "react-dom": "^16.7.0",
8 | "react-scripts": "2.1.5"
9 | },
10 | "scripts": {
11 | "start": "react-scripts start",
12 | "build": "react-scripts build",
13 | "test": "react-scripts test",
14 | "eject": "react-scripts eject"
15 | },
16 | "eslintConfig": {
17 | "extends": "react-app"
18 | },
19 | "browserslist": [
20 | ">0.2%",
21 | "not dead",
22 | "not ie <= 11",
23 | "not op_mini all"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/src/Description.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { CONCURRENT_AND_SCHEDULED } from './index'
3 | import './vendor/fpsmeter.min'
4 |
5 | export default class Description extends React.Component {
6 | fpsRef = React.createRef();
7 |
8 | componentDidMount() {
9 | const anchor = this.fpsRef.current;
10 |
11 | // eslint-disable-next-line no-undef
12 | const meter = new FPSMeter(anchor, {
13 | heat: true,
14 | graph: true
15 | });
16 |
17 | function tick() {
18 | meter.tick();
19 | requestAnimationFrame(tick);
20 | }
21 |
22 | tick();
23 | }
24 |
25 | render() {
26 | return (
27 |
28 |
29 | {CONCURRENT_AND_SCHEDULED
30 | ? "Concurrent and Scheduled"
31 | : "Synchronous"}
32 |
33 |
34 |
35 |
36 | );
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/Header.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const SPEED = 0.01;
4 |
5 | export default class Header extends React.PureComponent {
6 | state = { offset: 0 };
7 | t0 = Date.now();
8 | ref = React.createRef();
9 |
10 | componentDidMount() {
11 | this.frame = requestAnimationFrame(this.animate);
12 | }
13 |
14 | componentWillUnmount() {
15 | if (this.frame) {
16 | cancelAnimationFrame(this.frame);
17 | }
18 | }
19 |
20 | animate = () => {
21 | requestAnimationFrame(this.animate);
22 |
23 | const text = this.props.children;
24 |
25 | const td = Date.now() - this.t0;
26 | const offset = td * SPEED;
27 |
28 | const h1 = this.ref.current;
29 |
30 | if (!h1) {
31 | return;
32 | }
33 |
34 | h1.innerHTML = "";
35 |
36 | for (let i = 0; i < text.length; i++) {
37 | let charElem = document.createElement("span");
38 | charElem.style.color =
39 | "hsl(" + (360 * (i + offset)) / text.length + ",80%,60%)";
40 | charElem.innerHTML = text[i];
41 | h1.appendChild(charElem);
42 | }
43 | };
44 |
45 | render() {
46 | return ;
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/styles.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | margin-bottom: 40vh;
4 | }
5 |
6 | body {
7 | background-color: #0b0b0c;
8 | color: white;
9 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen,
10 | Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
11 | }
12 |
13 | .input {
14 | padding: 16px;
15 | font-size: 30px;
16 | width: 80%;
17 | display: block;
18 | margin: 60px auto;
19 | }
20 |
21 | h1 {
22 | color: #fcd93b;
23 | font-size: 87px;
24 | margin: 60px;
25 | }
26 |
27 | .name {
28 | font-size: 30px;
29 | padding: 20px 0;
30 | width: 50%;
31 | float: left;
32 | color: #ffadb4;
33 | }
34 |
35 | .highlight {
36 | color: #000000;
37 | background: #ffadb4;
38 | padding: 5px;
39 | }
40 |
41 | .clearfix::after {
42 | clear: both;
43 | content: "";
44 | }
45 |
46 | .marketing {
47 | background: linear-gradient(transparent 0%, black 80%);
48 | position: fixed;
49 | left: 0;
50 | right: 0;
51 | bottom: 0;
52 | height: 40vh;
53 | text-align: left;
54 | padding-left: 100px;
55 | padding-right: 100px;
56 | padding-bottom: 50px;
57 | display: flex;
58 | align-items: flex-end;
59 | }
60 |
61 | .marketing > span {
62 | font-size: 4rem;
63 | }
64 |
65 | .spacer {
66 | flex-grow: 1;
67 | }
68 |
69 | .fps {
70 | zoom: 2;
71 | position: relative;
72 | width: 120px;
73 | height: 40px;
74 | }
75 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
15 |
16 |
25 | React App
26 |
27 |
28 |
29 |
30 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import { NameList, sendAnalyticsPing } from "./helpers";
2 | import React from "react";
3 | import ReactDOM from "react-dom";
4 | import Header from "./Header";
5 | import Description from "./Description";
6 |
7 | import {
8 | unstable_LowPriority,
9 | unstable_next,
10 | unstable_runWithPriority,
11 | unstable_scheduleCallback
12 | } from "scheduler";
13 |
14 | import "./styles.css";
15 |
16 | // Change the flag below to enable Concurrent React and Scheduler improvements
17 | // as layed out in https://philippspiess.com/scheduling-in-react
18 | export const CONCURRENT_AND_SCHEDULED = true;
19 |
20 | class App extends React.Component {
21 | state = {
22 | searchValue: ""
23 | };
24 |
25 | handleChange = value => {
26 | this.setState({ searchValue: value });
27 | };
28 |
29 | render() {
30 | const { searchValue } = this.state;
31 |
32 | return (
33 |
34 |
35 |
36 |
37 |
38 |
39 | );
40 | }
41 | }
42 |
43 | class SearchBox extends React.Component {
44 | state = {
45 | inputValue: ""
46 | };
47 |
48 | handleChange = event => {
49 | const value = event.target.value;
50 | const onChange = this.props.onChange;
51 |
52 | if (CONCURRENT_AND_SCHEDULED) {
53 | this.setState({ inputValue: value });
54 |
55 | unstable_next(function() {
56 | onChange(value);
57 | });
58 |
59 | sendDeferredAnalyticsPing(value);
60 | } else {
61 | this.setState({ inputValue: value });
62 | onChange(value);
63 | sendAnalyticsPing(value);
64 | }
65 | };
66 |
67 | render() {
68 | const { inputValue } = this.state;
69 |
70 | return (
71 |
72 |
79 |
80 | );
81 | }
82 | }
83 |
84 | function sendDeferredAnalyticsPing(value) {
85 | unstable_runWithPriority(unstable_LowPriority, function() {
86 | unstable_scheduleCallback(function() {
87 | sendAnalyticsPing(value);
88 | });
89 | });
90 | }
91 |
92 | const rootElement = document.getElementById("root");
93 | const Wrapper = ReactDOM.render(
94 | CONCURRENT_AND_SCHEDULED ? (
95 |
96 |
97 |
98 | ) : (
99 |
100 | ),
101 | rootElement
102 | );
103 |
--------------------------------------------------------------------------------
/src/helpers.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export function NameList({ searchValue }) {
4 | return (
5 |
6 | {names.map(name => (
7 |
8 | ))}
9 |
10 | );
11 | }
12 |
13 | export function Name({ name, searchValue }) {
14 | const matchesFilterAtIndex = name
15 | .toLowerCase()
16 | .indexOf(searchValue.toLowerCase());
17 |
18 | miningBitcoin(2);
19 |
20 | if (matchesFilterAtIndex >= 0 && searchValue !== "") {
21 | return (
22 |
23 | {name.substring(0, matchesFilterAtIndex)}
24 |
25 | {name.substring(
26 | matchesFilterAtIndex,
27 | matchesFilterAtIndex + searchValue.length
28 | )}
29 |
30 |
31 | {name.substring(matchesFilterAtIndex + searchValue.length)}
32 |
33 | );
34 | } else {
35 | return {name}
;
36 | }
37 | }
38 |
39 | export function sendAnalyticsPing(value) {
40 | performance.mark("analytics-start");
41 | miningBitcoin(25);
42 | performance.mark("analytics-end");
43 | performance.measure(
44 | "Analytics: " + value,
45 | "analytics-start",
46 | "analytics-end"
47 | );
48 | }
49 |
50 | function miningBitcoin(ms) {
51 | let now = Date.now();
52 | while (Date.now() < now + ms) {
53 | // noop
54 | }
55 | }
56 |
57 | const names = [
58 | "Ada Moreno",
59 | "Ada Stewart",
60 | "Adele Valdez",
61 | "Adeline Knight",
62 | "Agnes Newman",
63 | "Alfred Stephens",
64 | "Allie Harris",
65 | "Andre Owen",
66 | "Andrew Clark",
67 | "Angel Murray",
68 | "Arthur Osborne",
69 | "Arthur Woods",
70 | "Barbara Holt",
71 | "Billy Baker",
72 | "Brian Vaughn",
73 | "Calvin Edwards",
74 | "Carl Pierce",
75 | "Charles Sanchez",
76 | "Charlie Hicks",
77 | "Charlie Matthews",
78 | "Chase Ruiz",
79 | "Chester Chandler",
80 | "Christopher Marsh",
81 | "Cordelia Brock",
82 | "Corey Gonzalez",
83 | "Cornelia Gordon",
84 | "Cory Lane",
85 | "Daisy Pena",
86 | "Dan Abramov",
87 | "Dollie Wilkerson",
88 | "Dominic Gannaway",
89 | "Dorothy Singleton",
90 | "Eddie Horton",
91 | "Lottie Harper",
92 | "Louis McBride",
93 | "Mabel Daniels",
94 | "Mabelle Bowman",
95 | "Martha Moreno",
96 | "Martin Simpson",
97 | "Mary Powers",
98 | "Mary Snyder",
99 | "Matthew Collier",
100 | "Maurice Myers",
101 | "Myra Jennings",
102 | "Myra Stephens",
103 | "Nellie Potter",
104 | "Nora Cannon",
105 | "Ola Bryant",
106 | "Paul Coleman",
107 | "Pearl Moss",
108 | "Phoebe Underwood",
109 | "Rachel May",
110 | "Sebastian Markbåge",
111 | "Shawn Lloyd",
112 | "Shawn Lynch",
113 | "Sophie Alpert",
114 | "Stella Lane",
115 | "Steve Byrd",
116 | "Steve Schmidt",
117 | "Sunil Pai",
118 | "Teresa Doyle",
119 | "Timothy Gray",
120 | "Timothy Harvey",
121 | "Todd Stewart",
122 | "Todd Washington"
123 | ];
124 |
--------------------------------------------------------------------------------
/src/vendor/fpsmeter.min.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 |
3 | /*! FPSMeter 0.3.0 - 24th Apr 2013 | https://github.com/Darsain/fpsmeter */
4 | (function(r, j) {
5 | function s(a, e) {
6 | for (var g in e)
7 | try {
8 | a.style[g] = e[g];
9 | } catch (j) {}
10 | return a;
11 | }
12 | function H(a) {
13 | return Object.prototype.toString
14 | .call(a)
15 | .match(/\s([a-z]+)/i)[1]
16 | .toLowerCase();
17 | }
18 | function R(a, e) {
19 | if ("array" !== H(e)) return -1;
20 | if (e.indexOf) return e.indexOf(a);
21 | for (var g = 0, j = e.length; g < j; g++) if (e[g] === a) return g;
22 | return -1;
23 | }
24 | function I() {
25 | var a = arguments,
26 | e;
27 | for (e in a[1])
28 | if (a[1].hasOwnProperty(e))
29 | switch (H(a[1][e])) {
30 | case "object":
31 | a[0][e] = I({}, a[0][e], a[1][e]);
32 | break;
33 | case "array":
34 | a[0][e] = a[1][e].slice(0);
35 | break;
36 | default:
37 | a[0][e] = a[1][e];
38 | }
39 | return 2 < a.length
40 | ? I.apply(null, [a[0]].concat(Array.prototype.slice.call(a, 2)))
41 | : a[0];
42 | }
43 | function N(a) {
44 | a = Math.round(255 * a).toString(16);
45 | return 1 === a.length ? "0" + a : a;
46 | }
47 | function S(a, e, g, j) {
48 | if (a.addEventListener)
49 | a[j ? "removeEventListener" : "addEventListener"](e, g, !1);
50 | else if (a.attachEvent) a[j ? "detachEvent" : "attachEvent"]("on" + e, g);
51 | }
52 | function D(a, e) {
53 | function g(b, a, d, c) {
54 | return y[0 | b][Math.round(Math.min(((a - d) / (c - d)) * J, J))];
55 | }
56 | function r() {
57 | f.legend.fps !== q &&
58 | ((f.legend.fps = q), (f.legend[T] = q ? "FPS" : "ms"));
59 | K = q ? b.fps : b.duration;
60 | f.count[T] = 999 < K ? "999+" : K.toFixed(99 < K ? 0 : d.decimals);
61 | }
62 | function m() {
63 | z = A();
64 | L < z - d.threshold &&
65 | ((b.fps -= b.fps / Math.max(1, (60 * d.smoothing) / d.interval)),
66 | (b.duration = 1e3 / b.fps));
67 | for (c = d.history; c--; )
68 | (E[c] = 0 === c ? b.fps : E[c - 1]),
69 | (F[c] = 0 === c ? b.duration : F[c - 1]);
70 | r();
71 | if (d.heat) {
72 | if (w.length)
73 | for (c = w.length; c--; )
74 | w[c].el.style[h[w[c].name].heatOn] = q
75 | ? g(h[w[c].name].heatmap, b.fps, 0, d.maxFps)
76 | : g(h[w[c].name].heatmap, b.duration, d.threshold, 0);
77 | if (f.graph && h.column.heatOn)
78 | for (c = u.length; c--; )
79 | u[c].style[h.column.heatOn] = q
80 | ? g(h.column.heatmap, E[c], 0, d.maxFps)
81 | : g(h.column.heatmap, F[c], d.threshold, 0);
82 | }
83 | if (f.graph)
84 | for (p = 0; p < d.history; p++)
85 | u[p].style.height =
86 | (q
87 | ? E[p]
88 | ? Math.round((O / d.maxFps) * Math.min(E[p], d.maxFps))
89 | : 0
90 | : F[p]
91 | ? Math.round((O / d.threshold) * Math.min(F[p], d.threshold))
92 | : 0) + "px";
93 | }
94 | function k() {
95 | 20 > d.interval
96 | ? ((x = M(k)), m())
97 | : ((x = setTimeout(k, d.interval)), (P = M(m)));
98 | }
99 | function G(a) {
100 | a = a || window.event;
101 | a.preventDefault
102 | ? (a.preventDefault(), a.stopPropagation())
103 | : ((a.returnValue = !1), (a.cancelBubble = !0));
104 | b.toggle();
105 | }
106 | function U() {
107 | d.toggleOn && S(f.container, d.toggleOn, G, 1);
108 | a.removeChild(f.container);
109 | }
110 | function V() {
111 | f.container && U();
112 | h = D.theme[d.theme];
113 | y = h.compiledHeatmaps || [];
114 | if (!y.length && h.heatmaps.length) {
115 | for (p = 0; p < h.heatmaps.length; p++) {
116 | y[p] = [];
117 | for (c = 0; c <= J; c++) {
118 | var b = y[p],
119 | e = c,
120 | g;
121 | g = (0.33 / J) * c;
122 | var j = h.heatmaps[p].saturation,
123 | m = h.heatmaps[p].lightness,
124 | n = void 0,
125 | k = void 0,
126 | l = void 0,
127 | t = (l = void 0),
128 | v = (n = k = void 0),
129 | v = void 0,
130 | l = 0.5 >= m ? m * (1 + j) : m + j - m * j;
131 | 0 === l
132 | ? (g = "#000")
133 | : ((t = 2 * m - l),
134 | (k = (l - t) / l),
135 | (g *= 6),
136 | (n = Math.floor(g)),
137 | (v = g - n),
138 | (v *= l * k),
139 | 0 === n || 6 === n
140 | ? ((n = l), (k = t + v), (l = t))
141 | : 1 === n
142 | ? ((n = l - v), (k = l), (l = t))
143 | : 2 === n
144 | ? ((n = t), (k = l), (l = t + v))
145 | : 3 === n
146 | ? ((n = t), (k = l - v))
147 | : 4 === n
148 | ? ((n = t + v), (k = t))
149 | : ((n = l), (k = t), (l -= v)),
150 | (g = "#" + N(n) + N(k) + N(l)));
151 | b[e] = g;
152 | }
153 | }
154 | h.compiledHeatmaps = y;
155 | }
156 | f.container = s(document.createElement("div"), h.container);
157 | f.count = f.container.appendChild(
158 | s(document.createElement("div"), h.count)
159 | );
160 | f.legend = f.container.appendChild(
161 | s(document.createElement("div"), h.legend)
162 | );
163 | f.graph = d.graph
164 | ? f.container.appendChild(s(document.createElement("div"), h.graph))
165 | : 0;
166 | w.length = 0;
167 | for (var q in f) f[q] && h[q].heatOn && w.push({ name: q, el: f[q] });
168 | u.length = 0;
169 | if (f.graph) {
170 | f.graph.style.width =
171 | d.history * h.column.width +
172 | (d.history - 1) * h.column.spacing +
173 | "px";
174 | for (c = 0; c < d.history; c++)
175 | (u[c] = f.graph.appendChild(
176 | s(document.createElement("div"), h.column)
177 | )),
178 | (u[c].style.position = "absolute"),
179 | (u[c].style.bottom = 0),
180 | (u[c].style.right =
181 | c * h.column.width + c * h.column.spacing + "px"),
182 | (u[c].style.width = h.column.width + "px"),
183 | (u[c].style.height = "0px");
184 | }
185 | s(f.container, d);
186 | r();
187 | a.appendChild(f.container);
188 | f.graph && (O = f.graph.clientHeight);
189 | d.toggleOn &&
190 | ("click" === d.toggleOn && (f.container.style.cursor = "pointer"),
191 | S(f.container, d.toggleOn, G));
192 | }
193 | "object" === H(a) && a.nodeType === j && ((e = a), (a = document.body));
194 | a || (a = document.body);
195 | var b = this,
196 | d = I({}, D.defaults, e || {}),
197 | f = {},
198 | u = [],
199 | h,
200 | y,
201 | J = 100,
202 | w = [],
203 | W = 0,
204 | B = d.threshold,
205 | Q = 0,
206 | L = A() - B,
207 | z,
208 | E = [],
209 | F = [],
210 | x,
211 | P,
212 | q = "fps" === d.show,
213 | O,
214 | K,
215 | c,
216 | p;
217 | b.options = d;
218 | b.fps = 0;
219 | b.duration = 0;
220 | b.isPaused = 0;
221 | b.tickStart = function() {
222 | Q = A();
223 | };
224 | b.tick = function() {
225 | z = A();
226 | W = z - L;
227 | B += (W - B) / d.smoothing;
228 | b.fps = 1e3 / B;
229 | b.duration = Q < L ? B : z - Q;
230 | L = z;
231 | };
232 | b.pause = function() {
233 | x && ((b.isPaused = 1), clearTimeout(x), C(x), C(P), (x = P = 0));
234 | return b;
235 | };
236 | b.resume = function() {
237 | x || ((b.isPaused = 0), k());
238 | return b;
239 | };
240 | b.set = function(a, c) {
241 | d[a] = c;
242 | q = "fps" === d.show;
243 | -1 !== R(a, X) && V();
244 | -1 !== R(a, Y) && s(f.container, d);
245 | return b;
246 | };
247 | b.showDuration = function() {
248 | b.set("show", "ms");
249 | return b;
250 | };
251 | b.showFps = function() {
252 | b.set("show", "fps");
253 | return b;
254 | };
255 | b.toggle = function() {
256 | b.set("show", q ? "ms" : "fps");
257 | return b;
258 | };
259 | b.hide = function() {
260 | b.pause();
261 | f.container.style.display = "none";
262 | return b;
263 | };
264 | b.show = function() {
265 | b.resume();
266 | f.container.style.display = "block";
267 | return b;
268 | };
269 | b.destroy = function() {
270 | b.pause();
271 | U();
272 | b.tick = b.tickStart = function() {};
273 | };
274 | V();
275 | k();
276 | }
277 | var A,
278 | m = r.performance;
279 | A = m
280 | ? m[m.now ? "now" : "webkitNow"].bind(m)
281 | : function() {
282 | return +new Date();
283 | };
284 | for (
285 | var C = r.cancelAnimationFrame || r.cancelRequestAnimationFrame,
286 | M = r.requestAnimationFrame,
287 | m = ["moz", "webkit", "o"],
288 | G = 0,
289 | k = 0,
290 | Z = m.length;
291 | k < Z && !C;
292 | ++k
293 | )
294 | M =
295 | (C =
296 | r[m[k] + "CancelAnimationFrame"] ||
297 | r[m[k] + "CancelRequestAnimationFrame"]) &&
298 | r[m[k] + "RequestAnimationFrame"];
299 | C ||
300 | ((M = function(a) {
301 | var e = A(),
302 | g = Math.max(0, 16 - (e - G));
303 | G = e + g;
304 | return r.setTimeout(function() {
305 | a(e + g);
306 | }, g);
307 | }),
308 | (C = function(a) {
309 | clearTimeout(a);
310 | }));
311 | var T =
312 | "string" === H(document.createElement("div").textContent)
313 | ? "textContent"
314 | : "innerText";
315 | D.extend = I;
316 | window.FPSMeter = D;
317 | D.defaults = {
318 | interval: 100,
319 | smoothing: 10,
320 | show: "fps",
321 | toggleOn: "click",
322 | decimals: 1,
323 | maxFps: 60,
324 | threshold: 100,
325 | position: "absolute",
326 | zIndex: 10,
327 | left: "5px",
328 | top: "5px",
329 | right: "auto",
330 | bottom: "auto",
331 | margin: "0 0 0 0",
332 | theme: "dark",
333 | heat: 0,
334 | graph: 0,
335 | history: 20
336 | };
337 | var X = ["toggleOn", "theme", "heat", "graph", "history"],
338 | Y = "position zIndex left top right bottom margin".split(" ");
339 | })(window);
340 | (function(r, j) {
341 | j.theme = {};
342 | var s = (j.theme.base = {
343 | heatmaps: [],
344 | container: {
345 | heatOn: null,
346 | heatmap: null,
347 | padding: "5px",
348 | minWidth: "95px",
349 | height: "30px",
350 | lineHeight: "30px",
351 | textAlign: "right",
352 | textShadow: "none"
353 | },
354 | count: {
355 | heatOn: null,
356 | heatmap: null,
357 | position: "absolute",
358 | top: 0,
359 | right: 0,
360 | padding: "5px 10px",
361 | height: "30px",
362 | fontSize: "24px",
363 | fontFamily: "Consolas, Andale Mono, monospace",
364 | zIndex: 2
365 | },
366 | legend: {
367 | heatOn: null,
368 | heatmap: null,
369 | position: "absolute",
370 | top: 0,
371 | left: 0,
372 | padding: "5px 10px",
373 | height: "30px",
374 | fontSize: "12px",
375 | lineHeight: "32px",
376 | fontFamily: "sans-serif",
377 | textAlign: "left",
378 | zIndex: 2
379 | },
380 | graph: {
381 | heatOn: null,
382 | heatmap: null,
383 | position: "relative",
384 | boxSizing: "padding-box",
385 | MozBoxSizing: "padding-box",
386 | height: "100%",
387 | zIndex: 1
388 | },
389 | column: { width: 4, spacing: 1, heatOn: null, heatmap: null }
390 | });
391 | j.theme.dark = j.extend({}, s, {
392 | heatmaps: [{ saturation: 0.8, lightness: 0.8 }],
393 | container: {
394 | background: "#222",
395 | color: "#fff",
396 | border: "1px solid #1a1a1a",
397 | textShadow: "1px 1px 0 #222"
398 | },
399 | count: { heatOn: "color" },
400 | column: { background: "#3f3f3f" }
401 | });
402 | j.theme.light = j.extend({}, s, {
403 | heatmaps: [{ saturation: 0.5, lightness: 0.5 }],
404 | container: {
405 | color: "#666",
406 | background: "#fff",
407 | textShadow:
408 | "1px 1px 0 rgba(255,255,255,.5), -1px -1px 0 rgba(255,255,255,.5)",
409 | boxShadow: "0 0 0 1px rgba(0,0,0,.1)"
410 | },
411 | count: { heatOn: "color" },
412 | column: { background: "#eaeaea" }
413 | });
414 | j.theme.colorful = j.extend({}, s, {
415 | heatmaps: [{ saturation: 0.5, lightness: 0.6 }],
416 | container: {
417 | heatOn: "backgroundColor",
418 | background: "#888",
419 | color: "#fff",
420 | textShadow: "1px 1px 0 rgba(0,0,0,.2)",
421 | boxShadow: "0 0 0 1px rgba(0,0,0,.1)"
422 | },
423 | column: { background: "#777", backgroundColor: "rgba(0,0,0,.2)" }
424 | });
425 | j.theme.transparent = j.extend({}, s, {
426 | heatmaps: [{ saturation: 0.8, lightness: 0.5 }],
427 | container: {
428 | padding: 0,
429 | color: "#fff",
430 | textShadow: "1px 1px 0 rgba(0,0,0,.5)"
431 | },
432 | count: { padding: "0 5px", height: "40px", lineHeight: "40px" },
433 | legend: { padding: "0 5px", height: "40px", lineHeight: "42px" },
434 | graph: { height: "40px" },
435 | column: {
436 | width: 5,
437 | background: "#999",
438 | heatOn: "backgroundColor",
439 | opacity: 0.5
440 | }
441 | });
442 | })(window, FPSMeter);
443 |
--------------------------------------------------------------------------------