Repository for Ideas & Research
Open Source GIS, Hydrologic Modeling, Optimization

# HTML5

## 1   Canvas animation

Uniqki code
```#regex /^/#html /
<!--
A simulation model of an elastic collision

Author:    Huidae Cho
Copyright: (C) 2017, 2019, Huidae Cho <https://idea.isnew.info>
-->
<table style="border:0px;">
<tr><td>ax:</td><td><input id="ax" oninput="ball.x.acc=parseFloat(this.value)*0.1; reanimate()" /></td><td>ay:</td><td><input id="ay" oninput="ball.y.acc=parseFloat(this.value)*0.1; reanimate()" /></td></tr>
</table>
<canvas id="canvas-bouncing-ball" width="500" height="500"></canvas>
<script>
var canvas = document.getElementById('canvas-bouncing-ball');
var context = canvas.getContext('2d');
var wall = {
mass: 100000
};
var ball = {
density: 1,
mass: 0,
x: {
pos: 0,
vel: 0,
acc: 0.0*9.81,
loss: 1, // loss from impact
loss2: 0.01, // loss in x from y impact
},
y: {
pos: 0,
vel: 0,
acc: 0.1*9.81,
loss: 1, // loss from impact
loss2: 0.01, // loss in y from x impact
}
};
var Draw = {
rectangle: function (x, y, w, h) {
context.beginPath();
context.rect(x, y, w, h);
context.fillStyle = '#8ED6FF';
context.fill();
context.lineWidth = 2;
context.strokeStyle = 'black';
context.stroke();
},
circle: function(x, y, r) {
context.beginPath();
context.arc(x, y, r, 0, 2 * Math.PI, false);
context.fillStyle = 'green';
context.fill();
context.lineWidth = 2;
context.strokeStyle = '#003300';
context.stroke();
}
};

function move(coor1, coor2, min, max) {
var vel1 = coor1.vel + coor1.acc;
if (coor1.pos + vel1 >= min && coor1.pos + vel1 <= max) {
coor1.vel = vel1;
coor1.pos += coor1.vel;
} else {
var wallPos = coor1.pos + vel1 < min ? min : max;
var t = (wallPos - coor1.pos) / vel1; // fraction of time before impact
vel1 = coor1.vel + coor1.acc * t; // partially accelerated

// conservations of momentum and kinetic energy
coor1.vel = (ball.mass - wall.mass) / (ball.mass + wall.mass) * vel1;

// other losses in coor1 from coor1 impact
if (Math.abs(coor1.vel) > coor1.loss)
coor1.vel = Math.sign(coor1.vel) * (Math.abs(coor1.vel) - coor1.loss);
else
coor1.vel = 0;

coor1.pos = wallPos + coor1.vel;

// other losses in coor2 from coor1 impact
if (Math.abs(coor2.vel) > coor2.loss2)
coor2.vel = Math.sign(coor2.vel) * (Math.abs(coor2.vel) - coor2.loss2);
else
coor2.vel = 0;
}
}

function animate() {
if (ball.x.vel == 0 && ball.y.vel == 0) {
ball.radius = Math.random() * ((canvas.width - 6) * 0.1 - 1) + 10;
ball.mass = ball.density * Math.PI * Math.pow(ball.radius, 2);
ball.x.pos = Math.random() * (canvas.width - 2 * ball.radius - 4) + ball.radius + 2;
ball.y.pos = Math.random() * (canvas.height - 2 * ball.radius - 4) + ball.radius + 2;
ball.x.vel = Math.random() * 100 - 50;
ball.y.vel = Math.random() * 100 - 50;
}

context.clearRect(0, 0, canvas.width, canvas.height);
Draw.rectangle(1, 1, canvas.width - 2, canvas.height - 2);

reqID = requestAnimationFrame(animate);

document.getElementById('x').value = ball.x.pos.toFixed(3);
document.getElementById('y').value = ball.y.pos.toFixed(3);
document.getElementById('vx').value = ball.x.vel.toFixed(3);
document.getElementById('vy').value = ball.y.vel.toFixed(3);
}

function reanimate() {
cancelAnimationFrame(reqID);
ball.x.vel = ball.y.vel = 0;
animate();
}

var reqID;
document.getElementById('ax').value = ball.x.acc.toFixed(3)*10;
document.getElementById('ay').value = ball.y.acc.toFixed(3)*10;
animate();
</script>
#noregex /^/```
Uniqki output