Skip to main content
The @googleforcreators/animation package provides a comprehensive animation system for Web Stories. It supports both Web Animations API (WAAPI) for modern browsers and AMP animations for AMP-compatible output.

Installation

npm install @googleforcreators/animation

Quick Start

import { 
  AnimationProvider, 
  WAAPIWrapper,
  createAnimationPart 
} from '@googleforcreators/animation';

function StoryPage() {
  return (
    <AnimationProvider>
      <WAAPIWrapper
        target="element-id"
        animations={[
          {
            type: 'effectFadeIn',
            duration: 600,
            delay: 0,
          }
        ]}
      >
        <div id="element-id">
          This element will fade in!
        </div>
      </WAAPIWrapper>
    </AnimationProvider>
  );
}

Components

AnimationProvider

Provides animation context to child components:
import { AnimationProvider } from '@googleforcreators/animation';

function App() {
  return (
    <AnimationProvider>
      {/* Your story content */}
    </AnimationProvider>
  );
}

WAAPIWrapper

Wraps elements with Web Animations API support:
import { WAAPIWrapper, AnimationType } from '@googleforcreators/animation';

function AnimatedElement() {
  const animations = [
    {
      type: AnimationType.EffectFadeIn,
      duration: 1000,
      delay: 200,
      easing: 'cubic-bezier(0.4, 0.4, 0.0, 1)',
    }
  ];

  return (
    <WAAPIWrapper
      target="my-element"
      animations={animations}
    >
      <img id="my-element" src="image.jpg" alt="Animated" />
    </WAAPIWrapper>
  );
}

AMPWrapper

Wraps elements for AMP-compatible animations:
import { AMPWrapper } from '@googleforcreators/animation';

function AMPAnimatedElement() {
  return (
    <AMPWrapper
      target="amp-element"
      animations={[
        {
          type: 'effectZoom',
          duration: 800,
        }
      ]}
    >
      <div id="amp-element">AMP Content</div>
    </AMPWrapper>
  );
}

AMPAnimations

Generates AMP animation definitions:
import { AMPAnimations } from '@googleforcreators/animation';

function StoryOutput() {
  const animations = [
    { id: '1', type: 'effectFadeIn', duration: 600 },
    { id: '2', type: 'effectZoom', duration: 800 },
  ];

  return (
    <>
      <AMPAnimations animations={animations} />
      {/* Story content */}
    </>
  );
}

AMPKeyframes

Generates AMP keyframe definitions:
import { AMPKeyframes } from '@googleforcreators/animation';

function StoryOutput() {
  return (
    <>
      <AMPKeyframes animations={animations} />
      {/* Story content */}
    </>
  );
}

Animation Effects

The library provides numerous pre-built animation effects:

Entrance Effects

import { AnimationType } from '@googleforcreators/animation';

const fadeIn = {
  type: AnimationType.EffectFadeIn,
  duration: 600,
  delay: 0,
  easing: 'cubic-bezier(0.4, 0.4, 0.0, 1)',
};

More Effects

import { AnimationType } from '@googleforcreators/animation';

const twirlIn = {
  type: AnimationType.EffectTwirlIn,
  duration: 600,
  delay: 0,
};

Background Animations

Special animations for background elements:
import { AnimationType } from '@googleforcreators/animation';

const bgZoom = {
  type: AnimationType.EffectBackgroundZoom,
  duration: 1000,
  delay: 0,
  zoomFrom: 100,
  zoomTo: 120,
};

Animation Parts

Create custom animations using animation parts:
import { createAnimationPart, AnimationType } from '@googleforcreators/animation';

const customAnimation = createAnimationPart({
  type: AnimationType.Move,
  duration: 1000,
  delay: 0,
  offsetX: 100,
  offsetY: 50,
});

Available Animation Parts

  • BlinkOn - Blinking effect
  • Bounce - Bouncing motion
  • Fade - Opacity transition
  • Flip - 3D flip effect
  • FloatOn - Floating appearance
  • Move - Position translation
  • Pulse - Scaling pulse
  • Spin - Rotation effect
  • Zoom - Scale effect

Constants

Easing Functions

import { BEZIER } from '@googleforcreators/animation';

const animation = {
  type: AnimationType.EffectFadeIn,
  duration: 600,
  easing: BEZIER.inOutQuad, // Smooth in-out easing
};

// Available easing options:
// linear, in, out, inOut, inQuad, outQuad, inOutQuad,
// inCubic, outCubic, inOutCubic, inQuart, outQuart, inOutQuart,
// inQuint, outQuint, inOutQuint, inSine, outSine, inOutSine,
// inExpo, outExpo, inOutExpo, inCirc, outCirc, inOutCirc, default

Animation Effects Constants

import { 
  ANIMATION_EFFECTS,
  BACKGROUND_ANIMATION_EFFECTS,
  ANIMATION_PARTS 
} from '@googleforcreators/animation';

// Entrance effects
console.log(ANIMATION_EFFECTS.FADE_IN.value); // 'effectFadeIn'
console.log(ANIMATION_EFFECTS.FADE_IN.name); // 'Fade In'

// Background effects
console.log(BACKGROUND_ANIMATION_EFFECTS.ZOOM.value);

// Animation parts
console.log(ANIMATION_PARTS.BOUNCE.value);

Scale Directions

import { SCALE_DIRECTIONS, ScaleDirection } from '@googleforcreators/animation';

const scaleIn = SCALE_DIRECTIONS.IN; // Scale in from corners
const scaleOut = SCALE_DIRECTIONS.OUT; // Scale out to corners

// Individual directions:
// ScaleDirection.ScaleInTopLeft
// ScaleDirection.ScaleInBottomRight
// ScaleDirection.ScaleOutTopRight
// ScaleDirection.ScaleOutBottomLeft

Background Scale Limits

import { BG_MIN_SCALE, BG_MAX_SCALE } from '@googleforcreators/animation';

const bgAnimation = {
  type: AnimationType.EffectBackgroundZoom,
  zoomFrom: BG_MIN_SCALE, // 100
  zoomTo: BG_MAX_SCALE,   // 400
};

Hooks

useStoryAnimationContext

Access the animation context:
import { useStoryAnimationContext } from '@googleforcreators/animation';

function MyComponent() {
  const { animationState, setAnimationState } = useStoryAnimationContext();

  const playAnimation = () => {
    setAnimationState({ playing: true });
  };

  return (
    <button onClick={playAnimation}>
      Play {animationState.playing ? 'Playing...' : 'Paused'}
    </button>
  );
}

TypeScript

The package is written in TypeScript and exports comprehensive type definitions:
import type { 
  AnimationType,
  AMPEffectTiming,
  ScaleDirection,
  BezierType,
  FadeInEffect,
  FlyInEffect,
  ZoomEffect,
} from '@googleforcreators/animation';

interface AnimationConfig extends AMPEffectTiming {
  type: AnimationType;
  duration: number;
  delay?: number;
  easing?: BezierType;
}

const config: AnimationConfig = {
  type: AnimationType.EffectFadeIn,
  duration: 600,
  delay: 0,
  easing: 'ease-in-out',
};

Complete Example

import { 
  AnimationProvider,
  WAAPIWrapper,
  AnimationType,
  BEZIER,
  ANIMATION_EFFECTS,
  useStoryAnimationContext 
} from '@googleforcreators/animation';

function Story() {
  return (
    <AnimationProvider>
      <StoryPage />
    </AnimationProvider>
  );
}

function StoryPage() {
  const { animationState, setAnimationState } = useStoryAnimationContext();

  const animations = [
    {
      type: AnimationType.EffectFadeIn,
      duration: 600,
      delay: 0,
      easing: BEZIER.inOutQuad,
    },
    {
      type: AnimationType.EffectZoom,
      duration: 800,
      delay: 600,
      easing: BEZIER.outQuad,
    }
  ];

  return (
    <div>
      <WAAPIWrapper
        target="headline"
        animations={animations}
      >
        <h1 id="headline">Animated Headline</h1>
      </WAAPIWrapper>

      <WAAPIWrapper
        target="image"
        animations={[
          {
            type: AnimationType.EffectFlyIn,
            duration: 1000,
            delay: 1400,
            flyInDirection: 'leftToRight',
          }
        ]}
      >
        <img id="image" src="photo.jpg" alt="Animated" />
      </WAAPIWrapper>

      <button onClick={() => setAnimationState({ playing: true })}>
        Play Animations
      </button>
    </div>
  );
}

Output Generation

Generate animation outputs for different platforms:
import { 
  AnimationOutput,
  KeyframesOutput 
} from '@googleforcreators/animation';

// For AMP output
function AMPStory({ animations }) {
  return (
    <>
      <AnimationOutput animations={animations} />
      <KeyframesOutput animations={animations} />
      {/* Story content */}
    </>
  );
}

Build docs developers (and LLMs) love