<p>collisions: 0</p>
<button onclick="m2 = 1;draw();">1 kg</button>
<button onclick="m2 = 100;draw();">100 kg</button>
<button onclick="m2 = 10000;draw();">10.000 kg</button>
<button onclick="m2 = 1000000;draw();">1.000.000 kg</button><br>
<canvas id="canvas" width="700" height="350"></canvas>
<span class="reload" onclick="draw()">Reload?</span>
<p class="p2">Imagine a frictionless ground where square b (blue) slides into square a (white) without energy loss. The amount of collisions of the white square will equal the digits of pi. The estimation will become more and more accurate if the mass of square b increases.</p>
html {
background-color: #000111;
}
body {
margin: 50px;
padding: 0px;
font-family: 'Roboto', sans-serif;
}
canvas {
box-shadow: 0px 0 200px -50px #fff;
border-radius: 1em;
border-bottom-left-radius: 0;
width: 40%;
min-width: 300px;
}
p {
font-size: calc(3vh + 0.5em);
margin: 0;
margin-bottom: 0.5em;
color: white;
display: inline-block;
vertical-align: middle
}
.p2 {
position: relative;
top: 50%;
margin-left: 2em;
vertical-align: top;
width: 40%;
}
button {
background: white;
border: none;
border-radius: 1em;
padding: 2em;
padding-top: 0.75em;
padding-bottom: 0.75em;
margin-left: 2em;
position: relative;
bottom: 0.5em;
display: inline-block;
cursor: pointer;
outline: none;
}
@media screen and (max-width: 900px) {
canvas {
width: 100%;
}
p {
display: block;
}
.p2 {
margin-left: 0;
width: 100%;
margin-top: 0.2em;
}
button {
margin: 0.5em;
}
}
.reload {
position: absolute;
color: black;
padding: 1em;
border-radius: 0.5em;
background: #49fb35;
cursor: pointer;
pointer-events: none;
opacity: 0;
transition: opacity 200ms ease;
transition-delay: 0s;
}
.reload.visible {
pointer-events: all;
opacity: 1;
transition: opacity 500ms ease;
transition-delay: 1s;
}
var canvas = document.getElementById("canvas"),
context = canvas.getContext("2d"),
x, y, m1 = 1,
m2 = 1,
x2, y2, vx, vx2, p = document.querySelector('p'),
html = p.innerHTML.split(' '),
collid = false,
collisions = 0,
w = 80,
w2 = 80,
span = document.querySelector('span');
context.fillStyle = "#000111"; //"#0001";
context.fillRect(0, 0, canvas.width, canvas.height);
function spanOffset() {
var cRect = canvas.getBoundingClientRect();
span.style.left=canvas.offsetWidth/2+cRect.left-span.offsetWidth/2+"px";
span.style.top=canvas.offsetHeight/2+cRect.top-span.offsetHeight/2+"px";
}
spanOffset();
window.addEventListener("resize", function(){
spanOffset();
}, true);
var renderCv = function(width, height, render) {
var buffer = document.createElement('canvas');
buffer.width = width;
buffer.height = height;
render(buffer.getContext('2d'));
return buffer;
};
var square1 = renderCv(w2, w2, function(ctx) {
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#000111";
ctx.font = "17pt sans-serif";
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillText("1 kg", w2 / 2, w2 / 2);
});
var square2;
function draw() {
context.fillStyle = "#000111"; //"#0001";
context.fillRect(0, canvas.height-w, canvas.width, canvas.height);
w = w2-20 + (10 * m2.toString().split('').length*2);
x = 100;
y = canvas.height - w2;
x2 = 350;
y2 = canvas.height - w;
vx = 0;
vx2 = 0.01;
p.style.color="#fff";
p.innerHTML = html[0] + ' ' + 0;
span.classList.remove('visible');
collid = false;
collisions = 0;
square2 = renderCv(w, w, function(ctx) {
ctx.fillStyle = "#a6dbf0";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.fillStyle = "#000111";
ctx.font = "17pt sans-serif";
ctx.textBaseline = 'middle';
ctx.textAlign = 'center';
ctx.fillText(m2.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".") + " kg", w / 2, w / 2);
});
}
function collide(squareA, squareB) {
return !(x + squareA.width < x2 ||
x2 + squareB.width < x);
}
function countUp() {
collisions++;
html = p.innerHTML.split(' ');
var num = collisions.toString();
var num1 = num.split('')[0];
var numx = num.substring(1, num.length);
//console.log(numx)
num = num1;
if (numx) {
num = num1 + '.' + numx;
}
p.innerHTML = html[0] + ' ' + num;
}
function renderFrame() {
x -= vx;
if (x < 0 || x > x2) {
vx = -vx;
x = 0;
countUp();
}
/*if (x2 < square1.width) {
x2 = square1.width;
x2 -= vx2;
} else {
x2 -= vx2;
}*/
x2 -= vx2;
//if( x2 < 0) vx2 = - vx2, countUp();
/*if (~(vx.toFixed(0)+1) == 0 && Math.abs(vx2.toFixed(0)) == 1 && collid == true) {
setTimeout(function() {
draw();
},3000);
}*/
var n = m2;
if (n == 1) {
n = 100;
}
if (Number(p.innerHTML.split(' ')[1].replace('.', '')) == (Math.PI * m2 / Math.sqrt(m2, 2)).toString().split('.')[0]) {
p.style.color="#49fb35";
span.classList.add('visible');
/*setTimeout(function() {
draw();
}, 3000);*/
}
if (collide(square1, square2)) {
var t = vx;
vx = ((m1 - m2) * t + 2 * m2 * vx2) / (m1 + m2);
vx2 = t - vx2 + vx;
countUp();
collid = true;
}
//context.clearRect(0, canvas.height-w, canvas.width, canvas.height);
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(square1, x, y);
context.drawImage(square2, x2, y2);
requestAnimationFrame(renderFrame);
}
draw();
for (var i = 0; i < 100; i++) {
renderFrame();
}
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.