JSPM

  • Created
  • Published
  • Downloads 1
  • Score
    100M100P100Q57590F
  • License ISC

A declarative React component for performing simple animations

Package Exports

  • react-declare-animate

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-declare-animate) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

react-declare-animate

A set of declarative components for animating your objects

Description

This is a set of React components which provide the programmer with a way to create simple animations in a declarative manner. It works for both web and React Native. Every animation component wraps its children with a DIV for web, or View for React Native, which can be additionally styled by passing a style parameter.

A simple example:

    <AnimatedPosition top={this.state.top} left={this.state.left} duration={2000} >
        <img src="..." />
    </AnimatedPosition>

Library size when installed: 32K for Web, 44K for React Native.

Table of Contents

Installation

    yarn add react-declare-animate

Details

There are two types of animations: animation actions and animated states.

Animated states

An animated state is a declaration of a child object's props which animate when they are changed. E.g. if you wrap an image in <AnimatedPosition top={10} >, and then change top=10 to top=50, the image will make an animated transition from top=10 to top=50.

AnimatedPosition

    <AnimatedPosition
        ...
        top={currentTop} [in pixels]
        left={currentLeft} [in pixels]
    >

Sets the child at the given coordinates, and when they move, an animated transition will happen between the old and the new value.

AnimatedRotation

    <AnimatedRotation
        ...
        angleX={...} [all angles in radians. One of more axes may be specified]
        angleY={...}
        angleZ={...}
    >

Displays the child rotated by the given angles around the given axis. When any of the angle props change, an animated transition will occur.

AnimatedScale

    <AnimatedScale
        ...
        scaleX={...} [a number by which the X-dimension is multiplied]
        scaleY={...} [a number by which the Y-dimension is multiplied]
    >

When scaleX (or scaleY, or both) are changed, they will not only snap, but animate instead.

AnimatedSkew

    <AnimatedSkew
        ...
        skewX={...} [a skew angle in radians]
        skewX={...} [a skew angle in radians]
    >

AnimatedPerspective

    <AnimatedPerspective
        ...
        perspective={...} [the perspective point distance in pixels]
    >

Animation actions

The animation actions have start and end parameters. They start animating immediatelly on mount, execute for the given time and when they finish, they can only be restarted by remounting. Once instantiated, they will run on first mount to the end, and they cannot be affected by changing props at any moment. You can pass onFinished callback, to be notified when the animation is finished.

E.g.:

    <AnimateMove
        onFinished={() => {}}
        start={{
            top: 10,
            left: 10,
        }}
        end={{
            top: 50,
            left: 50,
        }}
        duration={2000}
    >
        <img src="..." />
    </AnimateMove>

The image will start moving on mount, and will move from (10, 10) to (50, 50) within 2 seconds. Once it arrives to (50, 50), it will stay there, regardless of any prop change. The only way to restart an animation action is to remount it.

AnimateMove

    <AnimateMove
        ...
        start={{ top, left }} [start and end positions, in pixels]
        end={{ top, left }} [in pixels, required]
    >
        {child}
    <AnimateMove />

Moves the child from start to end position.

AnimateRotate

    <AnimateRotate
        ...
        start={{ X, Y, Z }} [start and end X, Y and/or Z angles in radians]
        end={{ X, Y, Z }}
    >

Rotates the child over the given axis (X, Y, Z or some combinations, depending on which of them you define), by the given angle in radians.

Example:

    <AnimateRotate
        duration={2000}
        start={{ Z: 30 }}
        end={{ Z: 80 }}
    >
        <span>I'm rotating</span>
    </AnimateRotate>

This piece of code, when mounted, will show the SPAN rotated at 30° around the Z-axis as the first frame, and immediately start rotating it until it reaches 80°, 2 seconds later.

AnimateScale

    <AnimateScale
        ...
        start={{ X, Y }} [start and end, X and Y multiplication factors]
        end={{ X, Y }}
    >

Scales the child over a given time period by the given X and/or Y axis.

AnimateSkew

    <AnimateSkew
        ...
        start={{ X, Y }} [start and end angles in degrees; one or both may be specified]
        end={{ X, Y }}
    >

AnimatePerspective

    <AnimatePerspective
        start={startPerspective} [number]
        end={endPerspective} [number]
    >

Common properties

All animation objects can also receive these props:

  • duration - every animation takes a duration parameter, which specifies the time needed for that animation to finish. For animated state objects, if some props are changed while an existing animation is in progress, then that existing animation will abort and a new animation with full duration will start immediately, with the current state as the starting point.
  • style - an object with additional CSS to apply on the enwrapping DIV / View (good examples are custom z-index, unwanted margins, paddings etc). The default is an empty object.
  • getEasingFunc - a function returning the easing/timing function to use in the animation. The expected result of the function must conform to the current platform (web / React Native), so it is up to the developer to make sure this custom function returns what is expected at the current platform. Easing functions for React Native are described here, and easing functions for web are described here. The default is 'ease' for web, and Easing.in() for React Native.
  • useNativeDriver - React Native specific (does not do anything for web), specifies whether or not to use this flag in animations. For React Native, this flag will help provide faster animations, by utilizing some system-specific animation threads. The default is false.

Example projects

Two examples projects are provided, one for web, and one for React Native. Both are contained in the GitLab repo of this library, at https://gitlab.com/dmaksimovic/react-declare-animate, in the example directory.

Bugs & Hacks

  • React Native has an awkward behavior regarding Views which don't have a fixed width and height. Even if its content is empty, a View will always have some random width and height if they are not explicitly set. Since all animation objects of this library wrap their children in a View, it is often needed to set width and height manually by using the style={...} override. The library cannot fix this alone, because there is no clear way provided by React Native to ask a View to "fit to content".
  • It is often needed to set a transformation origin point (transform-origin) when doing geometrical transformations. CSS provides a clear way to do this (by using the transform-origin directive), but React Native does not provide this, therefore the library does not provide it all, otherwise it would be inconsistent across Web <-> Native. There is a short discussion on StackOverflow about this problem, and there was a request for adding transform-origin to React Native on GitHub here.
  • There is a known bug in React Native that scale[XY] does not work on Android when set to 0 (zero) as the initial value. It behaves as if it was set to 1 instead. When you start animating however, it behaves as if it was indeed set to zero. There has been a bug opened on RN's GitHub issues page here, but it was closed due to inactivity, and a new one was opened on another RN's GitHub issues page here, but that one was closed unfixed as well. The general hack/workaround is to use 0.01 or similar, instead of just zero (note though, for some reason many zeroes like 0.00001 also don't work). Instead of introducing this hack to react-declare-animate and making it dirty, it is suggested to users to use 0.01 etc. with AnimateScale and AnimatedScale, instead of 0, until guys from React Native fix their bug.

Organizations and projects using react-radio-button-group


Mau King - Mau Mau, Crazy 8s, the card game