Calculator of PI
by maxell4o
HTML
<axis>
<collisions>Click on Document to RUN</collisions>
</axis>
CSS
body {
margin: 0;
}
axis {
display: flex;
align-items: flex-end;
height: 250px;
box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.2);
}
collisions {
display: inline-block;
position: absolute;
top: 10px;
font-size: 18px;
left: 10px;
}
collisions.done {
color: green;
}
block {
display: flex;
background: #ccc;
border: 2px #999 solid;
box-sizing: border-box;
align-items: center;
justify-content: center;
font-size: 14px;
color: #333;
position: absolute;
}
JavaScript
// You can define number of digits that will be generated
// At the last line in CalculatePi constructor param
// The Animation will stop 1 second after complete
class Block {
constructor(x, w, v, m) {
this.x = x;
this.w = w;
this.v = v;
this.m = m;
this.el = null;
this.display();
}
display() {
let block = document.createElement('block');
block.style.left = `${Math.floor(this.x)}px`;
block.style.width = `${this.w}px`;
block.style.height = `${this.w}px`;
block.innerText = `${this.m.toLocaleString()} kg`;
this.el = block;
document.querySelector('axis').append(block);
}
update() {
this.x += this.v;
}
updateView() {
this.el.style.left = `${this.x}px`;
}
collide(b) {
return !(this.x + this.w < b.x);
}
bounce(b) {
return (this.m - b.m) / (this.m + b.m) * this.v +
(2 * b.m / (this.m + b.m)) * b.v;
}
wall() {
return this.x <= 0;
}
reverse() {
this.v = this.v * -1;
}
}
class CalculatePI {
constructor(digits = 1) {
this.steps = Math.pow(10, Math.floor(digits) - 1);
this.b1 = new Block(50, 50, 0, 1);
this.b2 = new Block(150, 160, -1 / this.steps, Math.pow(100, Math.floor(digits) - 1));
this.animation = null;
this.collisions = 0;
this.collisionsRef = document.querySelector('collisions');
document.addEventListener('click', this.run.bind(this));
}
run(e) {
if (this.animation && e && e.type == 'click') {
window.cancelAnimationFrame(this.animation);
this.animation = null;
} else {
for (let i = 0; i < this.steps; i++) {
this.render();
}
this.updateView();
this.b1.updateView();
this.b2.updateView();
if (this.b1.v >= 0 && this.b2.v >= 0 && this.b1.v < this.b2.v) {
this.collisionsRef.className = 'done';
setTimeout(() => {
window.cancelAnimationFrame(this.animation);
}, 1000)
}
this.animation =...