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

use-spring-effect

v0.1.2

Published

React hooks for spring-animated side effects

Downloads

18

Readme

useSpringEffect

React hooks for spring-animated side effects.

npm install use-spring-effect

Spring dynamics are a great alternative to the traditional duration/easing model of UI animation. There are lots of good alternatives out there, like react-motion, react-spring or animated. Most of these, however, rely on React state. Running animations through state in React can sometimes come at a significant performance cost, as React desperately attempts to evaluate huge subtrees 60 times per second.

use-spring-effect attempts to solve this problem by exposing a spring as a side effect rather than through state. If this makes you uncomfortable there is also a stateful useSpring included.

If you're not sure what spring animation is, Cheng Lou has an excellent talk about it.

TDLR usage

// Animate scroll position
import useSpringEffect from 'use-spring-effect';

const Component = () => {
  const [transitionTo] = useSpringEffect(0, value => {
    document.scrollingElement.scrollTop = value;
  });

  return <button onClick={() => transitionTo(1000)}>Scroll!</button>;
};
// Animate the transform property of .box
import { useSpringStyle } from 'use-spring-effect';

const Component = () => {
  const [ref, transitionTo] = useSpringStyle(0, value => ({
    transform: `translateX(${value}px)`
  }));

  return (
    <div>
      <div className="box" ref={ref} />
      <button onClick={() => transitionTo(100)}>Move!</button>
    </div>
  );
};

API

useSpringEffect

import useSpringEffect from 'use-spring-effect';
const [transitionTo, setValue] = useSpringEffect();
function useSpringEffect(
  initialValue: number,
  onUpdate: (value: number) => void,
  configOrDependencies?: SpringConfig | any[],
  dependencies?: any[]
): ((value: number) => void)[];

See usage example above. The third argument can be either a dependency array or a SpringConfig (see below). When transitionTo is called with a value, the spring will start animating towards that value. setValue sets the value immediately, without animation.

useSpringStyle

import { useSpringStyle } from 'use-spring-effect';
const [ref, transitionTo, setValue] = useSpringStyle();
function useSpringStyle(
  initialValue: number,
  getStyle: (value: number) => InlineStyle,
  configOrDependencies?: SpringConfig | any[],
  dependencies = []
): [React.Dispatch<any>, UpdateSpring, UpdateSpring];

type UpdateSpring = (
  value: number | ((element: HTMLElement) => number)
) => void;

See usage example above. This hook returns a ref that needs to be connected to the element you want to apply animation to. While animating the hook will apply the inline styles to the ref. The second argument to useSpringStyle is a function that is called with the current spring value and should return an object of inline styles. transitionTo and setValue take a number or a function. In case of a function, it will be called with the animated element (example below).

import { useSpringStyle } from 'use-spring-effect';

const Component = () => {
  const [ref, transitionTo] = useSpringStyle(0, value => ({
    transform: `translateX(${value}px)`
  }));

  return (
    <div>
      <div className="box" ref={ref} />
      <button onClick={() => transitionTo(element => element.offsetWidth)}>
        Move!
      </button>
    </div>
  );
};

useMultiSpringEffect

import { useMultiSpringEffect } from 'use-spring-effect';
const [transitionTo, setValue] = useMultiSpringEffect();
function useMultiSpringEffect(
  initialValue: NumberDict,
  onUpdate: (value: NumberDict) => void,
  configOrDependencies?: SpringConfig | any[],
  dependencies?: any[]
): ((value: NumberDict) => void)[];

type NumberDict = { [key: string]: number };

This hook works the same way as useSpringEffect except for the fact that it can animate multiple values at the same time. This is useful for stuff like tracking the mouse position or other things that depend on two or more values. You can't add other properties to the object other than those specified in initialValue (but you don't need to update all of the properties at the same time)

Example (moves .box when the mouse is moved over the outer div):

import { useMultiSpringEffect } from '../../source/index';

const Component = () => {
  const [el, setEl] = React.useState();
  const [transitionTo] = useMultiSpringEffect(
    { x: 0, y: 0 },
    ({ x, y }) => {
      if (el) el.style.transform = `translate(${x}px, ${y}px)`;
    },
    [el]
  );
  const onMouseMove = e => {
    transitionTo({
      x: e.clientX,
      y: e.clientY
    });
  };

  return (
    <div onMouseMove={onMouseMove}>
      <div className="box" ref={setEl} />
    </div>
  );
};

useSpring

import { useSpring } from 'use-spring-effect';
const [value, transitionTo, setValue] = useSpring();
function useSpring(
  initialValue: number,
  configOrDependencies?: SpringConfig | any[],
  dependencies?: any[]
): [number, (v: number) => void, (v: number) => void] {

This hook returns an animated value. Otherwise this hook works like useSpringEffect.

SpringConfig

type SpringConfig = {
  stiffness?: number;
  damping?: number;
  precision?: number;
};

stiffness: number = 200

Stiffness controls how "fast" your animation will be. Higher values result in faster motion.

damping: number = 10

Damping controls how much friction is applied to the spring. You can think about this as how "wobbly" the resulting motion is. Lower values result in more wobbly-ness.

precision: number = 100

Used to determine when to stop animating. With a precision of 0 the spring will reach its end value immediately. With really high values it might keep animating fractions of a pixel for a long time. Tweak this value if animations end abruptly or linger for too long. When tweaking this value you'll want to make big changes in order to see an effect (like adding/removing zeros).