Last active
November 6, 2022 07:34
-
-
Save gordonbrander/8766f52dd13cc3cff4a3 to your computer and use it in GitHub Desktop.
boing.js (second pass)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Create a spring object. | |
| export const Spring = (curr, prev, dest, stiffness, damping) => ({ | |
| curr, // The current position of spring | |
| prev, // The position of spring at previous tick | |
| dest, // The destination of spring | |
| stiffness, // How hard it springs back | |
| damping, // Friction. 1.0 means no bounce. | |
| }); | |
| // Given numbers, calculate the next position for a spring. | |
| Spring.next = (curr, prev, dest, stiffness, damping) => { | |
| // Calculate spring force | |
| const fspring = -stiffness * (curr - dest); | |
| // Calculate velocity | |
| const vel = curr - prev; | |
| // Calculate damping force. | |
| const fdamping = -damping * vel; | |
| // Calc acceleration by adjusting spring force to damping force | |
| const acc = fspring + fdamping; | |
| // Calculate new velocity after adding acceleration. Scale to framerate. | |
| const nextv = (vel + acc); | |
| // Calculate next position by integrating velocity. Scale to framerate. | |
| const next = (curr + nextv); | |
| return next; | |
| } | |
| // Some arbitrarily small positive number used as threshold value. | |
| const epsilon = 0.001; | |
| // Given numbers, calcluate if a spring is at rest. | |
| Spring.isResting = (curr, prev, dest) => | |
| Math.abs(curr - prev) < epsilon && Math.abs(curr - dest) < epsilon; | |
| // Create a new spring at location. | |
| Spring.at = (pos, stiffness, damping) => | |
| Spring(pos, pos, pos, stiffness, damping); | |
| // Copy a spring | |
| Spring.copy = (spring) => Spring( | |
| spring.curr, spring.prev, spring.dest, | |
| spring.stiffness, spring.damping | |
| ); | |
| // Set coords on a spring, mutating spring | |
| Spring.coords = (spring, curr, prev, dest) => { | |
| spring.curr = curr; | |
| spring.prev = prev; | |
| spring.dest = dest; | |
| return spring; | |
| } | |
| // Set the destination of spring A to the current location of spring B. | |
| Spring.connect = (a, b) => | |
| Spring.coords(a, a.curr, a.prev, b.curr); | |
| Spring.animate = (spring) => | |
| !Spring.isResting(spring.curr, spring.prev, spring.dest) ? | |
| Spring.coords( | |
| spring, | |
| Spring.next( | |
| spring.curr, spring.prev, spring.dest, | |
| spring.stiffness, spring.damping), | |
| spring.curr, spring.dest) : | |
| Spring.coords(spring, spring.dest, spring.dest, spring.dest); | |
| Spring.animate2d = (spring) => | |
| (!Spring.isResting(spring.curr[0], spring.prev[0], spring.dest[0]) || | |
| !Spring.isResting(spring.curr[1], spring.prev[1], spring.dest[1])) ? | |
| Spring.coords( | |
| spring, | |
| [Spring.next( | |
| spring.curr[0], spring.prev[0], spring.dest[0], | |
| spring.stiffness, spring.damping), | |
| Spring.next( | |
| spring.curr[1], spring.prev[1], spring.dest[1], | |
| spring.stiffness, spring.damping)], | |
| spring.curr, spring.dest) : | |
| Spring.coords(spring, spring.dest, spring.dest, spring.dest); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment