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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mihirsarya/manim-scroll-runtime

v0.2.2

Published

Scroll-driven playback runtime for pre-rendered Manim animations.

Downloads

62

Readme

@mihirsarya/manim-scroll-runtime

Core scroll-driven playback runtime for pre-rendered Manim animations. Works in any JavaScript environment—use directly in vanilla JS or as the foundation for framework integrations.

Installation

npm install @mihirsarya/manim-scroll-runtime

Or use the unified package (recommended for React/Next.js):

npm install @mihirsarya/manim-scroll

Features

  • Video or frame-by-frame playback with automatic fallback
  • Flexible scroll ranges via presets, relative units, or pixels
  • Native text animation using SVG (no pre-rendered assets needed)
  • Zero framework dependencies for the core runtime

Quick Start

Pre-rendered Animation (Video/Frames)

import { registerScrollAnimation } from "@mihirsarya/manim-scroll-runtime";

const container = document.querySelector("#hero") as HTMLElement;

const cleanup = await registerScrollAnimation({
  container,
  manifestUrl: "/assets/scene/manifest.json",
  scrollRange: "viewport",
  onReady: () => console.log("Animation ready"),
  onProgress: (progress) => console.log(`Progress: ${progress}`),
});

// Call cleanup() when done to remove listeners

Native Text Animation

import { registerNativeAnimation } from "@mihirsarya/manim-scroll-runtime";

const container = document.querySelector("#text") as HTMLElement;

const cleanup = await registerNativeAnimation({
  container,
  text: "Hello World",
  fontSize: 48,
  color: "#ffffff",
  scrollRange: "viewport",
  onReady: () => console.log("Ready"),
});

Exports

Functions

  • registerScrollAnimation(options) - Register a scroll-driven animation with pre-rendered assets
  • registerNativeAnimation(options) - Register a native SVG text animation

Classes

  • NativeTextPlayer - Low-level native text animation player

Types

  • RenderManifest - Animation manifest schema
  • ScrollAnimationOptions - Options for registerScrollAnimation
  • NativeAnimationOptions - Options for registerNativeAnimation
  • ScrollRange, ScrollRangePreset, ScrollRangeValue - Scroll range types

API Reference

registerScrollAnimation(options)

Registers a scroll-driven animation using pre-rendered video or frame assets.

interface ScrollAnimationOptions {
  /** Container element for the animation */
  container: HTMLElement;
  /** URL to the animation manifest.json */
  manifestUrl: string;
  /** Playback mode (default: "auto") */
  mode?: "auto" | "frames" | "video";
  /** Optional canvas element (created automatically if not provided) */
  canvas?: HTMLCanvasElement;
  /** Scroll range configuration */
  scrollRange?: ScrollRangeValue;
  /** Called when animation is loaded and ready */
  onReady?: () => void;
  /** Called on scroll progress updates (0 to 1) */
  onProgress?: (progress: number) => void;
}

Returns: Promise<() => void> - Cleanup function to remove listeners

registerNativeAnimation(options)

Registers a native text animation that renders in the browser using SVG, replicating Manim's Write/DrawBorderThenFill effect.

interface NativeAnimationOptions {
  /** Container element for the animation */
  container: HTMLElement;
  /** Text to animate */
  text: string;
  /** Font size in pixels (inherits from parent if not specified) */
  fontSize?: number;
  /** Text color (hex or CSS color) */
  color?: string;
  /** URL to a font file (woff, woff2, ttf, otf) */
  fontUrl?: string;
  /** Stroke width for the drawing phase (default: 2) */
  strokeWidth?: number;
  /** Scroll range configuration */
  scrollRange?: ScrollRangeValue;
  /** Called when animation is loaded and ready */
  onReady?: () => void;
  /** Called on scroll progress updates (0 to 1) */
  onProgress?: (progress: number) => void;
}

Returns: Promise<() => void> - Cleanup function to remove listeners

Scroll Range Configuration

The scrollRange option controls when the animation plays relative to scroll position.

Presets

// Animation plays as element crosses the viewport (most common)
scrollRange: "viewport"

// Animation tied to element's own scroll position
scrollRange: "element"

// Animation spans entire document scroll
scrollRange: "full"

Relative Units

Use viewport height (vh) or element percentage (%):

// Start when element is 100vh from top, end at -50% of element height
scrollRange: ["100vh", "-50%"]

// Mix units as needed
scrollRange: ["80vh", "-100%"]

Pixel Values

For precise control:

// As a tuple
scrollRange: [800, -400]

// As an object (legacy format)
scrollRange: { start: 800, end: -400 }

Manifest Schema

The manifest.json file describes a pre-rendered animation:

interface RenderManifest {
  /** Scene name */
  scene: string;
  /** Frames per second */
  fps: number;
  /** Canvas width */
  width: number;
  /** Canvas height */
  height: number;
  /** Array of frame image URLs */
  frames: string[];
  /** Video URL (null if not available) */
  video: string | null;
  /** Whether rendered with transparent background */
  transparent?: boolean;
  /** Whether this is an inline animation */
  inline?: boolean;
  /** Aspect ratio for inline sizing */
  aspectRatio?: number | null;
}

Playback Modes

| Mode | Description | |------|-------------| | "auto" | Uses video if available, falls back to frames | | "video" | Forces video playback (fails if no video) | | "frames" | Forces frame-by-frame playback |

Browser Usage (CDN)

<script type="module">
  import { registerScrollAnimation } from "https://esm.sh/@mihirsarya/manim-scroll-runtime";
  
  registerScrollAnimation({
    container: document.querySelector("#hero"),
    manifestUrl: "/assets/scene/manifest.json",
    scrollRange: "viewport",
  });
</script>

Dependencies

License

MIT