rk-4th-spring
v0.1.1
Published
A spring physics engine for animations
Downloads
215
Maintainers
Readme
Rk4thSpring Animation Library
Overview
The Rk4thSpring
class is a physics-based animation library that simulates a damped harmonic oscillator using the 4th-order Runge-Kutta method. It provides smooth and natural motion, ideal for UI animations, game development, or any application requiring realistic spring dynamics.
Why Runge-Kutta 4th Order Method?
The Runge-Kutta 4th Order (RK4) method is a numerical technique for solving ordinary differential equations (ODEs) with high accuracy. In the context of spring animations, it offers a significant advantage over simpler methods like Euler's method by providing better stability and precision without greatly increasing computational cost. By using RK4, Rk4thSpring
can simulate complex spring dynamics accurately, resulting in smoother and more realistic animations that closely mimic natural motion.
Key Features
- Physics-based spring animations using damped harmonic oscillator equations
- Configurable mass, tension, and friction parameters
- Built-in presets for common animation styles
- Event callbacks for animation lifecycle (start, update, end)
- High precision numerical integration using RK4 method
- Energy-based stopping condition for accurate animation completion
- TypeScript support with full type definitions
Installation
npm install rk4th-spring
import { Rk4thSpring } from 'rk4th-spring';
Basic Usage
// Create a spring with default parameters
const spring = new Rk4thSpring();
// Animate to a target value
spring.start(100, (value) => {
// Update your UI with the current value
element.style.transform = `translateX(${value}px)`;
});
Using Presets
// Create a spring with a preset
const wobblySpring = Rk4thSpring.createWithPreset("wobbly", {
initialValue: 0,
onUpdate: (value) => {
element.style.scale = value;
},
});
// Start animation
wobblySpring.start(1);
Advanced Configuration
const customSpring = new Rk4thSpring({
mass: 1, // Controls the "weight" of the animated object
tension: 170, // Controls the "stiffness" of the spring
friction: 26, // Controls the damping effect
precision: 0.01, // Controls when the animation stops
initialValue: 0, // Starting value
velocity: 0, // Initial velocity
targetValue: 0, // Initial target value
onStart: (value) => console.log("Animation started:", value),
onUpdate: (value) => console.log("Current value:", value),
onEnd: (value) => console.log("Animation completed:", value),
});
Parameters
options
(Optional): An object containing configuration options.mass
(number): Mass of the object attached to the spring. Default is1
.tension
(number): Stiffness of the spring. Default is170
.friction
(number | null): Damping coefficient. Ifnull
, it's calculated as critical damping. Default isnull
.precision
(number): Energy threshold for stopping the animation. Default is0.01
.initialValue
(number): Initial position of the spring. Default is0
.velocity
(number): Initial velocity. Default is0
.targetValue
(number): Target position to animate towards. Default is0
.onStart
(Callback
| null): Function called when the animation starts.onUpdate
(Callback
| null): Function called on each animation frame.onEnd
(Callback
| null): Function called when the animation ends.
Available Presets
gentle
: Smooth, gentle animationswobbly
: Bouncy, playful animationsstiff
: Quick, responsive animationsslow
: Gradual, controlled animationsmolasses
: Heavy, slow-moving animationsavati
: Custom preset with high mass and friction
Practical Example: Animated Button
// Create an interactive button animation
const buttonSpring = Rk4thSpring.createWithPreset("wobbly", {
initialValue: 1,
onUpdate: (value) => {
button.style.transform = `scale(${value})`;
},
});
// Add interaction handlers
button.addEventListener("mousedown", () => {
buttonSpring.start(0.95); // Scale down on press
});
button.addEventListener("mouseup", () => {
buttonSpring.start(1); // Scale back to normal
});
Advanced Example: Chained Animations
const chainedAnimation = new Rk4thSpring({
tension: 180,
friction: 12,
onUpdate: (value) => {
// Animate multiple properties
element.style.transform = `
translateX(${value}px)
scale(${1 + value * 0.001})
`;
element.style.opacity = Math.min(1, value * 0.01);
},
onEnd: () => {
// Start next animation when this one completes
nextAnimation.start();
},
});
Tips for Best Results
- Adjust Mass: Higher mass values create heavier-feeling animations
- Tune Tension: Higher tension values make the spring stiffer and faster
- Control Friction: Higher friction values reduce oscillation
- Use Precision: Adjust the precision value to control when animations stop
- Monitor Performance: Use the built-in callbacks to track animation progress
Technical Details
The Rk4thSpring
class employs the 4th-order Runge-Kutta method for numerical integration, providing high accuracy in simulating spring dynamics.
Equations of Motion
The acceleration a
is calculated using Hooke's law and damping force:
a = \frac{-\text{tension} \times (\text{position} - \text{targetValue}) - \text{friction} \times \text{velocity}}{\text{mass}}
Energy-Based Stopping Condition
Animation stops when total mechanical energy falls below precision
.
Kinetic Energy:
KE = 0.5 \times \text{mass} \times \text{velocity}^2
Potential Energy:
PE = 0.5 \times \text{tension} \times (\text{position} - \text{targetValue})^2
Total Energy:
E_{\text{total}} = KE + PE
Browser Compatibility
Relies on requestAnimationFrame
and performance.now()
. Compatible with modern browsers.
Contributing
Contributions are welcome! Please open issues or submit pull requests on the GitHub repository.
License
This library is licensed under the MIT License.