Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

use-spring-transition

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

use-spring-transition

Hooks for spring transition

  • 0.1.5
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
13
decreased by-40.91%
Maintainers
1
Weekly downloads
 
Created
Source

use-spring-transition

NPM version Package size typescript NPM license NPM total downloads NPM monthly downloads

Collection of basic hooks to perform css transitions and spring animation in React

At this moment library exports 2 hooks:

  • useSpringTransition - a hook for simple open/close transition (same as Transition/CSSTransition components from react-transition-group)
  • useSpringTransitions - a hook for value transition (same as TransitionGroup component from react-transition-group)

Demo

Basics

use-spring-transition use same stage model as react-transition-group - open, opening, opened, close, closing, closed.

  • open - when open transition stat. At this moment you want to set your element initial style before css transition applied.
  • opening - when transition in process. At this moment you want to set your element target style.
  • opened - when transition is end. At this moment you want to set your element opened styles.
  • close - same as open but for close transition.
  • closing - same as opening but for close transition.
  • closed - same as opened but for close transition. At this moment you want to unmount/hide your element.

Looks pretty similar with react-transition-group, but with different naming (enter -> open, enter-active -> opening, enter-done -> opened). But instead of react-transition-group stages in use-spring-transition don't combine like enter enter-active

Value transition has much more difference with TransitionGroup, mostly it looks like useTransition hook from react-spring

Usage

useSpringTransition as simple css transition

Show menu from opacity (fadeIn/fadeOut):

// Menu.tsx
import cx from 'clsx';
import { useSpringTransition } from 'use-spring-transition';
import styles from './Menu.module.css';

const Menu = () => {
  const [opened, setOpened] = useState(false);
  const transition = useSpringTransition(
    opened,
    500,
  );

  if (transition.stage === 'closed') {
    return null;
  }

  return (
    <div
      className={cx(
        styles.menu,
        styles[transition.stage],
      )}
    >
      Menu
    </div>
  );
};
/* Menu.module.css */
.menu {
  height: 500px;
  width: 500px;
  transition: opacity 500ms ease-in-out;
}

.menu.closing,
.menu.open {
  opacity: 0;
}

useSpringTransitions as simple css transition

Switch image with translate (slideIn/slideOut):

// Viewer.tsx
import cx from 'clsx';
import { useSpringTransitions } from 'use-spring-transition';
import styles from './Viewer.module.css';

const Viewer = ({
  images,
}: {
  images: {
    id: string;
    url: sring;
    alt: string;
  }[];
}) => {
  const [currentIndex, setCurrentIndex] =
    useState(0);
  const transitions = useSpringTransitions(
    images[currentIndex],
    500,
  );

  return (
    <div className={styles.viewer}>
      {transitions.map(
        (transition) =>
          transition.value && (
            <img
              className={cx(
                styles.image,
                styles[transition.stage],
              )}
              key={transition.value.id}
              src={transition.value.url}
              alt={transition.value.alt}
            />
          ),
      )}
    </div>
  );
};
/* Viewer.module.css */
.viewer {
  height: 100%;
  width: 100%;
  position: relative;
}

.image {
  height: 100%;
  width: 100%;
  transition: transform 500ms ease-in-out;
}

.image.close,
.image.closing {
  position: absolute;
  top: 0;
  left: 0;
}

.image.closing {
  transform: translate3d(-100%, 0, 0);
}

.image.open {
  transform: translate3d(100%, 0, 0);
}

useSpringTransition as spring animation

Show menu with height spring animation:

// Menu.tsx
import cx from 'clsx';
import { useSpringTransition } from 'use-spring-transition';
import styles from './Menu.module.css';

const Menu = () => {
  const [opened, setOpened] = useState(false);
  const transition = useSpringTransition(
    opened,
    { mass: 1, stiffness: 80, damping: 20 },
    {
      from: 0,
      to: 500,
    },
  );

  if (transition.stage === 'closed') {
    return null;
  }

  return (
    <div
      className={styles.menu}
      style={{ height: transition.springValue }}
    >
      Menu
    </div>
  );
};
/* Menu.module.css */
.menu {
  width: 500px;
}

useSpringTransitions as spring animation

Switch image with spring translate (slideIn/slideOut):

// Viewer.tsx
import cx from 'clsx';
import { useSpringTransitions } from 'use-spring-transition';
import styles from './Viewer.module.css';

const Viewer = ({
  images,
}: {
  images: {
    id: string;
    url: sring;
    alt: string;
  }[];
}) => {
  const [currentIndex, setCurrentIndex] =
    useState(0);
  const transitions = useSpringTransitions(
    images[currentIndex],
    { mass: 1, stiffness: 180, damping: 30 },
    { from: 100, to: { open: 0, close: -100 } },
  );

  return (
    <div className={styles.viewer}>
      {transitions.map(
        (transition) =>
          transition.value && (
            <img
              className={cx(
                styles.image,
                styles[transition.stage],
              )}
              style={{
                transform: `translate3d(${transition.springValue}px, 0, 0)`,
              }}
              key={transition.value.id}
              src={transition.value.url}
              alt={transition.value.alt}
            />
          ),
      )}
    </div>
  );
};
/* Viewer.module.css */
.viewer {
  height: 100%;
  width: 100%;
  position: relative;
}

.image {
  height: 100%;
  width: 100%;
}

.image.close,
.image.closing {
  position: absolute;
  top: 0;
  left: 0;
}

API

SpringOptions

type SpringOptions = {
  mass?: number;
  stiffness?: number;
  damping?: number;
  initialVelocity?: number;
  threshold?: number;
};

Defaults:

mass: 1;
stiffness: 100;
damping: 10;
initialVelocity: 0;
threshold: 0.01;

Description:

  • mass, stiffness, damping, initialVelocity - spring animation configuration
  • threshold - special property for ending a spring animation when spring value difference on each frame lower than threshold 10 times in a row*.

*spring animation can generate a small difference on each frame before reach to value. For example, we want to animate opacity from 0 to 1. Spring animation can generate 0.991233, 0.992533, 0.993334... in a near minute before reach 1 (or never reach at all). To avoid this long useless animation we can finish animation when spring value is near the to value. That's why we use threshold property.

Stage

type Stage =
  | 'open'
  | 'opening'
  | 'opened'
  | 'close'
  | 'closing'
  | 'closed';

Values

type Values = {
  from: number;
  to: number | { open: number; close: number };
};

Options

type Options =
  | SpringOptions
  | number
  | {
      close: SpringOptions | number;
      open: SpringOptions | number;
    };

useSpringTransition

const useSpringTransition = (
    opened: boolean,
    options: Options = {},
    values: Values = { from: 0, to: 1},
): { stage: Stage; springValue: number; }

Params:

  • opened: boolean - trigger for transition
  • values: Values | null - values for spring animation. You can use { from: number; openingTo: number; closingTo: number } for different target animated values for open and close. If you use null or omit this param, default values { from: 0, to: 1} will be used.
  • options: Options - configuration for spring animation. You can use { close: SpringOptions | number; open: SpringOptions | number } for different animation timings for open and close. If yse use number as options a simple css transition will be happened via timeout. If you omit this param, default options {} will be used (SpringOptions defaults).

Returns:

  • transition: { stage: Stage; springValue: number; } - transition object with stage of transition and spring value; you should use springValue as animated style property

useSpringTransitions

const useSpringTransitions = <T>(
    value: T,
    options: Options = {},
    values: Values = { from: 0, to: 1},
): { value: T; stage: Stage, springValue: number; }[]

Params:

  • opened: boolean - trigger for transition
  • { from, openingTo, closingTo }: { from: number; openingTo: number; closingTo: number } - values for spring animation
  • options: SpringOptions - configuration for spring animation

Returns:

  • transitions: { value: T; stage: Stage, springValue: number; }[] - array of transitions (values); you should map this array in your component; you should use springValue as animated style property

Keywords

FAQs

Package last updated on 07 Apr 2023

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc