Skip to content

Comments

Lottie Animation Integration#8

Open
codedbytahir wants to merge 1 commit intomainfrom
feat/lottie-integration-8781275110360285891
Open

Lottie Animation Integration#8
codedbytahir wants to merge 1 commit intomainfrom
feat/lottie-integration-8781275110360285891

Conversation

@codedbytahir
Copy link
Owner

@codedbytahir codedbytahir commented Feb 15, 2026

This PR introduces a robust Lottie animation system to MotionForge, comparable to Remotion's implementation.

Key features:

  1. Deterministic Rendering: The LottieAnimation component disables internal requestAnimationFrame and instead seeks to specific frames based on the MotionForge timeline.
  2. Flexible Composition: Supports frameStart, frameEnd, playbackRate, and loop properties.
  3. Sequence Awareness: Automatically detects if it's inside a Sequence and uses relative frame numbers for synchronization.
  4. Performance Optimized: Instances are memoized and properly destroyed to prevent memory leaks.
  5. CLI Support: New projects bootstrapped via create-motionforge now include lottie-web and a working example.
  6. Documentation: README and CHANGELOG have been updated to reflect these changes.

A new demo has been added to showcase these capabilities.


PR created automatically by Jules for task 8781275110360285891 started by @codedbytahir

Summary by CodeRabbit

Release Notes

  • New Features
    • Added production-grade Lottie animation support with frame-perfect synchronization to the timeline.
    • Introduced LottieAnimation component with configurable frame ranges, playback rates, and looping controls.
    • Added comprehensive demo examples and updated documentation with integration guides.

- Created <LottieAnimation /> component with frame-perfect synchronization.
- Implemented deterministic rendering by manually driving Lottie frames.
- Added support for relative frame contexts in Sequence component.
- Updated create-motionforge templates with Lottie examples and dependencies.
- Added comprehensive documentation and demo assets.
- Bumped motionforge to v1.3.0 and create-motionforge to v1.1.0.

Co-authored-by: codedbytahir <200578194+codedbytahir@users.noreply.github.com>
@google-labs-jules
Copy link
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@netlify
Copy link

netlify bot commented Feb 15, 2026

Deploy Preview for motion-forge ready!

Name Link
🔨 Latest commit 5165d15
🔍 Latest deploy log https://app.netlify.com/projects/motion-forge/deploys/69913ba0cd9abc0008b000eb
😎 Deploy Preview https://deploy-preview-8--motion-forge.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link

coderabbitai bot commented Feb 15, 2026

📝 Walkthrough

Walkthrough

This PR introduces Lottie animation support to MotionForge, adding a synchronizable LottieAnimation component that ties animation frames to the MotionForge timeline. It updates dependencies, refines context typing to support null values for better sequence detection, makes AbsoluteFillProps.children optional, and includes demo code with documentation and template updates.

Changes

Cohort / File(s) Summary
Package Version Bumps
packages/create-motionforge/package.json, packages/motionforge/package.json, src/lib/remotion/... (implied)
Updated versions from 1.2.0 to 1.3.0 across main packages.
Lottie Component Implementation
packages/motionforge/src/components/Lottie.tsx, src/lib/remotion/components/Lottie.tsx
New LottieAnimation component (~127 lines each) supporting frame synchronization with MotionForge timeline, looping, playback rate control, and deterministic rendering via manual frame control.
Type Definitions
packages/motionforge/src/core/types.ts, src/lib/remotion/core/types.ts
Added LottieAnimationProps interface with src, frameStart, frameEnd, playbackRate, loop, width, height, style, and className properties.
Context Type Refinements
packages/motionforge/src/components/Sequence.tsx, src/lib/remotion/components/Sequence.tsx
Changed RelativeFrameContext from createContext<number>(0) to `createContext<number
Media Component Updates
packages/motionforge/src/components/Media.tsx, src/lib/remotion/components/Media.tsx
Made AbsoluteFillProps.children optional (React.ReactNode?) to allow rendering without child content.
Public API Exports
packages/motionforge/src/index.ts, src/lib/remotion/index.ts
Exported new LottieAnimation component and LottieAnimationProps type; bumped version comment to 1.3.0.
Demo & Sample Assets
packages/motionforge/src/demo/LottieDemo.tsx, packages/motionforge/src/demo/sample-lottie.json, src/lib/remotion/demo/LottieDemo.tsx, src/lib/remotion/demo/sample-lottie.json
New demo component showcasing basic playback, partial window playback with looping, playback rate, and Sequence integration; includes a sample Lottie JSON animation (500x500 square with rotation, position, scale, opacity keyframes over 60 frames).
Documentation
packages/motionforge/README.md, packages/motionforge/CHANGELOG.md
Added "Using Lottie" section with code samples, LottieAnimation props documentation, and "Player Integration" / "Media Components" subsections; CHANGELOG entry for v1.3.0 features.
Dependency Updates
packages/motionforge/package.json, packages/create-motionforge/templates/shared/package.json.template
Added lottie-web ^5.13.0 (or ^5.12.2 in template) as runtime dependency.
Template Updates
packages/create-motionforge/templates/hello-world/page.tsx.template, packages/create-motionforge/templates/shared/package.json.template
Integrated LottieAnimation component usage in hello-world template with looping animation; updated gradient styling; bumped motionforge dependency to ^1.3.0.

Sequence Diagram(s)

sequenceDiagram
    participant App as App/Component
    participant LottieAnimation as LottieAnimation
    participant LottieWeb as lottie-web
    participant MotionForgeTimeline as MotionForge Timeline
    
    App->>LottieAnimation: Render with src, frameStart, frameEnd
    activate LottieAnimation
    LottieAnimation->>LottieWeb: Initialize Lottie instance on mount
    LottieWeb-->>LottieAnimation: DOMLoaded event
    LottieAnimation->>LottieAnimation: Set DOMLoaded flag to true
    
    loop On Each Frame
        MotionForgeTimeline->>LottieAnimation: useRelativeCurrentFrame / useCurrentFrame
        LottieAnimation->>LottieAnimation: Compute currentFrame from relative or absolute context<br/>(apply frameStart, playbackRate, looping logic)
        LottieAnimation->>LottieWeb: goToAndStop(lottieFrame, true)
        LottieWeb-->>LottieAnimation: Frame updated (no internal playback)
    end
    
    App->>LottieAnimation: Unmount
    LottieAnimation->>LottieWeb: Remove event listeners & destroy()
    deactivate LottieAnimation
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

Poem

🐰 bounces with glee
Lottie frames now dance in perfect time,
Synced to MotionForge's rhythm sublime,
Loop and fade, frame-perfect and bright,
Animation magic, utterly right! ✨

🚥 Pre-merge checks | ✅ 3 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Merge Conflict Detection ⚠️ Warning ❌ Merge conflicts detected (16 files):

⚔️ eslint.config.mjs (content)
⚔️ packages/create-motionforge/package.json (content)
⚔️ packages/create-motionforge/templates/hello-world/page.tsx.template (content)
⚔️ packages/create-motionforge/templates/shared/package.json.template (content)
⚔️ packages/motionforge/CHANGELOG.md (content)
⚔️ packages/motionforge/README.md (content)
⚔️ packages/motionforge/bun.lock (content)
⚔️ packages/motionforge/package.json (content)
⚔️ packages/motionforge/src/components/Media.tsx (content)
⚔️ packages/motionforge/src/components/Sequence.tsx (content)
⚔️ packages/motionforge/src/core/types.ts (content)
⚔️ packages/motionforge/src/index.ts (content)
⚔️ src/lib/remotion/components/Media.tsx (content)
⚔️ src/lib/remotion/components/Sequence.tsx (content)
⚔️ src/lib/remotion/core/types.ts (content)
⚔️ src/lib/remotion/index.ts (content)

These conflicts must be resolved before merging into main.
Resolve conflicts locally and push changes to this branch.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Lottie Animation Integration' accurately reflects the main purpose of the PR, which adds production-grade Lottie animation support to MotionForge.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/lottie-integration-8781275110360285891
⚔️ Resolve merge conflicts (beta)
  • Auto-commit resolved conflicts to branch feat/lottie-integration-8781275110360285891
  • Create stacked PR with resolved conflicts
  • Post resolved changes as copyable diffs in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🤖 Fix all issues with AI agents
In `@packages/create-motionforge/templates/hello-world/page.tsx.template`:
- Around line 37-40: The LottieAnimation usage currently points to an external
CDN URL; replace that with a bundled local JSON (e.g., sample-lottie.json) and
update the LottieAnimation src to reference the local asset via an import or
static file path instead of "https://assets10.lottiefiles.com/..."; add the
sample-lottie.json to the template directory so new projects ship with the asset
and update the component usage (LottieAnimation src prop) to load the local
file.

In `@packages/create-motionforge/templates/shared/package.json.template`:
- Line 18: The template pins lottie-web to ^5.12.2 which conflicts with
motionforge@^1.3.0's lottie-web@^5.13.0 requirement; update the lottie-web entry
in the package.json.template from "^5.12.2" to "^5.13.0" (or match motionforge's
range) so both dependencies use the same version range and avoid duplicate
installations.

In `@packages/motionforge/CHANGELOG.md`:
- Line 8: Update the incorrect release date in the CHANGELOG entry header for
version "## [1.3.0]" by replacing "2024-02-25" with the intended release date
"2026-02-15" so the changelog reflects the PR creation/release date; edit the
line that reads '## [1.3.0] - 2024-02-25' to '## [1.3.0] - 2026-02-15'.

In `@packages/motionforge/package.json`:
- Around line 91-93: Update the shared package.json.template to make the
lottie-web dependency match the main package: change the "lottie-web" version
specifier from "^5.12.2" to "^5.13.0" in the create-motionforge CLI template
(the shared package.json.template) so newly scaffolded projects use a compatible
lottie-web range that matches the packages/motionforge package.json.

In `@packages/motionforge/src/components/Sequence.tsx`:
- Around line 110-112: The exported hook useRelativeCurrentFrame now returns
number | null (RelativeFrameContext), which is a breaking change for external
consumers—update the release notes and add a short migration guide showing how
to handle the null case (e.g., using relativeFrame !== null ? relativeFrame :
absoluteFrame, as used in LottieAnimation) and include a minimal example snippet
and suggested fallback strategy; also mention the symbols RelativeFrameContext,
useRelativeCurrentFrame, LottieAnimation, relativeFrame and absoluteFrame so
consumers can find the relevant code, and optionally document or add a helper
alternative hook for callers that want a guaranteed number fallback.

In `@src/lib/remotion/components/Lottie.tsx`:
- Line 34: The isLoaded state is not reset when a new src is initialized,
causing stale true state to let the sync effect call goToAndStop on an unready
animation; inside the initialization useEffect that tears down and recreates the
Lottie animation (the effect that references createAnimation / destroy or the
effect where setIsLoaded(true) is currently set), call setIsLoaded(false) at the
start before creating the new animation so that isLoaded reflects the fresh
instance; ensure this change is applied alongside the existing setIsLoaded(true)
in the animation's load/complete handler so the sync effect (which checks
isLoaded) only runs after the new animation is ready.
- Line 5: The import of useVideoConfig in the Lottie component is unused; remove
useVideoConfig from the import statement that currently reads "import {
useCurrentFrame, useVideoConfig } from '../core/context';" (or alternatively use
it inside the Lottie component if you intended to access video config). Update
the import to only include useCurrentFrame to eliminate the unused-symbol lint
error.
- Around line 94-103: The non-loop branch for computing lottieFrame (variables:
lottieFrame, currentFrame, playbackRate, frameStart, end, duration, loop) only
clamps the upper bound to end and can produce values below frameStart; change
the non-loop logic to clamp lottieFrame between frameStart and end (and
optionally ensure it is not negative by clamping to Math.max(frameStart, 0) if
needed) so the value passed to lottie-web is always within the valid window.
- Line 79: The effect in the Lottie component (useEffect in
src/lib/remotion/components/Lottie.tsx) depends directly on the `src` prop which
can be a new object each render and cause infinite re-initialization; update the
component to stabilize `src` before using it in the dependency array (for
example, compute a stable key with useMemo or a serialized string like
JSON.stringify(src) and use that key in the dependency array) and then use that
stable reference/key in the effect (keep references to the Lottie instance
creation/cleanup in the same effect), or alternatively document that the `src`
prop must be a stable/memoized reference; ensure you only change the dependency
from `[src]` to the new stable memoized value (e.g., `stableSrc` or `srcKey`)
and keep instance teardown/creation logic attached to that stable dependency.

In `@src/lib/remotion/demo/LottieDemo.tsx`:
- Around line 51-61: The Sequence in LottieDemo.tsx is using its default
absolute-fill layout which causes its children to escape the 300px card
container; update the Sequence instance (the one wrapping the LottieAnimation
and Text) to set layout="none" so its content remains positioned inside the
parent div, keeping the existing from/durationInFrames props intact and not
altering the surrounding container styles.
🧹 Nitpick comments (3)
packages/motionforge/src/core/types.ts (1)

62-72: Consider narrowing the src type from object.

object accepts any non-primitive (arrays, dates, regex, etc.). A slightly tighter type like Record<string, unknown> would better signal intent and catch accidental misuse, while still accommodating arbitrary Lottie JSON shapes.

Suggested change
 export interface LottieAnimationProps {
-  src: string | object;
+  src: string | Record<string, unknown>;
src/lib/remotion/demo/sample-lottie.json (1)

1-35: Duplicate asset: identical to packages/motionforge/src/demo/sample-lottie.json.

These two files are byte-for-byte identical. If both packages genuinely need their own copy, consider generating one from the other during build, or placing the asset in a shared location and symlinking/importing from there. This avoids the risk of the files drifting out of sync.

src/lib/remotion/core/types.ts (1)

62-72: src: object is overly permissive.

Consider narrowing the type to Record<string, unknown> or a dedicated LottieAnimationData interface (e.g., with required v, fr, ip, op, layers fields) to catch misuse at compile time.

Comment on lines +37 to +40
<LottieAnimation
src="https://assets10.lottiefiles.com/packages/lf20_m6cu96.json"
loop
/>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

External URL in a starter template is a reliability risk.

The src points to https://assets10.lottiefiles.com/packages/lf20_m6cu96.json, which is a third-party CDN. If this asset is removed or the CDN is unreachable, new users will see a broken animation on first run — a poor out-of-box experience.

Consider bundling a local sample JSON (similar to the sample-lottie.json already added in this PR for the demo) and referencing it via a static file path or import.

Proposed fix: use a bundled local asset
+import sampleLottie from './sample-lottie.json';
 ...
             <LottieAnimation
-              src="https://assets10.lottiefiles.com/packages/lf20_m6cu96.json"
+              src={sampleLottie}
               loop
             />

You'd also need to include a copy of sample-lottie.json (or similar) in the template directory.

🤖 Prompt for AI Agents
In `@packages/create-motionforge/templates/hello-world/page.tsx.template` around
lines 37 - 40, The LottieAnimation usage currently points to an external CDN
URL; replace that with a bundled local JSON (e.g., sample-lottie.json) and
update the LottieAnimation src to reference the local asset via an import or
static file path instead of "https://assets10.lottiefiles.com/..."; add the
sample-lottie.json to the template directory so new projects ship with the asset
and update the component usage (LottieAnimation src prop) to load the local
file.

"framer-motion": "^11.13.1",
"lucide-react": "^0.468.0"
"lucide-react": "^0.468.0",
"lottie-web": "^5.12.2"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Version mismatch with motionforge's own lottie-web dependency.

The template pins lottie-web at ^5.12.2, but motionforge@^1.3.0 declares a dependency on lottie-web@^5.13.0. This mismatch could cause duplicate installations or resolution conflicts. Align both to the same version range.

🤖 Prompt for AI Agents
In `@packages/create-motionforge/templates/shared/package.json.template` at line
18, The template pins lottie-web to ^5.12.2 which conflicts with
motionforge@^1.3.0's lottie-web@^5.13.0 requirement; update the lottie-web entry
in the package.json.template from "^5.12.2" to "^5.13.0" (or match motionforge's
range) so both dependencies use the same version range and avoid duplicate
installations.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.3.0] - 2024-02-25
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Incorrect date: 2024-02-25 should likely be 2026-02-15 (or the intended release date).

The changelog entry date appears to be two years in the past. The PR was created on 2026-02-15.

Proposed fix
-## [1.3.0] - 2024-02-25
+## [1.3.0] - 2026-02-15
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
## [1.3.0] - 2024-02-25
## [1.3.0] - 2026-02-15
🤖 Prompt for AI Agents
In `@packages/motionforge/CHANGELOG.md` at line 8, Update the incorrect release
date in the CHANGELOG entry header for version "## [1.3.0]" by replacing
"2024-02-25" with the intended release date "2026-02-15" so the changelog
reflects the PR creation/release date; edit the line that reads '## [1.3.0] -
2024-02-25' to '## [1.3.0] - 2026-02-15'.

Comment on lines +91 to 93
"dependencies": {
"lottie-web": "^5.13.0"
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# Check the motionforge package.json dependencies
cat -n packages/motionforge/package.json | grep -A 5 -B 5 "lottie-web"

Repository: codedbytahir/motionforge

Length of output: 272


🏁 Script executed:

# Check the CLI template for lottie-web version
cat -n shared/package.json.template | grep -A 5 -B 5 "lottie-web"

Repository: codedbytahir/motionforge

Length of output: 128


🏁 Script executed:

# Find if lottie-web or LottieAnimation is used in the codebase
rg -i "lottie" --type ts --type tsx --type js --type jsx

Repository: codedbytahir/motionforge

Length of output: 95


🌐 Web query:

latest version of lottie-web npm package 2025

💡 Result:

The latest lottie-web version on npm released in 2025 is 5.13.0 (it’s also the current latest tag), published ~4 months ago (≈ Oct 2025). [1]

Source: npm package page for lottie-web@5.13.0. [1]

References:
[1] (npmjs.com)

Citations:


🏁 Script executed:

# Search for lottie-web usage without type restrictions
rg "lottie-web" -A 3 -B 1

Repository: codedbytahir/motionforge

Length of output: 3841


🏁 Script executed:

# Search for lottie or LottieAnimation more broadly
rg "lottie" -i -A 2 -B 1

Repository: codedbytahir/motionforge

Length of output: 22590


🏁 Script executed:

# Find if there's a template file with a different name/path
fd "package.*template" -type f

Repository: codedbytahir/motionforge

Length of output: 238


🏁 Script executed:

# List files in shared directory to see what exists
ls -la shared/ 2>/dev/null || echo "shared directory not found"

Repository: codedbytahir/motionforge

Length of output: 94


Update the CLI template to use lottie-web ^5.13.0 to match the main package.

The template at packages/create-motionforge/templates/shared/package.json.template specifies lottie-web ^5.12.2, but packages/motionforge/package.json requires ^5.13.0. These versions don't overlap (^5.12.2 is >=5.12.2 <5.13.0, while ^5.13.0 is >=5.13.0 <5.14.0), which can cause version conflicts when users scaffold a project with the template and install motionforge. Update the template to ^5.13.0.

Regarding the optional dependency suggestion: LottieAnimation is a core, directly-exported component with a top-level import of lottie-web. Making it optional would require dynamic imports and error handling throughout the codebase, which is a significant refactor. Since LottieAnimation is a first-class feature (not a conditional enhancement), keeping it as a hard dependency is reasonable.

🤖 Prompt for AI Agents
In `@packages/motionforge/package.json` around lines 91 - 93, Update the shared
package.json.template to make the lottie-web dependency match the main package:
change the "lottie-web" version specifier from "^5.12.2" to "^5.13.0" in the
create-motionforge CLI template (the shared package.json.template) so newly
scaffolded projects use a compatible lottie-web range that matches the
packages/motionforge package.json.

Comment on lines +110 to 112
const RelativeFrameContext = createContext<number | null>(null);

export const useRelativeCurrentFrame = () => useContext(RelativeFrameContext);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's examine the Sequence.tsx file around the lines mentioned
cat -n packages/motionforge/src/components/Sequence.tsx | sed -n '100,125p'

Repository: codedbytahir/motionforge

Length of output: 946


🏁 Script executed:

# Search for all usages of useRelativeCurrentFrame
rg -n 'useRelativeCurrentFrame' --type=ts --type=tsx -B2 -A4

Repository: codedbytahir/motionforge

Length of output: 95


🏁 Script executed:

# Also search in JS/JSX files in case there are any
find . -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \) | xargs grep -l 'useRelativeCurrentFrame' 2>/dev/null | head -20

Repository: codedbytahir/motionforge

Length of output: 391


🏁 Script executed:

# Check the Lottie.tsx file where useRelativeCurrentFrame is likely used
cat -n packages/motionforge/src/components/Lottie.tsx

Repository: codedbytahir/motionforge

Length of output: 4820


🏁 Script executed:

# Check the index.ts files to see how it's exported
cat -n packages/motionforge/src/index.ts

Repository: codedbytahir/motionforge

Length of output: 5664


🏁 Script executed:

# Get more detailed context around usages
rg 'useRelativeCurrentFrame' --type-add 'tsx:*.tsx' --type-add 'ts:*.ts' -B3 -A3 packages/motionforge/src/ 2>/dev/null || rg 'useRelativeCurrentFrame' -B3 -A3 packages/motionforge/src/

Repository: codedbytahir/motionforge

Length of output: 2347


🏁 Script executed:

# Check if there are other usages in the src/lib/remotion directories
cat -n src/lib/remotion/components/Lottie.tsx 2>/dev/null | head -50

Repository: codedbytahir/motionforge

Length of output: 2005


🏁 Script executed:

# Check the other Sequence file
cat -n src/lib/remotion/components/Sequence.tsx 2>/dev/null | head -50

Repository: codedbytahir/motionforge

Length of output: 1667


🏁 Script executed:

# Search for any other usages in the entire src directory
rg 'useRelativeCurrentFrame' src/ 2>/dev/null || find src -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \) -exec grep -l 'useRelativeCurrentFrame' {} \;

Repository: codedbytahir/motionforge

Length of output: 423


useRelativeCurrentFrame type change properly handled internally.

The type change from number to number | null is a breaking change for external consumers, but internal usage in LottieAnimation correctly handles it with a null check: relativeFrame !== null ? relativeFrame : absoluteFrame. However, external consumers of this exported hook may not handle the null case—document this change in release notes and consider providing a migration guide.

🤖 Prompt for AI Agents
In `@packages/motionforge/src/components/Sequence.tsx` around lines 110 - 112, The
exported hook useRelativeCurrentFrame now returns number | null
(RelativeFrameContext), which is a breaking change for external consumers—update
the release notes and add a short migration guide showing how to handle the null
case (e.g., using relativeFrame !== null ? relativeFrame : absoluteFrame, as
used in LottieAnimation) and include a minimal example snippet and suggested
fallback strategy; also mention the symbols RelativeFrameContext,
useRelativeCurrentFrame, LottieAnimation, relativeFrame and absoluteFrame so
consumers can find the relevant code, and optionally document or add a helper
alternative hook for callers that want a guaranteed number fallback.


import React, { useEffect, useRef, useState } from 'react';
import lottie, { AnimationItem, AnimationConfigWithData, AnimationConfigWithPath } from 'lottie-web';
import { useCurrentFrame, useVideoConfig } from '../core/context';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Unused import: useVideoConfig.

useVideoConfig is imported but never referenced in this component.

Proposed fix
-import { useCurrentFrame, useVideoConfig } from '../core/context';
+import { useCurrentFrame } from '../core/context';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { useCurrentFrame, useVideoConfig } from '../core/context';
import { useCurrentFrame } from '../core/context';
🤖 Prompt for AI Agents
In `@src/lib/remotion/components/Lottie.tsx` at line 5, The import of
useVideoConfig in the Lottie component is unused; remove useVideoConfig from the
import statement that currently reads "import { useCurrentFrame, useVideoConfig
} from '../core/context';" (or alternatively use it inside the Lottie component
if you intended to access video config). Update the import to only include
useCurrentFrame to eliminate the unused-symbol lint error.

const absoluteFrame = useCurrentFrame();
const currentFrame = relativeFrame !== null ? relativeFrame : absoluteFrame;

const [isLoaded, setIsLoaded] = useState(false);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

isLoaded is not reset when src changes — stale state bug.

When src changes, the initialization effect (Line 37) destroys the old animation and creates a new one, but isLoaded remains true from the previous instance. On the next frame change, the sync effect (Line 82) will call goToAndStop on a not-yet-loaded animation because it still sees isLoaded === true.

Reset isLoaded at the start of the initialization effect.

Proposed fix
   // Initialize Lottie instance
   useEffect(() => {
     if (!containerRef.current) return;
+    setIsLoaded(false);

     // Clear container to prevent duplicate renders
     containerRef.current.innerHTML = '';

Also applies to: 67-68, 79-79

🤖 Prompt for AI Agents
In `@src/lib/remotion/components/Lottie.tsx` at line 34, The isLoaded state is not
reset when a new src is initialized, causing stale true state to let the sync
effect call goToAndStop on an unready animation; inside the initialization
useEffect that tears down and recreates the Lottie animation (the effect that
references createAnimation / destroy or the effect where setIsLoaded(true) is
currently set), call setIsLoaded(false) at the start before creating the new
animation so that isLoaded reflects the fresh instance; ensure this change is
applied alongside the existing setIsLoaded(true) in the animation's
load/complete handler so the sync effect (which checks isLoaded) only runs after
the new animation is ready.

anim.destroy();
animationRef.current = null;
};
}, [src]);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Object src as a useEffect dependency will cause infinite re-initialization.

When a consumer passes an inline object literal (e.g., <LottieAnimation src={{ ...data }} />), a new reference is created on every render, causing the [src] dependency to trigger the effect repeatedly — destroying and re-creating the Lottie instance each frame.

Consider accepting a stable reference via useMemo internally, or document that callers must memoize src. A common pattern is to serialize and compare:

Proposed fix — stabilize with useMemo
+import React, { useEffect, useMemo, useRef, useState } from 'react';
 ...
+  // Stabilize object src to avoid re-init on every render
+  const stableSrc = useMemo(
+    () => (typeof src === 'object' ? JSON.parse(JSON.stringify(src)) : src),
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+    [typeof src === 'string' ? src : JSON.stringify(src)]
+  );
+
   useEffect(() => {
     ...
-  }, [src]);
+  }, [stableSrc]);

Alternatively, document that src must be a stable reference (module import or memoized value).

🤖 Prompt for AI Agents
In `@src/lib/remotion/components/Lottie.tsx` at line 79, The effect in the Lottie
component (useEffect in src/lib/remotion/components/Lottie.tsx) depends directly
on the `src` prop which can be a new object each render and cause infinite
re-initialization; update the component to stabilize `src` before using it in
the dependency array (for example, compute a stable key with useMemo or a
serialized string like JSON.stringify(src) and use that key in the dependency
array) and then use that stable reference/key in the effect (keep references to
the Lottie instance creation/cleanup in the same effect), or alternatively
document that the `src` prop must be a stable/memoized reference; ensure you
only change the dependency from `[src]` to the new stable memoized value (e.g.,
`stableSrc` or `srcKey`) and keep instance teardown/creation logic attached to
that stable dependency.

Comment on lines +94 to +103
// Calculate the target frame in the Lottie animation
let lottieFrame = (currentFrame * playbackRate) + frameStart;

if (loop && duration > 0) {
// Loop within the specified window [frameStart, end]
lottieFrame = frameStart + ((lottieFrame - frameStart) % duration);
} else {
// Clamp to the end frame if not looping
lottieFrame = Math.min(lottieFrame, end);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Missing lower-bound clamp — lottieFrame can go below frameStart.

In the non-loop branch (Line 102), lottieFrame is clamped to end but never to frameStart. If currentFrame is 0 and playbackRate is 1, the result is frameStart (correct). But with unusual values (e.g., negative currentFrame from a sequence edge, or playbackRate < 0), lottieFrame can fall below frameStart or even below 0, which would be out of bounds for lottie-web.

Proposed fix
     } else {
       // Clamp to the end frame if not looping
-      lottieFrame = Math.min(lottieFrame, end);
+      lottieFrame = Math.max(frameStart, Math.min(lottieFrame, end));
     }
+
+    // Ensure we never go below 0
+    lottieFrame = Math.max(0, lottieFrame);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Calculate the target frame in the Lottie animation
let lottieFrame = (currentFrame * playbackRate) + frameStart;
if (loop && duration > 0) {
// Loop within the specified window [frameStart, end]
lottieFrame = frameStart + ((lottieFrame - frameStart) % duration);
} else {
// Clamp to the end frame if not looping
lottieFrame = Math.min(lottieFrame, end);
}
// Calculate the target frame in the Lottie animation
let lottieFrame = (currentFrame * playbackRate) + frameStart;
if (loop && duration > 0) {
// Loop within the specified window [frameStart, end]
lottieFrame = frameStart + ((lottieFrame - frameStart) % duration);
} else {
// Clamp to the end frame if not looping
lottieFrame = Math.max(frameStart, Math.min(lottieFrame, end));
}
// Ensure we never go below 0
lottieFrame = Math.max(0, lottieFrame);
🤖 Prompt for AI Agents
In `@src/lib/remotion/components/Lottie.tsx` around lines 94 - 103, The non-loop
branch for computing lottieFrame (variables: lottieFrame, currentFrame,
playbackRate, frameStart, end, duration, loop) only clamps the upper bound to
end and can produce values below frameStart; change the non-loop logic to clamp
lottieFrame between frameStart and end (and optionally ensure it is not negative
by clamping to Math.max(frameStart, 0) if needed) so the value passed to
lottie-web is always within the valid window.

Comment on lines +51 to +61
<div style={{ width: 300, textAlign: 'center' }}>
<Sequence from={60} durationInFrames={120}>
<div style={{ height: 200, background: '#1e293b', borderRadius: 12, overflow: 'hidden', marginBottom: 10 }}>
<LottieAnimation
src={sampleLottie}
loop
/>
</div>
<Text style={{ fontSize: 16 }}>Inside Sequence (Starts at frame 60)</Text>
</Sequence>
</div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Layout bug: Sequence's default absolute-fill layout breaks the card container.

The Sequence component defaults to layout='absolute-fill' (see Sequence.tsx Line 73: position: 'absolute'). This means the content inside the Sequence will escape the width: 300 parent div and fill the nearest positioned ancestor — the root AbsoluteFill — overlaying the entire viewport instead of staying inside the card.

The other three demo blocks work correctly because they don't use Sequence.

Proposed fix: use `layout="none"` on the Sequence
-        <div style={{ width: 300, textAlign: 'center' }}>
-          <Sequence from={60} durationInFrames={120}>
+        <div style={{ width: 300, textAlign: 'center', position: 'relative' }}>
+          <Sequence from={60} durationInFrames={120} layout="none">
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div style={{ width: 300, textAlign: 'center' }}>
<Sequence from={60} durationInFrames={120}>
<div style={{ height: 200, background: '#1e293b', borderRadius: 12, overflow: 'hidden', marginBottom: 10 }}>
<LottieAnimation
src={sampleLottie}
loop
/>
</div>
<Text style={{ fontSize: 16 }}>Inside Sequence (Starts at frame 60)</Text>
</Sequence>
</div>
<div style={{ width: 300, textAlign: 'center', position: 'relative' }}>
<Sequence from={60} durationInFrames={120} layout="none">
<div style={{ height: 200, background: '#1e293b', borderRadius: 12, overflow: 'hidden', marginBottom: 10 }}>
<LottieAnimation
src={sampleLottie}
loop
/>
</div>
<Text style={{ fontSize: 16 }}>Inside Sequence (Starts at frame 60)</Text>
</Sequence>
</div>
🤖 Prompt for AI Agents
In `@src/lib/remotion/demo/LottieDemo.tsx` around lines 51 - 61, The Sequence in
LottieDemo.tsx is using its default absolute-fill layout which causes its
children to escape the 300px card container; update the Sequence instance (the
one wrapping the LottieAnimation and Text) to set layout="none" so its content
remains positioned inside the parent div, keeping the existing
from/durationInFrames props intact and not altering the surrounding container
styles.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant