diff --git a/demos/worker.html b/demos/worker.html
index 8b69b7d..c8eec8a 100644
--- a/demos/worker.html
+++ b/demos/worker.html
@@ -1,82 +1,38 @@
-
Worker
-
- Canvas is running whilst an prime number finder runs in a worker
- Prime found: 0
-
-
-
+
+
+ Worker
+
+
+
+ Web Worker Demo
+ Works in Chrome, Safari, and Firefox. Web worker portion works in Opera.
+ Use arrow keys to change the direction of the animated square. The square is animated with requestAnimationFrame.
+ Click the button below to start or stop the worker.
+
+ Messages from Worker:
+
+
+
+
+
diff --git a/js/cruncher.js b/js/cruncher.js
deleted file mode 100644
index 96ec29a..0000000
--- a/js/cruncher.js
+++ /dev/null
@@ -1,24 +0,0 @@
-var running = false;
-
-onmessage = function (event) {
- // doesn't matter what the message is, just toggle the worker
- if (running == false) {
- running = true;
- run();
- } else {
- running = false;
- }
-};
-
-function run() {
- var n = 1;
- search: while (running) {
- n += 1;
- for (var i = 2; i <= Math.sqrt(n); i += 1)
- if (n % i == 0)
- continue search;
- // found a prime!
- postMessage(n);
- }
-}
-
diff --git a/js/worker-cruncher.js b/js/worker-cruncher.js
new file mode 100644
index 0000000..82bd24c
--- /dev/null
+++ b/js/worker-cruncher.js
@@ -0,0 +1,68 @@
+/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, browser: true */
+/*global postMessage, addEventListener */
+
+(function () {
+ "use strict";
+
+ var WHEN_TO_STOP = 10000000;
+ var COMPUTE_BLOCK_SIZE = 1000000;
+
+ var running = false;
+ var count = 0;
+
+ // We have to compute in blocks of ~1 second of computation in order to make sure
+ // that we read our message queue occasionally. Worker threads are not preemptive
+ // (like all JS), so if we don't pause computation to read the message queue, we'll
+ // be unresponsive to user requests.
+ function compute(start) {
+ var n = start;
+ var i, hasDivisor;
+
+ if (!running) { // got a message to stop before this call to compute
+ postMessage("Stopped!");
+ } else {
+ while (n < start + COMPUTE_BLOCK_SIZE) {
+ hasDivisor = false;
+ for (i = 2; i <= Math.sqrt(n); i += 1) {
+ if (n % i === 0) {
+ hasDivisor = true;
+ break;
+ }
+ }
+ if (!hasDivisor) {
+ // found a prime!
+ count++;
+ }
+ n += 1;
+ }
+
+ if (n < WHEN_TO_STOP) {
+ // allow for event loop to actually forward messages to the worker
+ setTimeout(function () { compute(n); }, 1);
+ } else {
+ // we reached the end
+ running = false;
+ postMessage("Done!");
+ }
+ }
+
+ // Finally, always report how many primes we've found so far
+ postMessage("Found " + count + " primes between 2 and " + (n - 1));
+
+ }
+
+ addEventListener('message', function (event) {
+ // doesn't matter what the message is, just toggle the worker
+ if (running === false) {
+ postMessage("Starting...");
+ count = 0;
+ running = true;
+ compute(1);
+ } else {
+ postMessage("Stopping...");
+ running = false;
+ }
+ });
+
+
+}());
\ No newline at end of file
diff --git a/js/worker-main.js b/js/worker-main.js
new file mode 100644
index 0000000..5077b18
--- /dev/null
+++ b/js/worker-main.js
@@ -0,0 +1,92 @@
+/*jslint vars: true, plusplus: true, devel: true, nomen: true, indent: 4, maxerr: 50, browser: true */
+/*global Worker */
+
+(function () {
+ "use strict";
+
+ var SQUARE_SIZE = 75;
+ var MOVEMENT_STEP = 3;
+
+ var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
+ window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
+
+
+ // Set up the worker
+ var running = false;
+ var statusDiv = document.getElementById('status');
+ var button = document.getElementById('toggleWorker');
+ var worker = new Worker('../js/worker-cruncher.js'); // path is relative to the main HTML file
+ worker.addEventListener('message', function (event) {
+ var currentStatus = statusDiv.innerHTML;
+ statusDiv.innerHTML = "" + event.data + "
" + currentStatus;
+ if (event.data === "Done!") {
+ running = false;
+ button.value = "start worker";
+ }
+ });
+
+ button.onclick = function () {
+ running = !running;
+ if (running) {
+ statusDiv.innerHTML = "";
+ button.value = "stop worker";
+ } else {
+ button.value = "start worker";
+ }
+ worker.postMessage('');
+
+ };
+
+
+ // Set up the animated square
+ var square = document.getElementById('square');
+ var direction = 39; // right
+
+ square.style.top = 0;
+ square.style.left = 20;
+ square.style.height = SQUARE_SIZE;
+ square.style.width = SQUARE_SIZE;
+
+ function moveSquare() {
+ var left = parseInt(square.style.left, 10);
+ var top = parseInt(square.style.top, 10);
+ var right = left + SQUARE_SIZE;
+ var bottom = top + SQUARE_SIZE;
+
+ switch (direction) {
+ case 37: // left
+ if (left > 0) {
+ square.style.left = left - MOVEMENT_STEP;
+ }
+ break;
+ case 38: // up
+ if (top > 0) {
+ square.style.top = top - MOVEMENT_STEP;
+ }
+ break;
+ case 39: //right
+ if (right < document.documentElement.clientWidth) {
+ square.style.left = left + MOVEMENT_STEP;
+ }
+ break;
+ case 40: // down
+ if (bottom < document.documentElement.clientHeight) {
+ square.style.top = top + MOVEMENT_STEP;
+ }
+ break;
+ default:
+ break;
+ }
+ requestAnimationFrame(moveSquare);
+ }
+
+ window.onkeydown = function (event) {
+ if (event.keyCode >= 37 && event.keyCode <= 40) { // is an arrow key
+ direction = event.keyCode;
+ }
+ };
+
+ // start the square animating
+ requestAnimationFrame(moveSquare);
+
+}());
\ No newline at end of file
diff --git a/js/worker.js b/js/worker.js
deleted file mode 100644
index 6e49142..0000000
--- a/js/worker.js
+++ /dev/null
@@ -1,23 +0,0 @@
-var running = false;
-var ctr = 0;
-
-function log(s) {
- postMessage('log:' + s);
-}
-
-onmessage = function (event) {
- // doesn't matter what the message is, just toggle the worker
- if (running == false) {
- running = true;
- run();
- } else {
- running = false;
- }
-};
-
-function run() {
- while (running) {
- postMessage(ctr);
- ctr++;
- }
-}