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

simple-performant-harmonic-oscillator

v4.0.0

Published

A small library that models a harmonic oscillator (a spring) that forgoes flexibility in the name of performance.

Downloads

36

Readme

Simple Performant Harmonic Oscillator (SPHO)

A highly optimized physics spring behavior calculator. This is inspired by Wobble for focusing on just one thing: simulating a damped harmonic oscillator - i.e. a spring. SPHO differs from Wobble in some very key ways though and focuses on performance at the expense of error checking and configurability. Also the API has been changed to be more intuitive (IMHO).

One spring demo - https://omar.dev/simple-performant-harmonic-oscillator/demos/basicSpring.html

Multiple springs demo - https://omar.dev/simple-performant-harmonic-oscillator/demos/multipleSprings.html

API

new Spring(config?: SpringConfig, initialPosition?: InitialPosition)

Initialize a new spring with a given spring configuration. Whenever the from and to values are different the spring will be in motion. This means if the initial values are different the spring will be updating right away. And if there's an update "to" of a spring instance and there's a difference between the current spring value and the new to value the spring will be active.

SpringConfig

These configuration parameters differ from the usual "damping" "frictin" "stiffness" "mass" that you see in other spring libraries. The reason SPHO uses another type of configuration (bounciness and speed) is that I found these a lot more intuitive to understand and work with.

bounciness: number

Determines how "bouncy" the spring is. Where bouncy is how much the spring will overshoot as it tries to get to the target value. The higher the number the more oscillations the spring will experience before settling. The default is 1 which gives a good amount of bounce. A value of 0.75 will give almost no bounce (usually just 1 small one) and 0.5 will give no bounce at all. Real values Between 1 and 2 (i.e. 1.25, 1.5) give good bounciness that is still usable in a regular UI.

speed: number

Defines how "fast" the spring moves. Low values = low speed, and high values = high speed. The default is 1 which is a medium speed. 2 is considered fast and anything above that starts looking silly. For slower speeds 0.5 to 0.75 is a good range. Once you start going below 0.5 that's probably too slow to be useful in most cases.

InitialPosition

fromValue: number

Starting value of the animation. Defaults to 0.

toValue: number

Ending value of the animation. Defaults to 1.

Methods

getCurrentValue(): number

Gets the spring's current value.

setCurrentValue(value: number): void

Sets the spring's current value.

getToValue(): number

Gets the spring's to value that it's trying to reach (or has reached).

setToValue(value: number): void

Sets the spring's to value.

getVelocity(): number

Gets the spring's current velocity.

setVelocity(value: number): void

Sets the spring's velocity

clone(): Spring

Returns a new spring that has the same toValue, and starts the spring at the original spring's current value and velocity. No listeners are transferred over.

setBounciness(bounciness: number): void

Sets the spring's bounciness.

setSpeed(speed: number): void

Sets the spring's speed.

setValueMapper(fn: (value: number) => number): void

When set, makes it so that when onUpdate and onAtRest listeners are called the valueMapper will be called first, and the resulting value will get passed to the listener functions. This does not change the underlying toValue and currentValues at all. This is useful if you want to "normalize" different springs. For example if you have two springs, one will go from 0 to 100, and one will go from 0-255 if you want those springs to complete at the same time, then you can set the from and to value to 0 and 1, and then use the valueMapper to interpolate along those original ranges.

unsetValueMapper(): void

Remove the valueMapper so original behavior is restored.

blockSpringFromResting(): () => void

Block the spring from calling onRest callbacks. Returns a callback that allows onRest callbacks to be called, and if spring is at a rest state then will call those callbacks synchronously.

end(): void

Stops the spring and removes all listeners.

onUpdate(callback: (springValue: number) => void): () => void

Register a callback that will be called each time the spring value is updated. The callback will be called with the new value of the spring. Returns a method, that when invoked will unregister the callback.

onAtRest(callback: (springValue: number) => void): () => void

Register a callback that will be called each time the spring comes to a "resting" position after it has moved. The callback will be called with the toValue of the spring. Returns a method, that when invoked will unregister the callback.

onEnd(callback: () => void): () => void

Register a callback that will be called when the spring has been ended (i.e. .end() was called). Returns a method, that when invoked will unregister the callback.

getLinkedSpring(offset: number, springConfig: SpringConfig): Spring

Returns a new "follow" spring that is "linked" to the spring you called the method on the "anchor" spring. What this means is that the starting point of the follow spring is set to the current value of the anchor spring. Whenever the current position of the anchor spring is updated that will set the toValue of the follow spring. This means that you can't manually set the toValue on the follow spring (the code makes sure this won't happen).

You can have the follow spring come to a different resting state with the "offset". The toValue of the follow spring is anchor spring's current value + offset. By default offset is 0.

By default the follow spring's configuration (bounciness, speed) will match that of the anchor spring. But you can override this behavior by passing in a different SpringConfig.