npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rk-4th-spring

v0.1.1

Published

A spring physics engine for animations

Downloads

215

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 is 1.
    • tension (number): Stiffness of the spring. Default is 170.
    • friction (number | null): Damping coefficient. If null, it's calculated as critical damping. Default is null.
    • precision (number): Energy threshold for stopping the animation. Default is 0.01.
    • initialValue (number): Initial position of the spring. Default is 0.
    • velocity (number): Initial velocity. Default is 0.
    • targetValue (number): Target position to animate towards. Default is 0.
    • 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 animations
  • wobbly: Bouncy, playful animations
  • stiff: Quick, responsive animations
  • slow: Gradual, controlled animations
  • molasses: Heavy, slow-moving animations
  • avati: 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

  1. Adjust Mass: Higher mass values create heavier-feeling animations
  2. Tune Tension: Higher tension values make the spring stiffer and faster
  3. Control Friction: Higher friction values reduce oscillation
  4. Use Precision: Adjust the precision value to control when animations stop
  5. 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.