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

retween

v0.1.2

Published

A functional reimagining of the Shifty interpolation kernel

Downloads

2

Readme

retween

A functional take on the interpolation kernel of Shifty. Ideally something highly-performant that Shifty proper and/or Rekapi could use. Optimized for fast repeated execution of similarly-shaped interpolations. Explicitly not optimized for end-user ease-of-use; it should generally be wrapped with something else.

Functional inspiration taken from Redux.

Design notes

Interpolators

createInterpolator: (state, easing) => interpolator

Creates and returns an interpolator function for a state shaped like state and using the easing functions in easing. The interpolator function has the signature:

interpolator: (fromState, toState, position, outputState = {}) => outputState

fromState and toState must be objects with the same shape as the state argument to createInterpolator, and all values being numbers. position must be a number between 0.0 and 1.0 inclusive. The interpolated result is copied into the object provided in outputState and returned.

Preprocessors

A preprocessor is a function with the following signature:

preprocessor: (inputState, inputEasing) => [outputState, outputEasing, decoder]

inputState is an object with zero or more properties, and inputEasing is an object containing easing functions for properties in inputState. The preprocessor must return an outputState which is "closer" to a state accepted by an interpolator, an outputEasing for the outputState, and a decoder function which will perform a reverse transformation on a state shaped like outputState to produce a state shaped like inputShape. The preprocessor should pass properties it does not deal with through verbatim.

The signature of decoder is:

decoder: (outputState) => inputState

Composing preprocessors

Preprocessors may be composed with the following function:

composePreprocessors: (...preprocessors) => preprocessor

This will compose the preprocessors in the ...preprocessors arguments right-to-left, returning a new preprocessor which performs the composed transformation.

Usage strawman

import { createInterpolator, linear } from 'retween';

const fromState = { x: 1.0, y: 3.0 };
const toState = { x: 4.0, y: 1.0 };
const easing = { x: linear, y: linear };

const interpolator = createInterpolator(toState, easing);

interpolator(fromState, toState, 0.5); // { x: 2.5, y: 2.0 }
// Works for any states shaped like toState:
interpolator({ x: 0, y: 0 }, { x: 1, y: 1 }, 0.25); // { x: 0.25, y: 0.25 }

import { tokenPreprocessor } from 'retween-token-preprocessor';
const customEasing = (pos) -> Math.pow(pos, 2);

const [ tokenState, tokenEasing, tokenDecoder ] =
    tokenPreprocessor({ transform: 'translateX(10px) rotate(10deg)' },
                      { transform: [ linear, customEasing ] });
// tokenState ~= {
//     transform__0: 10,
//     transform__1: 10,
// }
// tokenEasing ~= {
//     transform__0: [Function linear],
//     transform__1: [Function customEasing],
// }

tokenDecoder({ transform__0: 2.3, transform__1: 57 });
    // 'translateX(2.3px) rotate(57deg)'

import { easingFunctions } from 'retween-easing-functions';
import { createEasingPreprocessor } from 'retween-easing-preprocessor';

const easingPreprocessor =
    createEeasingPreprocessor({ ...easingFunctions, customEasing });

const [ easedState, easedEasing, easedDecoder ]
    = easingPreprocessor(fromState, { x: 'customEasing', y: 'easeInOutSine' });
// easedState === fromState
// easedEasing ~= {
//     x: [Function customEasing],
//     y: [Function easeInOutSine],
// }
// easedDecoder === identity

import { composePreprocessors } from 'retween';

const easedTokenPP =
    composePreprocessors(easingPreprocessor, tokenPreprocessor);

const [ easedTokenState, easedTokenEasing, easedTokenDecoder ] =
    easedTokenPP({ transform: 'translateX(10px) rotate(10deg)' },
                 { transform: [ 'linear', 'customEasing' ] });
// easedTokenState ~= {
//     transform__0: 10,
//     transform__1: 10,
// }
// easedTokenEasing ~= {
//     transform__0: [Function linear],
//     transform__1: [Function customEasing],
// }
// easedTokenDecoder === tokenDecoder

License

MIT.