Merge branch 'new-web-worker-demo' of git://github.com/joelrbrandt/html5demos
This commit is contained in:
commit
61fe0b95f6
|
@ -1,82 +1,38 @@
|
||||||
<title>Worker</title>
|
<html>
|
||||||
<article>
|
<head>
|
||||||
<p>Canvas is running whilst an prime number finder runs in a worker</p>
|
<title>Worker</title>
|
||||||
<p>Prime found: <span id="status">0</span></p>
|
<style>
|
||||||
<div><input type="button" value="start worker" id="toggleWorker" /></div>
|
body {
|
||||||
</article>
|
font-family: sans-serif;
|
||||||
<script>
|
}
|
||||||
|
|
||||||
buildSpinner({ x : 50, y : 50, size : 20, degrees : 30 });
|
#status {
|
||||||
|
height: 200px;
|
||||||
var w = new Worker('/js/cruncher.js');
|
max-height: 200px;
|
||||||
|
border: thin solid black;
|
||||||
addEvent(document.getElementById('toggleWorker'), 'click', function () {
|
overflow-y: scroll;
|
||||||
w.postMessage('');
|
}
|
||||||
});
|
|
||||||
|
#square {
|
||||||
w.onmessage = function (event) {
|
position: absolute;
|
||||||
if (event.data && (event.data+"").match(/^log:/i)) {
|
left: 0px;
|
||||||
console.log(event.data.match(/^log:\s*(.*)/)[1]);
|
top: 0px;
|
||||||
} else {
|
width: 75px;
|
||||||
document.querySelector('#status').innerHTML = event.data;
|
height: 75px;
|
||||||
}
|
background-color: rgba(0, 0, 220, 0.3);
|
||||||
}
|
z-index: -1;
|
||||||
|
}
|
||||||
function buildSpinner(data) {
|
</style>
|
||||||
|
</head>
|
||||||
var canvas = document.createElement('canvas');
|
<body>
|
||||||
canvas.height = 100;
|
<h1>Web Worker Demo</h1>
|
||||||
canvas.width = 300;
|
<p>Works in Chrome, Safari, and Firefox. Web worker portion works in Opera.</p>
|
||||||
document.querySelector('article').appendChild(canvas);
|
<p>Use arrow keys to change the direction of the animated square. The square is animated with <em>requestAnimationFrame</em>.</p>
|
||||||
var ctx = canvas.getContext("2d"),
|
<p>Click the button below to start or stop the worker.</p>
|
||||||
i = 0, degrees = data.degrees, loops = 0, degreesList = [];
|
<div><input type="button" value="start worker" id="toggleWorker" /></div>
|
||||||
|
<h2>Messages from Worker:</h2>
|
||||||
for (i = 0; i < degrees; i++) {
|
<div id="status"></div>
|
||||||
degreesList.push(i);
|
<div id="square"></div>
|
||||||
}
|
<script src="../js/worker-main.js"></script>
|
||||||
|
</body>
|
||||||
// reset
|
</html>
|
||||||
i = 0;
|
|
||||||
|
|
||||||
// so I can kill it later
|
|
||||||
window.canvasTimer = setInterval(draw, 1000/degrees);
|
|
||||||
|
|
||||||
function reset() {
|
|
||||||
ctx.clearRect(0,0,100,100); // clear canvas
|
|
||||||
|
|
||||||
var left = degreesList.slice(0, 1);
|
|
||||||
var right = degreesList.slice(1, degreesList.length);
|
|
||||||
degreesList = right.concat(left);
|
|
||||||
}
|
|
||||||
|
|
||||||
function draw() {
|
|
||||||
var c, s, e;
|
|
||||||
|
|
||||||
var d = 0;
|
|
||||||
|
|
||||||
if (i == 0) {
|
|
||||||
reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.save();
|
|
||||||
|
|
||||||
d = degreesList[i];
|
|
||||||
c = Math.floor(255/degrees*i);
|
|
||||||
ctx.strokeStyle = 'rgb(' + c + ', ' + c + ', ' + c + ')';
|
|
||||||
ctx.lineWidth = data.size;
|
|
||||||
ctx.beginPath();
|
|
||||||
s = Math.floor(360/degrees*(d));
|
|
||||||
e = Math.floor(360/degrees*(d+1)) - 1;
|
|
||||||
|
|
||||||
ctx.arc(data.x, data.y, data.size, (Math.PI/180)*s, (Math.PI/180)*e, false);
|
|
||||||
ctx.stroke();
|
|
||||||
|
|
||||||
ctx.restore();
|
|
||||||
|
|
||||||
i++;
|
|
||||||
if (i >= degrees) {
|
|
||||||
i = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}());
|
|
@ -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 = "<p>" + event.data + "</p>" + 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);
|
||||||
|
|
||||||
|
}());
|
23
js/worker.js
23
js/worker.js
|
@ -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++;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue