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

@evatrilvideo/ai-video-package

v1.0.23

Published

@evatrilvideo/ai-video-package

Readme

@evatrilvideo/ai-video-package

A React + Remotion package that contains reusable invitation video frames, visual elements, transitions, font registration, video-data mapping, and the main Remotion composition.

This README documents only the functionality and structure contained inside this package.

Table of Contents

Overview

Package Information

Technology

Package Structure

Main Flow

Main Files

VideoComposition

Frame Registry

Frames

Elements and Animations

Transitions

Video Data Mapper

Font Registration

Image Preloading

Preview Assets

Remotion Root

Adding a New Frame

Adding a New Element or Animation

Adding a New Transition

Adding a New Data Field

Frame Duration

Usage Flow

Development Notes

Overview

@evatrilvideo/ai-video-package is a reusable video-template package built with React and Remotion.

The package contains:

Reusable video frame components

Reusable visual elements and animations

Reusable transition components

A centralized frame registry

Backend-data normalization through mapVideoData()

Font registration and loading

Image preloading helpers

Preview asset utilities

The main Remotion composition

The package is designed so that a video can be assembled from a list of registered frame names and a videoData object.

Package Information

Current package configuration:

{ "name": "@evatrilvideo/ai-video-package", "version": "1.0.10", "type": "module", "main": "src/remotionRoot.jsx", "exports": { ".": "./src/remotionRoot.jsx" } }

Peer Dependencies

The package expects:

React >= 18 React DOM >= 18 Remotion ^4.0.0

The package entry point is:

src/remotionRoot.jsx

Technology

Technology Purpose

React Video UI and reusable components

Remotion Programmatic video composition and rendering

JavaScript / JSX Package implementation

FontFace API Dynamic font loading

Remotion Sequence Frame timeline sequencing

Remotion delayRender / Asset and font loading control continueRender

Remotion prefetch Preview asset preloading

Package Structure

video-templates/ │ ├── package.json │ └── src/ │ ├── compositions.jsx ├── frameRegistry.js ├── videoDataMapper.js ├── remotionRoot.jsx │ ├── fonts/ │ ├── index.js │ └── registerFonts.js │ └── Invitations/ │ ├── Elements/ │ ├── reusable animations │ ├── visual effects │ └── transitions │ ├── Frames/ │ └── video frame components │ ├── hooks/ │ ├── useImagePreload.js │ └── usePreloadImages.js │ └── utils/ └── previewAssets.js

Main Flow

The internal package flow is:

videoData + frame list │ ▼ VideoComposition │ ▼ mapVideoData() │ ▼ normalized data │ ▼ frameRegistry │ ▼ Frame Component │ ├── Elements / Animations │ └── Transitions │ ▼ Remotion Sequence │ ▼ Video Render

The package does not itself define an external application, database, admin panel, or AI-generation service. Those systems can provide data or media to the package, but they are outside this package.

Main Files

src/remotionRoot.jsx

The main Remotion entry point.

Responsibilities:

Registers the Remotion root

Creates the Video composition

Loads fonts before rendering continues

Defines video dimensions

Defines FPS

Defines default props

src/compositions.jsx

Contains VideoComposition.

Responsibilities:

Receives frames

Receives videoData

Normalizes videoData

Finds each frame in frameRegistry

Calculates each frame's starting position

Creates Remotion components

Passes normalized data to each frame

src/frameRegistry.js

Contains the mapping between frame IDs and frame components.

Each registry entry contains:

{ component: FrameComponent, duration: 150 }

The current registry contains the package's registered frame components.

src/videoDataMapper.js

Contains:

mapVideoData(videoData)

It converts the incoming video data into a normalized object that can be consumed by different frame components.

The mapper also preserves the original:

eventData occasion extraData

and spreads the original videoData into the returned object.

VideoComposition

VideoComposition is the main internal composition component.

export const VideoComposition = ({ frames = [], videoData = {} }) => { const normalizedData = mapVideoData(videoData);

// ... };

Processing Flow

For every frame name:

frame name ↓ frameRegistry[frameName] ↓ frame component ↓ frame duration ↓ Remotion Sequence

The component uses:

<Sequence key={${frameName}-${index}} from={currentStart} durationInFrames={duration}

<FrameComponent {...normalizedData} />

This means every registered frame receives the normalized video data as props.

Frame Registry

File:

src/frameRegistry.js

The registry connects a frame name with its component and duration.

Example:

F01042026_01: { component: F01042026_01, duration: 150 }

The frame name used in the frames array must match the registry key exactly.

Example:

const frames = [ "F01042026_01", "F01042026_02", "F01042026_03" ];

If a frame name is not found:

const frameConfig = frameRegistry[frameName];

if (!frameConfig) return null;

the frame is skipped.

Frames

Frame components are located in:

src/Invitations/Frames/

The package contains a large collection of registered frames for different invitation designs and occasions.

Frame names follow patterns such as:

F01042026_01 F01042026_02 F01042026_03

F30072026_01 F30072026_02

F17062026_01 F17062026_02

The exact frame naming convention is already established by the package's existing files and registry.

A frame is responsible for its own visual composition.

A frame can contain:

Backgrounds

Text

Images

Decorative elements

Animations

Other reusable components

Elements and Animations

Reusable visual components are located in:

src/Invitations/Elements/

The package contains elements such as:

BalloonPhotoReveal28072026.jsx BirdsFlyAnimation14042026.jsx BlowingLeaves28012026.jsx Butterflies20012026.jsx CandleGlowReveal01072026.jsx FallingPetals27062026.jsx FloatingBalloons26022026.jsx FlowersSide20012026.jsx OpeningGate20012026.jsx PhotoOrbitReveal08072026.jsx SmokeEffect14042026.jsx TextAnimation16032026.jsx WalkingSequenceAnimation27032026.jsx WordReveal28012026.jsx

These components are reusable building blocks for frames.

For example:

Frame ├── Text ├── Image ├── FallingPetals ├── Butterflies └── Other Elements

This keeps common visual effects separate from individual frame components.

Transitions

Transitions are also stored in:

src/Invitations/Elements/

The package uses the T_ naming pattern for transition components.

Examples:

T_CornerFlip05022026.jsx T_Curtain_LeftRight20012026.jsx T_Diagonal12022026.jsx T_FadeTransition.jsx T_FlowerCurtain16022026.jsx T_HoldSlide03022026.jsx T_InkSmoke20012026.jsx T_MultiDirectionPageCurl11032026.jsx T_OpenPageReveal17032026.jsx T_PageCurl10032026.jsx T_PageFlip28012026.jsx T_ParticleSwarmTransition03072026.jsx T_Spread13032026.jsx T_WallPainting06072026.jsx T_Zoom0503202601.jsx T_ZoomFocus27032026.jsx

A transition is a reusable visual effect intended to control movement or transformation between visual states.

The transition components are part of the package itself; their configuration or selection can be handled by an external application.

Video Data Mapper

File:

src/videoDataMapper.js

The main function is:

mapVideoData(videoData)

The mapper reads:

videoData ├── eventData │ └── occasion │ └── extraData

It supports multiple naming styles for several fields.

For example:

videoData?.eventData videoData?.event_data videoData?.eventdata

are accepted for the event data object.

Similarly:

eventData?.occasion_data eventData?.occasionData eventData?.occasiondata

are accepted for occasion data.

And:

videoData?.extraData videoData?.extra_data videoData?.extradata

are accepted for extra data.

Normalized Data

The mapper creates normalized properties for the frames.

Wedding Data

firstName secondName

firstPhoto secondPhoto

firstSideNote secondSideNote

The wedding fields are mapped from bride/groom information.

Birthday / Haldi / Mehendi / Religious Function

name invitedBy celebrationAge photo

Engagement

brideName groomName

bridePhoto groomPhoto

Baby Shower

name1 name2

photo1 photo2

specialannouncementmessage

Naming Ceremony

gender

Reception / Festival / Walima / Bachelor Party

host

Thread Ceremony / Annaprasanna

parentsName

House Warming

specialNote

Corporate Event

eventTitle companyName eventType eventDescription

Anniversary

anniversaryYear

Temple Anniversary

templeAnniversary organizationName

Death Anniversary

deathAnniversary

Funeral / Antim Sanskar

birthAndPassingDates dashakarmaDate

Common Data

The mapper also provides:

welcomeMessage invitationMessage familyMember

venueName venueAddress occasionDate eventDateTime

Original Data

The mapper keeps the original nested objects:

eventData occasion extraData

It also includes the original videoData properties:

return { // normalized fields

eventData, occasion, extraData,

...videoData, };

This allows a frame to use normalized properties while still having access to the original data when required.

Font Registration

Font files and font-loading logic are located in:

src/fonts/

The package exports:

export { registerFonts } from "./registerFonts";

The main implementation is:

src/fonts/registerFonts.js

The package currently registers these font families:

Great Vibes Dancing Script Italic Playfair Display Noto Sans Devanagari Noto Naskh Arabic Noto Serif Oriya Noto Serif Kannada Noto Sans Gurmukhi

The fonts are loaded through the browser FontFace API.

Font Loading Flow

The root component uses:

delayRender() ↓ registerFonts() ↓ FontFace.load() ↓ document.fonts.add() ↓ document.fonts.ready ↓ continueRender()

This prevents Remotion from continuing while the font-loading process is still running.

Font loading uses timeouts so that one unavailable font does not keep the rendering process waiting indefinitely.

Current timeout values:

Font loading timeout: 15000 ms document.fonts.ready: 5000 ms

Image Preloading

The package contains:

src/Invitations/hooks/useImagePreload.js

The hook:

useImagePreload(src)

is designed to preload and decode an image before continuing Remotion rendering.

It uses:

delayRender() continueRender()

and loads images with:

img.crossOrigin = "anonymous";

If image loading fails, the hook logs a warning and continues rendering instead of leaving Remotion permanently blocked.

Preview Assets

Preview asset utilities are located at:

src/Invitations/utils/previewAssets.js

The package defines:

S3_ELEMENTS_BASE

for the package's remote element assets.

The utility provides:

isMobilePreviewRuntime()

which checks whether the current browser viewport is a mobile-sized preview.

It also provides:

usePreviewAssets(imageSources)

for preview asset preparation.

Preview Asset Flow

The preview asset utility:

Image Sources ↓ Remove empty values ↓ Remove duplicates ↓ Remotion prefetch() ↓ Blob URL ↓ Image loading ↓ Image decoding ↓ Decoded image cache ↓ continueRender()

The decoded image cache is stored on:

window.__decodedImagesCache

This helps avoid repeatedly decoding the same preview image.

usePreloadImages

File:

src/Invitations/hooks/usePreloadImages.js

This hook is a small wrapper around:

usePreviewAssets(imageSources)

Usage:

const { assetsReady, sources } = usePreloadImages(imageSources);

It allows frame components to prepare their preview assets through the shared preview utility.

Remotion Root

File:

src/remotionRoot.jsx

The package defines the Remotion composition:

<Composition id="Video" component={VideoComposition} durationInFrames={10000} fps={30} width={1080} height={1920} defaultProps={{ frames: [], videoData: {}, }} />

Current composition settings:

Property Value

Composition ID Video Width 1080 Height 1920 FPS 30 Default duration 10000 frames

The video format is therefore:

1080 × 1920 9:16 portrait 30 FPS

The file finishes by registering the root:

registerRoot(Root);

Adding a New Frame

To add a new frame:

  1. Create the frame component

Create a file inside:

src/Invitations/Frames/

Example:

F25092026_01.jsx

Example component:

export const F25092026_01 = ({ firstName, secondName, }) => { return ( <div style={{ width: 1080, height: 1920, }} > {firstName} {secondName} ); };

  1. Import the frame into frameRegistry.js

import { F25092026_01 } from "./Invitations/Frames/F25092026_01";

  1. Register the frame

F25092026_01: { component: F25092026_01, duration: 150 },

  1. Use the frame name

The frame can then be supplied through the frames array:

[ "F25092026_01" ]

The name must exactly match the registry key.

Adding a New Element or Animation

Create the component inside:

src/Invitations/Elements/

Example:

MyAnimation.jsx

Example:

export const MyAnimation = ({ children }) => { return ( <> {children} </> ); };

Then import it into the frame where it is needed:

import { MyAnimation } from "../Elements/MyAnimation";

Use it:

Reusable visual logic should generally live in Elements/ instead of being duplicated across multiple frames.

Adding a New Transition

Create the transition inside:

src/Invitations/Elements/

Follow the existing T_ naming convention.

Example:

T_MyTransition.jsx

Then implement the transition component and import it into the frame or composition where it is required.

Example:

export const T_MyTransition = ({ children }) => { return ( <> {children} </> ); };

Adding a New Data Field

When a new frame requires a data field that is not currently normalized, add the mapping to:

src/videoDataMapper.js

For example, if the incoming data contains:

extraData?.couple_tagline

you can expose it as:

coupleTagline: extraData?.couple_tagline || extraData?.coupleTagline || extraData?.coupletagline || "",

The frame can then use:

Keep backend-to-frame field normalization in videoDataMapper.js rather than repeating it inside individual frames.

Frame Duration

Frame durations in the registry are measured in frames, not seconds.

The package runs at:

30 FPS

Therefore:

30 frames = 1 second 60 frames = 2 seconds 90 frames = 3 seconds 120 frames = 4 seconds 150 frames = 5 seconds 180 frames = 6 seconds 210 frames = 7 seconds 300 frames = 10 seconds

Formula:

seconds = frames / 30

For example:

150 / 30 = 5 seconds

Frame Timeline

VideoComposition builds the timeline sequentially.

For example:

[ "F01042026_01", "F01042026_02", "F01042026_03" ]

with durations:

F01042026_01 → 150 frames F01042026_02 → 180 frames F01042026_03 → 150 frames

creates:

0 │ ├──────── Frame 1 ────────┤ 0 149 │ ├──────── Frame 2 ─────────┤ 150 329 │ ├──── Frame 3 ────┤ 330 479

The next frame starts where the previous frame ends.

Usage Flow

The package expects the consuming Remotion environment to provide:

{ frames: [ "F01042026_01", "F01042026_02", "F01042026_03" ],

videoData: { // event data } }

The internal processing is:

frames │ ▼ VideoComposition │ ├── mapVideoData(videoData) │ ▼ normalizedData │ ▼ frames.map(...) │ ▼ frameRegistry[frameName] │ ├── component └── duration │ ▼ │ ▼ <FrameComponent {...normalizedData} />

Development Notes

Keep frame IDs consistent

The same frame ID must be used consistently between:

Frame file ↓ Import ↓ Registry key ↓ frames array

For example:

F01042026_01

must match exactly.

Keep reusable visual logic in Elements

If an animation or visual effect is used by multiple frames, place it in:

src/Invitations/Elements/

instead of duplicating the implementation.

Keep data normalization in one place

Use:

src/videoDataMapper.js

for converting incoming data into frame-friendly props.

This keeps frame components simpler.

Keep frame registration centralized

All renderable frames should be registered in:

src/frameRegistry.js

so that VideoComposition can resolve them by name.

Keep loading logic safe

When adding assets that must be loaded before rendering, use the existing Remotion loading pattern:

delayRender() ↓ load asset ↓ continueRender()

and make sure failures cannot leave the composition permanently waiting.

Internal Package Summary

The package can be understood through these core layers:

┌──────────────────────────────────────────┐ │ Remotion Root │ │ remotionRoot.jsx │ └───────────────────┬──────────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ Video Composition │ │ compositions.jsx │ └───────────────────┬──────────────────────┘ │ ┌─────────┴─────────┐ ▼ ▼ ┌─────────────────┐ ┌───────────────────┐ │ Video Data │ │ Frame Registry │ │ Mapper │ │ frameRegistry.js │ └────────┬────────┘ └─────────┬─────────┘ │ │ │ ▼ │ ┌─────────────────┐ │ │ Frame Components│ │ │ Frames/ │ │ └────────┬────────┘ │ │ │ ▼ │ ┌─────────────────┐ │ │ Elements │ │ │ Animations │ │ │ Transitions │ │ └─────────────────┘ │ ▼ ┌──────────────────────────────────────────┐ │ Normalized Props │ └──────────────────────────────────────────┘

Package Responsibility

This package is responsible for:

✓ Remotion composition ✓ Frame components ✓ Frame registry ✓ Frame sequencing ✓ Video-data normalization ✓ Reusable visual elements ✓ Animations ✓ Transitions ✓ Font registration ✓ Image preloading ✓ Preview asset preparation

External systems may provide the input data or media, but those systems are not part of this package.

End

@evatrilvideo/ai-video-package provides the reusable React + Remotion building blocks required to compose invitation videos from registered frames, normalized data, reusable elements, transitions, and assets.

Video Effects System

@evatrilvideo/ai-video-package supports a dynamic, registry-driven video effect system. It allows backend services and admin panels to inject visual overlays (such as falling petals or flying butterflies) and camera transitions (such as zoom-in and zoom-out) directly into compositions via input props without modifying template code.

1. Architecture & Flow

Effects in the package are categorized into two types: | Effect Type | Description | Rendering Mechanism | Examples | | :--- | :--- | :--- | :--- | | wrapper | Camera / Zoom Movements: Applies continuous scale/transform animations to the underlying video frames. | Wraps <AbsoluteFill> frames via reduce | ZoomIn27092026, ZoomOut27092026 | | component | Visual Overlays: Floating transparent layers rendered on top of the video frames. | Rendered as foreground siblings via <EffectRenderer> | FallingPetals27062026, Butterflies20012026 |

Visual Pipeline:

            Backend / Admin Payload
                       │
                       ▼
                inputProps: {
                  frames: [...],
                  effects: [...],
                  videoData: {...}
                }
                       │
                       ▼
               VideoComposition
                       │
        ┌──────────────┴──────────────┐
        │                             │
        ▼                             ▼
 wrapperEffects                overlayEffects

(type === "wrapper") (type === "component") │ │ ▼ ▼ Wraps Frames via reduce EffectRenderer <ZoomIn27092026 {...props}> │ Frame 1 ▼ Frame 2 effectRegistry │ ▼ Foreground Overlays


2. Core Files & Responsibilities

1. src/effectRegistry.js

The central registry linking effect keys with their React components and execution types (wrapper or component).

import { Butterflies20012026 } from "./Invitations/Elements/Butterflies20012026";
import { FallingPetals27062026 } from "./Invitations/Elements/FallingPetals27062026";
import { ZoomIn27092026 } from "./Invitations/Elements/ZoomIn27092026";
import { ZoomOut27092026 } from "./Invitations/Elements/ZoomOut27092026";
export const effectRegistry = {
  FallingPetals27062026: {
    type: "component",
    component: FallingPetals27062026,
  },
  Butterflies20012026: {
    type: "component",
    component: Butterflies20012026,
  },
  ZoomIn27092026: {
    type: "wrapper",
    component: ZoomIn27092026,
  },
  ZoomOut27092026: {
    type: "wrapper",
    component: ZoomOut27092026,
  },
};
2. src/effectRenderer.jsx
Responsible for mounting overlay (component) effects. It gracefully verifies that the requested effectKey exists in the registry.

3. src/compositions.jsx
The master composition orchestrator:

Sequences static frames.
Wraps the frames inside active wrapper effects (e.g. ZoomIn, ZoomOut).
Renders component overlays (e.g. FallingPetals, Butterflies) on top.
3. Registered Effects Reference
A. Camera / Zoom Effects (type: "wrapper")
1. ZoomIn27092026
Smoothly scales into the video scene over a specified frame window.

Registry Key: "ZoomIn27092026"
Props (props object):
startFrame (number, default: 0): Video frame when zooming starts.
endFrame (number, default: durationInFrames): Video frame when zoom finishes.
startScale (number, default: 1.0): Starting scale factor (1.0 = 100%).
endScale (number, default: 1.20): Target scale factor (1.20 = 120%).
duration (number, optional): Total animation duration in frames.
isMobilePreview (boolean, default: false): Disables hardware transform acceleration for mobile viewports.
2. ZoomOut27092026
Smoothly pulls back from an enlarged scale to a normal or smaller scale.

Registry Key: "ZoomOut27092026"
Props (props object):
startFrame (number, default: 0): Video frame when zoom-out begins.
endFrame (number, default: durationInFrames): Video frame when zoom-out reaches target scale.
startScale (number, default: 1.20): Starting enlarged scale factor.
endScale (number, default: 1.0): Target normal scale factor.
duration (number, optional): Total animation duration in frames.
isMobilePreview (boolean, default: false): Disables hardware transform acceleration for mobile viewports.
B. Visual Overlay Effects (type: "component")
3. FallingPetals27062026
Renders realistic floating and swaying flower petals over the video.

Registry Key: "FallingPetals27062026"
Props (props object):
count (number, default: 30): Number of petals generated simultaneously.
color (string, default: "#d94b5b"): Color tint applied to the petals.
petalImage (string, optional): Custom image URL for petal texture.
speed (number, default: 0.08): Downward falling velocity.
sway (number, default: 15): Amplitude of horizontal swaying.
size (number, default: 2.5): Scale factor of petal size.
startFrame (number, default: 0): Timeline frame when petals start falling.
endFrame (number, default: end of composition): Timeline frame when petals fade out.
4. Butterflies20012026
Renders flying animated butterflies with natural flapping and path easing.

Registry Key: "Butterflies20012026"
Props (props object):
src (string, Required): Public URL of the butterfly asset (e.g. S3 WebP image).
startX (number, default: 400): Starting X coordinate (in 1080 canvas pixels).
startY (number, default: height + 120): Starting Y coordinate.
endX (number, optional): Ending X coordinate.
endY (number, default: -250): Ending Y coordinate.
duration (number, default: 8): Flight duration in seconds.
size (number, default: 160): Butterfly dimension in pixels.
startFrame (number, default: 0): Timeline frame when flight starts.
4. Backend / API JSON Payload Examples
Example 1: Full Cinematic Setup (Zoom In + Falling Petals)
json


{
  "frames": [
    "F20012026_01",
    "F20012026_02",
    "F20012026_03"
  ],
  "effects": [
    {
      "effect_key": "ZoomIn27092026",
      "props": {
        "startFrame": 0,
        "endFrame": 300,
        "startScale": 1.0,
        "endScale": 1.15
      }
    },
    {
      "effect_key": "FallingPetals27062026",
      "props": {
        "count": 25,
        "color": "#e05263"
      }
    }
  ],
  "videoData": {
    "eventData": {
      "bride_name": "Pooja",
      "groom_name": "Rahul"
    }
  }
}
Example 2: Flying Butterfly Overlay Only
json


{
  "frames": ["F01042026_01"],
  "effects": [
    {
      "effect_key": "Butterflies20012026",
      "props": {
        "src": "https://storage.evatril.com/video-themes/elements/20012026-butterfly.webp",
        "size": 150,
        "duration": 9
      }
    }
  ],
  "videoData": {}
}
Example 3: Clean Video (No Effects)
json


{
  "frames": ["F01042026_01", "F01042026_02"],
  "effects": [],
  "videoData": {}
}
5. Adding a New Effect in the Future
A. To add a new Visual Overlay (e.g. Snow, Sparkles, Fireflies):
Create your component in src/Invitations/Elements/MyOverlayEffect.jsx.
Ensure it renders inside <AbsoluteFill style={{ pointerEvents: "none" }}>.
Register in src/effectRegistry.js:
javascript


import { MyOverlayEffect } from "./Invitations/Elements/MyOverlayEffect";
export const effectRegistry = {
  // ...
  MyOverlayEffect: {
    type: "component",
    component: MyOverlayEffect,
  },
};
B. To add a new Camera / Wrapper Effect (e.g. Pan, Tilt, Camera Shake):
Create your component in src/Invitations/Elements/MyCameraEffect.jsx.
Ensure it accepts { children } and wraps them:
jsx


export const MyCameraEffect = ({ children, ...props }) => {
  // calculate animation values with useCurrentFrame()
  return (
    <AbsoluteFill style={{ transform: `...` }}>
      {children}
    </AbsoluteFill>
  );
};
Register in src/effectRegistry.js with type: "wrapper":
javascript


MyCameraEffect: {
  type: "wrapper",
  component: MyCameraEffect,
},
6. Admin Panel Implementation Guidelines
When managing effects in the Admin Panel or Template Creator:

Camera Animation Selector (Single Select):

Provide dropdown options:
None (no zoom)
Subtle Zoom In (1.0x -> 1.15x)
Deep Zoom In (1.0x -> 1.30x)
Zoom Out (1.20x -> 1.0x)
Stores the selected key and injects it into the effects payload.
Atmosphere / Foreground Effects (Multi-Select Checkboxes):

[x] Falling Rose Petals (FallingPetals27062026)
[x] Flying Butterflies (Butterflies20012026)
Custom Parameters (Optional Sliders):

Density/Count slider for Petals (range: 10 – 50).
Color picker for Petals.
S3 URL selector for custom butterfly assets.
12:16 PM