Moving a Bouncing Ball on Canvas: A JavaScript Experiment with Variable Gravity and Restitution

プログラミング・Web開発カテゴリを表すパンダのイラスト Programming / Web Development

About this article
This article was created using an automated generation workflow powered by generative AI.
Based on primary documentation from MDN regarding Canvas animation, requestAnimationFrame, and reduced motion, we developed a JavaScript educational tool that alters gravity and the restitution coefficient.

Verification Status: 📘 Official Information, V8 Syntax, and Numerical Calculations Verified / Browser Hardware Unverified
On October 31, 2026, three Daily Code files were saved to and reloaded from GitHub, and the conditions for falling, collision, repulsion, and resting on the floor were tested. GitHub Pages reachability, WordPress blue callout boxes, and actual mobile or print/PDF rendering remain unverified.

Dropping a ball and watching it bounce makes the practical application ofvelocity, position, and accelerationin JavaScript visually intuitive. This learning material allows you to compare the effects of varying gravity versus varying the coefficient of restitution one by one.

What You Can Do This Time

ItemCondition
SupportCanvas 2D and JavaScript-compatible browsers (hardware not verified)
TechnologyCanvas API / requestAnimationFrame
CostNo external libraries, paid APIs, or login required
NetworkPage load only. No external transmission of operation results
OperationPlay, stop, step forward 0.2 seconds, reset, slider
DataFictional ball. No personal information or location data

Try it first: Make the ball bounce

🔷 Experience with just three operations
🏀 Open Canvas Bounce Demo (Public, browser behavior unverified)
📘 Completed HTML, JavaScript, and README

  1. Press "Play" and observe if the ball falls and bounces.
  2. Change the "coefficient of restitution" from 0.80 to 0.45.
  3. "Reset" and run it again from the same height.

🟦 Look here after operation
Also check the "Height from floor (px)" and "Collision count" below the rendering area. If the motion is difficult to see, use "Step forward 0.2s" to track changes frame by frame.

ConditionExpected change
Coefficient of restitution 0.80Bounces high
Coefficient of restitution 0.45Bounces low
Gravity 600 -> 1000 px/s²Reaches the floor sooner
PausePreserve position and count
Advance by 0.2 secondsAdvance calculations and display stationary state

These are expected results anticipated from the code, not measured results from an actual browser. Reset using "Reset" each time you compare to align the initial conditions.

Why does a ball bounce?

The Canvas is an area for drawing circles and lines. Movement is visible because JavaScript updates the current position of the ball and redraws it repeatedly. The material used here is a simplified physical model using pixels within the screen.

Letting vertical velocity be vy, position y, acceleration g, and elapsed seconds dt, the core process is as follows.

vy = vy + g * dt;          // 速度を更新する
y = y + vy * dt;          // 位置を更新する
if (y >= floor - radius) {
  y = floor - radius;     // 床の位置に戻す
  vy = -vy * restitution; // 反対方向へ跳ねる
}

This code is an excerpt illustrating the concept and is not a standalone executable complete version.The main JavaScript of Daily Code includes processing to prevent the collision count from increasing after the ball comes to rest on the floor, stopping the timer, and handling reduced motion settings.

flowchart LR
  A["再生・コマ送り"] --> B["速度・位置の更新"]
  B --> C{"床に接した?"}
  C -->|はい| D["反発係数で速度を反転"]
  C -->|いいえ| E["その位置を使用"]
  D --> F["Canvasに再描画"]
  E --> F
  F --> G["高さ・衝突回数を更新"]

requestAnimationFrame in the browser is an API that requests processing to be called before the next redraw. The elapsed time from the previous frame is used to prevent unnatural speeds on high refresh rate displays. When the screen is hidden, playback is stopped, and sudden movement caused by large elapsed time intervals is also suppressed.

Change one thing and compare

Fix the restitution coefficient at 0.80 andchange only the gravity settingfrom 600 px/s² to 1000 px/s². Always click "Reset" to align the initial conditions.

ComparisonGravityExpected Result
Before Change600 px/s²Standard fall speed
After Change1000 px/s²Reaches the floor faster

The only change made here is gravity. If you change the coefficient of restitution at the same time, it becomes difficult to determine which factor caused the difference.

px/s² is an instructional unit using pixel coordinates within the Canvas. It does not directly represent Earth's gravitational acceleration and cannot be used for safety calculations of real-world materials or machinery.

Respect motion reduction settings as well

⚠️ If you have difficulty with continuous animations
When the OS or browser motion reduction setting (prefers-reduced-motion: reduce) is enabled, continuous playback is disabled. You can observe still images one by one using "Step forward 0.2s". Playback does not start simply by opening the page.

Normal mode can also be interrupted with the "Stop" button, and playback stops when switching to another tab. On smartphones, since the internal Canvas coordinates of 720×360 are scaled down via CSS, the px values at the bottom of the screen do not match the physical pixel count of the display.

Run on your own PC

HTMLandJavaScriptin the same folder, then open the HTML file in your browser. If necessary, start a local server with the following command and access localhost.

python3 -m http.server 8000 --bind 127.0.0.1

The URL to open is http://127.0.0.1:8000/. If the Python Launcher is available on Windows, you can also run it with py -3 -m http.server 8000 –bind 127.0.0.1. Press Ctrl+C to exit.

Troubleshooting

SymptomCheck
Stuck in loading stateapp.js placement and Console errors
Ball does not movePlayback controls and reduced motion settings
Collisions do not increaseDid you advance until it reached the floor?
Unstable comparisonDid you reset to match initial conditions?
Appears smallDifference between Canvas internal coordinates and CSS display width

How to use in work and study?

It can be applied as a foundation for games, educational materials, and UIs showing state changes. However, just because the bounce looks correct does not mean real-world physical phenomena have been verified. Practical calculations require comparison with measured values, unit conversion, boundary conditions, and error evaluation.

Comparing position and velocity at the exact moment of floor contact

At the moment the ball touches the floor, not only the bounce velocity but also the process of resetting its position so it does not extend beyond the floor is critical. Since a ball moving toward the floor at the bottom of the screen is a circle, setting its center coordinate equal to the floor height causes its lower half to sink into the floor. The center position must be placed at a location equal to the floor height minus the radius. If only the position is corrected while leaving the downward velocity unchanged, it will attempt to enter the floor again in the next update. Conversely, if the velocity is inverted without correcting the position, it may appear to bounce from beneath the floor. This is why the excerpted code in the article performs both processes.

The coefficient of restitution is an instructional value that represents how much of the velocity immediately before collision is retained after collision. A value of 0.80 leaves a relatively large velocity, while 0.45 leaves a smaller one. Just because the coefficient of restitution is halved does not mean the rebound height is simply halved. Height is also affected by velocity, acceleration, and elapsed time. Observe the difference when dropping from the same height, fixing gravity, and changing only the coefficient. If you do not reset before comparison, the previous velocity may remain, making the results unreadable.

It can be expected that increasing gravity shortens the time to the floor. However, if the coefficient of restitution is also changed, it becomes unclear which setting caused the difference in bouncing behavior. In the article comparison table, the coefficient of restitution is fixed at 0.80 when changing gravity from 600 to 1000. At this time, focus on how the velocity increases during the fall and avoid making the number of collisions the sole success condition. In the next experiment, return gravity to 600 and lower only the coefficient of restitution to 0.45. Separating the two experiments makes it easier to understand the differences in acceleration changes and energy loss during collisions.

Observing the progression of time

Screen movement appears continuous, but the program updates velocity and position at short time intervals. If dt, which represents elapsed time, is not taken into account, differences in the terminal rendering frequency may alter the apparent speed. If you switch tabs and a long time passes, and upon returning the ball suddenly moves as if piercing through the floor, it may be the effect of calculating a long duration all at once. This educational material incorporates concepts to suppress such effects, but the same results have not been empirically verified in all environments.

In the operation to advance by 0.2 seconds, instead of viewing continuous screens, you can observe the results of advancing a short time as a still image. If the ball has not yet reached the floor, it is normal for the collision count not to increase. If the collision count continues to increase after contacting the floor, it is necessary to check whether the stationary state is being counted as a new collision each time. Observing the height from the floor alongside numerical values makes it easier to understand the state. Forcing a velocity onto a stationary ball is also different from stopping as a result of calculation.

The px/s² in this educational material is the acceleration set within the Canvas coordinates. It is not a measured value of real-world gravity or machine material properties. While it can be applied to UI for games and educational materials, it cannot be used in calculations to evaluate the safety of real equipment. Users who struggle with motion can observe the same conditions using step-by-step playback and status displays instead of continuous playback. Ensuring that critical information is not confined solely to screen colors and motion is also an important perspective when applying this to practical work.

Official Information and References

Official documentation review date: October 31, 2026. GitHub source read-back, V8 syntax, and calculation checks were performed, but Pages publication, actual browser operation, and WordPress blue box displays remain unverified.

GitHub Sample

Document information

Article title
Moving a Bouncing Ball on Canvas: A JavaScript Experiment with Variable Gravity and Restitution
Published
Updated
Source
https://papanda925.com/?p=18448&lang=en

License: Text and original figures for which this site holds the relevant rights are available under CC BY 4.0 , unless otherwise noted. This article may include content created or edited with generative AI. If code has a separate license notice or a linked GitHub repository license, that license takes precedence for the code. Quotations, third-party materials, images, and trademarks are excluded from this license. Usage policy

Copied title and URL