Projectile motion simulator + lesson template
Summary:
Over the course of the last 3-4 days, I created a projectile motion simulation where the user can control speed and angle of the projectile. The code uses real kinematic equations to solve for the new position of the projectile given time. This then maps to a mapCanvas(t) function that allows the equations to give the coordinates for a working website and canvas HTML element. Finally, I created a drawFrame() function to actually paint the simulation so that it looks like the projectile is consistently moving to human eyes.
Intro to Challenges:
There were many bugs along the way. This included learning curves such as learning the requestAnimationFrame() function, making sliders, and even writing some part of CSS !
Oct 18, 2026 - Day 13,
1. One important concept is that the canvas starts (0,0) from the top left corner of the grid, so subtracting y actually makes an object/line move upward.
2. I learned to use the function beginPath() to create a new drawing object. Without using beginPath(), an drawing connects a the previous drawing to the new drawing with a line. Additionally, the fill() function needs to be used to actually draw a point.
3. I learned that css uses different punctuation for different rules:
selector (plain word) - looks for elements with tag
.selector - looks for elements whose classes list contains the word
#selector - looks for the element with the ID
:selector - does the css action only while it is in the state
4. You can test with console.log. To open it on a website/app screen, you can use CMD+OPT+J
Oct 19, 2026 - Day 14,
- In javaScript, when a function is called with parentheses: drawFrame(), it runs immediately. When a function is just called by its name, it runs when another function tells it to: requestAnimationFrame(drawFrame) (no parentheses)!
2. I forgot to use the fill() function again. fill() is important because it actually “paints” the drawing.
Oct 20, 2026 - Day 15,
- I got confused that y increases to make a drawing go downwards. This caused me to write the falling logic incorrectly. I switched the case where falling = true with falling = false.
- After making the falling variable, I wasn’t using it in any way. The falling variable also needed to be used in the eventHandler for the launch button to make sure that multiple cycles of drawFrame() weren’t running at the same time:
a. When drawFrame() is run several times, it causes the speed to increase by n times as much if n represents the number of times you click the launch button
To fix this, I used the falling variable in the EventHandler. I decided that it is easier to just not do anything if the button is in mid-flight and the user wants to re-launch the ball/projectile.
Oct 21, 2026 - Day 16,
- Sliders are There are two events possible to use in an event listener (of a slider):
a. “input” - a live update. The event triggers continously while a slider is being dragged
b. “change” - only triggers and runs the event listener when you let go of the element (slider). This prevents changing while you are holding the slider - Sliders don’t have a closing tag. They don’t have . This means that textContent can’t be used on sliders because they are not containers. Therfore, there has to be a new variable to act as the label for the slider element (or any input element for that matter)
- Span is inline, div begins on the next line
- Inner workings of requestAnimationFrame() - when this function is called, it let’s the function end and immediately return to where it was called. It then continues until it reaches the end of the code in the file. The requestAnimationFrame() just tells the compiler to call the function again AFTER everything ran. This was important because it was the reason the disabling of the sliders was not working.