Skip to content

Instantly share code, notes, and snippets.

@darbicus
Created January 1, 2014 18:30
Show Gist options
  • Save darbicus/8210241 to your computer and use it in GitHub Desktop.
Save darbicus/8210241 to your computer and use it in GitHub Desktop.
A Pen by Darby Rathbone.
<script type="text/js-worker">
</script>
<textarea rows="20" cols="100" id='workersrc'>onmessage = function (e) {
if(e.data == "draw") w.getPoints();
var d = JSON.parse(e.data);
if(JSON.parse(e.data).action == "add") w.addBall(parseFloat(d.x), parseFloat(d.y), 0, 0, parseFloat(d.r))
};
Number.prototype.add = function (b) {
return this + b
};
Number.prototype.sub = function (b) {
return this - b
};
Number.prototype.mult = function (b) {
return this * b
};
Number.prototype.div = function (b) {
return this / b
};
Array.prototype.add = function (b) {
return this.map(function (e, i, a) {
return e + b[i]
})
};
Array.prototype.sub = function (b) {
return this.map(function (e, i, a) {
return e - b[i]
})
};
Array.prototype.sqrt = function () {
return this.map(function (e, i, a) {
return Math.sqrt(e)
})
};
Array.prototype.mult = function (b) {
if(b.length) return this.map(function (e, i, a) {
return e * b[i]
});
return this.map(function (e, i, a) {
return e * b
})
};
Array.prototype.div = function (b) {
if(b.length) return this.map(function (e, i, a) {
return e / b[i]
});
return this.map(function (e, i, a) {
return e / b
})
};
var temp = 4;
var lerp = function (d, a, b) {
return((a.sub(b)).mult(d)).add(b)
};
var Vertex = (function () {
function Vertex() {
this.arg = [];
Array.prototype.push.apply(this.arg, arguments);
return this.arg
}
Vertex.prototype.lerpTo = function (d, a) {
return new Vertex(lerp(d, a.x, this.x), lerp(d, a.y, this.y))
};
Array.prototype.mag = function () {
return Math.sqrt((this[0]) * (this[0]) + (this[1]) * (this[1]))
};
Array.prototype.norm = function () {
return this.div(Math.sqrt((this[0]) * (this[0]) + (this[1]) * (this[1])))
};
Array.prototype.dist = function (a) {
return Math.sqrt((this[0] - a[0]) * (this[0] - a[0]) + (this[1] - a[1]) * (this[1] - a[1]))
};
Array.prototype.midpoint = function (a) {
return new Vertex((this[0] + a[0]) / 2.0, (this[1] + a[1]) / 2.0)
};
return Vertex
})();
var Ball = (function () {
function Ball(a, b, c) {
this.pos = a;
this.velocity = b;
this.radius = c;
return this
}
Ball.prototype.step = function (a, b, c) {
this.pos = this.pos.add(this.velocity);
var d = false;
var e = 0;
if(this.pos[0] < b[0]) {
this.velocity[0] -= this.pos.sub(b)[0]*2 ;
e = Math.abs(this.pos.sub(b)[0]);
this.pos[0] = b[0]
}
if(this.pos[0] > c[0]) {
this.velocity[0] -= this.pos.sub(c)[0]*2 ;
d = true;
e = Math.abs(this.pos.sub(c)[0]);
this.pos[0] = c[0]
}
if(this.pos[1] < b[1]) {
this.velocity[1] -= this.pos.sub(b)[1] *2;
d = true;
e = Math.abs(this.pos.sub(b)[1]);
this.pos[1] = b[1]
}
if(this.pos[1] > c[1]) {
this.velocity[1] -= this.pos.sub(c)[1] *2;
d = true;
e = Math.abs(this.pos.sub(c)[1]);
this.pos[1] = c[1]
}
if(!d) {
this.velocity = this.velocity.add(a)
}
if(d) {
this.velocity = this.velocity.mult(0.7)
}
};
Ball.prototype.toString = function () {
return JSON.stringify({
'radius': this.radius,
'pos': [this.pos[0].toFixed(2), this.pos[1].toFixed(2)]
})
};
return Ball
})();
var World = (function () {
function World(a, b, c) {
this.acceleration = a;
this.min = b;
this.max = c;
this.balls = []
}
World.prototype.addBall = function (x, y, a, b, r) {
this.balls.push(new Ball(new Vertex(x, y), new Vertex(a, b), r))
};
World.prototype.step = function () {
var b = this.acceleration,
min = this.min,
max = this.max,
balls = this.balls;
balls.forEach(function (e, i, a) {
e.step(b, min, max)
});
balls.forEach(function (e, i, a) {
balls.map(movecollisionsapart, balls[i])
})
};
World.prototype.draw = function () {
this.balls.forEach(function (e) {
context.beginPath();
context.arc(e.pos[0], e.pos[1] , e.radius, 0, Math.PI * 2, true);
context.stroke()
})
};
World.prototype.getPoints = function () {
var a = "";
a = this.balls.join(',');
a = "[" + a + "]";
postMessage(a)
};
return World
})();
var w = new World(new Vertex(0, 1), new Vertex(10, 10), new Vertex(450, 450));
for(var i = 0; i < 500; i++) {
w.addBall(450 * Math.random(), 450 * Math.random(), 0, 0, 4)
}
w.timer = setInterval(function () {
w.step()
});
function movecollisionsapart(e) {
if(this !== e && e) {
var a = this.pos.dist(e.pos);
if(a < ((this.radius + e.radius))) {
var b = this.pos.sub(e.pos);
var d = b.norm().mult( ((this.radius + e.radius) - a));
e.velocity = e.velocity.sub(d);
e.pos = e.pos.sub(d);
this.velocity = this.velocity.add(d);
this.pos = this.pos.add(d);
return e
}
}
}
</textarea><button id="reloader" >load</button>
var canvas = document.createElement('canvas');
canvas.width = 500;
canvas.height = 500;
canvas.style.border = "inset";
document.body.appendChild(canvas);
var context = canvas.getContext('2d');
window.requestAnimFrame = (function () {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var blob;
document.getElementById('reloader').onclick = function () {
if (document.worker)
document.worker.terminate();
// usage:
// instead of setInterval(render, 16) ....
blob = new Blob(Array.prototype.map.call(document.querySelectorAll("script[type=\"text\/js-worker\"]"), function (oScript) {
document.querySelectorAll("script[type=\"text\/js-worker\"]").textContent = document.getElementById('workersrc').value;
return document.getElementById('workersrc').value;
}), {
type: "text/javascript"
});
document.worker = new Worker(window.URL.createObjectURL(blob));
document.worker.onmessage = function (datae) {
context.clearRect(0, 0, 500, 500);
//console.log(datae.data);
var data = JSON.parse(datae.data);
data.forEach(function (e) {
context.beginPath();
context.arc(e.pos[0], e.pos[1], e.radius, 0, 2 * Math.PI, false);
context.closePath();
context.stroke();
});
};
var action = "draw";
document.worker.postMessage(action);
(function animloop() {
setTimeout(animloop, 1000 / 30);
repeater();
})();
function repeater() {
var action = "draw";
document.worker.postMessage(action);
}
};
canvas.onclick = function (e) {
var action = new Object();
action.action = "add";
action.x = e.pageX - canvas.offsetLeft;
action.y = e.pageY - canvas.offsetTop;
action.r = 5;
document.worker.postMessage(JSON.stringify(action));
};

webworker with an editable textbox

an experiment I wanted to try to see if i could get the physics to work faster if i used a webworker.. while it works it's not best.

A Pen by Darby Rathbone on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment