html
html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!--
Of course I ignored air resistance for this code.
If it doesn't follow the ball (scroll to the right) automatically, try changing the speed to 20 in the settings and then changing it back to 10 (don't ask why).
-->
<!DOCTYPE html>
<html>
<head>
<title>Ball throw simulation</title>
</head>
<body>
<div id="ground"></div>
<div id="aim_line"></div>
<div id="ball"></div>
<div id="angle_div">30°</div>
<div id="aim_btn" onclick="start_aiming()">Click here to start aiming.</div>
<div id="settings_div">
<h1 align="center">Settings</h1>
<p>
initial speed of the ball: <input id="speed_input" value="10" placeholder="10" type="number" onchange="change_speed()"> m/s
<br><br>
gravitational acceleration: <input id="gravity_input" value="9.81" placeholder="9.81" type="number" onchange="change_gravity()"> m/s²
<br><br>
interval: <input id="interval_time_input" value="20" placeholder="20" type="number" onchange="change_interval_time()"> milliseconds<br>
A smaller number will make the animation smoother and the simulation more exact but can also make the code run more slowly.
</p>
</div>
<div id="settings_btn" onclick="settings()">
Enter to Rename, Shift+Enter to Preview
css
css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
body {
margin:0;
background: #ddf;
user-select:none;
font-family:arial;
}
div, div2 {
position:absolute;
}
/*I use div2 for the gear and house symbol because their position mustn't be set to "fixed" when the settings are opened (see JS lines 153 and 135)*/
#ground {
bottom:0;
background: green;
}
#ball {
border-radius:50%;
background: blue;
transform:translate3d(-50%, 50%, 0);
}
.meter_mark {
background: black;
transform:translateX(-50%);
}
.meter_mark div {
top:100%;
left:50%;
transform:translateX(-50%);
}
Enter to Rename, Shift+Enter to Preview
js
js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
const window_size = [window.innerWidth, window.innerHeight];
const meter = Math.min(...window_size)*0.2;
const meter_mark_0 = 0.3;
const ball_radius = 0.15;
const ball_original_position = [meter_mark_0, 0.5+ball_radius];
var ball_position;
var interval_time = 0.02; //seconds
var ball_speed = 10; //m/s
var g = 9.81; //m/s²
var ball_velocity = [];
var interval;
var aiming = false;
var simulating_throw = false;
var throwing_angle;
var pc;
var first_throw = true;
window.onload = function() {
ball.style.width = ball.style.height = 2*ball_radius*meter+"px";
ground.style.height = 0.5*meter+"px";
ball.style.bottom = ball_original_position[1]*meter+"px"
ball.style.left = angle_div.style.left = ball_original_position[0]*meter+"px";
angle_div.style.bottom = 1.6*meter+"px";
change_ground_width();
aim_line.style.height = 1*meter+"px";
aim_line.style.width = 0.02*meter+"px";
aim_line.style.left = (ball_original_position[0]-0.01)*meter+"px";
aim_line.style.bottom = ball_original_position[1]*meter+"px";
};
Enter to Rename, Shift+Enter to Preview
BROWSER
Console
Run