Skip to content

fix: fix gradient background export rendering#237

Merged
siddharthvaddem merged 2 commits intosiddharthvaddem:mainfrom
ryujh030820:fix/gradient-export-rendering
Mar 20, 2026
Merged

fix: fix gradient background export rendering#237
siddharthvaddem merged 2 commits intosiddharthvaddem:mainfrom
ryujh030820:fix/gradient-export-rendering

Conversation

@ryujh030820
Copy link
Contributor

@ryujh030820 ryujh030820 commented Mar 18, 2026

Description

Fixes an export-only background rendering issue where certain gradient backgrounds, especially the first preset using rgba(...) color stops, were not rendered correctly in exported video output.

Motivation

The editor preview displayed these gradients correctly via CSS, but the export pipeline used a custom gradient parser that split on every comma. That broke gradients containing rgba(...) values, causing the
exported background to disappear or fall back incorrectly. This change makes export parsing robust and aligns export behavior with the preview.

Type of Change

  • New Feature
  • Bug Fix
  • Refactor / Code Cleanup
  • Documentation Update
  • Other (please specify)

Related Issue(s)

#236

Screenshots / Video

Screenshot (if applicable):

before:
Screenshot 2026-03-18 at 1 44 42 PM
after:
Screenshot 2026-03-18 at 2 01 46 PM

Testing

  1. Select a gradient background in the editor, including the first preset with rgba(...) stops.
  2. Export the video and confirm the background is rendered in the output.
  3. Compare the exported result against the editor preview.

Commands run:

npm exec biome check -- src/lib/exporter/frameRenderer.ts src/lib/exporter/gradientParser.ts src/lib/exporter/gradientParser.test.ts
npm exec vitest -- run src/lib/exporter/gradientParser.test.ts src/lib/exporter/gifExporter.test.ts
npm exec tsc -- --noEmit

Checklist

  • I have performed a self-review of my code.
  • I have added any necessary screenshots or videos.
  • I have linked related issue(s) and updated the changelog if applicable.

Thank you for contributing!

Summary by CodeRabbit

  • New Features

    • Improved gradient handling for frame exports with robust parsing and accurate linear/radial geometry, producing more faithful rendered wallpapers.
    • Adds a reusable gradient parsing/evaluation toolkit used by the renderer.
  • Bug Fixes

    • Adds a safe fallback: when gradient parsing fails, exports use a solid background and emit a warning to avoid broken renders.
  • Tests

    • Added comprehensive tests covering gradient parsing and geometry.

@coderabbitai
Copy link

coderabbitai bot commented Mar 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 56579f7f-ecc5-428f-9ff1-3fcb5868de10

📥 Commits

Reviewing files that changed from the base of the PR and between 038d6c4 and 7965068.

📒 Files selected for processing (1)
  • src/lib/exporter/frameRenderer.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/lib/exporter/frameRenderer.ts

📝 Walkthrough

Walkthrough

Introduces a standalone CSS gradient parser and geometry helpers, adds tests, and updates the frame renderer to use the parser for linear and radial wallpaper gradients with a fallback on parse failure.

Changes

Cohort / File(s) Summary
Gradient Parsing Module
src/lib/exporter/gradientParser.ts
New module: parseCssGradient (linear/radial), ParsedGradient/ParsedGradientStop interfaces, geometry helpers (resolveLinearGradientAngle, getLinearGradientPoints, getRadialGradientShape), parsing utilities (split, color-stop parsing, offset normalization) and helpers (clamp, findLastDefinedIndex).
Gradient Parser Tests
src/lib/exporter/gradientParser.test.ts
New tests covering rgba/hex gradients, stop offsets, angle resolution, linear endpoint computation, and radial shape/radius calculations.
Frame Renderer Integration
src/lib/exporter/frameRenderer.ts
Replaces inline gradient parsing with parseCssGradient(wallpaper) usage; applies parsed color stops and computed geometry for linear and radial gradients; adds parse-failure fallback (fills #000000 and logs a warning). Minor formatting refactors for canvas context/options and destroy call object shape.

Sequence Diagram(s)

sequenceDiagram
    participant Renderer as FrameRenderer
    participant Parser as GradientParser
    participant Canvas as Canvas2DContext

    Renderer->>Parser: parseCssGradient(wallpaper)
    Parser-->>Renderer: ParsedGradient (type, descriptor, stops)
    Renderer->>Parser: resolveLinearGradientAngle / getLinearGradientPoints\nor getRadialGradientShape(width,height)
    Parser-->>Renderer: geometry (points/center,radius)
    Renderer->>Canvas: createGradient(...) and addColorStop(offset,color)
    Renderer->>Canvas: fillRect / fill with gradient
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Poem

🐇 I parsed the hues with nimble paws and cheer,
Stops aligned like carrots, bright and clear,
Angles traced and circles found their place,
The canvas sipped the colors with a grace,
A rabbit's cheer — the gradients appear! 🎨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: fix gradient background export rendering' directly addresses the main change—fixing gradient background export rendering issues with rgba color stops.
Description check ✅ Passed The description covers all required template sections: description, motivation, type of change, related issue, screenshots, testing steps, and checklist. It is comprehensive and detailed.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
📝 Coding Plan
  • Generate coding plan for human review comments

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

Tip

CodeRabbit can use Trivy to scan for security misconfigurations and secrets in Infrastructure as Code files.

Add a .trivyignore file to your project to customize which findings Trivy reports.

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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/exporter/gradientParser.ts`:
- Around line 34-46: The current logic silently drops stops that parseColorStop
cannot represent causing partial gradients to be treated as successful; update
the parsing branch so that if any stop fails (i.e., parseColorStop returns null
for any element of stopArgs) the function returns null instead of filtering them
out. Concretely, after mapping stopArgs with parseColorStop (the parsedStops
variable), check whether parsedStops length matches stopArgs length or use
parsedStops.includes(null)/some(...) to detect failures and return null; only
call normalizeStopOffsets and return the gradient object when all stops parsed
successfully.
- Around line 90-106: getRadialGradientShape currently only handles "at"
position and always returns a circular radius using Math.max(...distances),
ignoring radial keywords accepted by isGradientDescriptor (like ellipse,
closest-side, closest-corner, farthest-side, farthest-corner), which yields
incorrect shapes on non-square canvases; update getRadialGradientShape to parse
the shape/extent tokens (e.g. "ellipse" vs "circle" and "closest-*/farthest-*")
in the descriptor, compute ellipse radii (radiusX, radiusY) when "ellipse" is
specified using distances to edges in x and y, and select min/distances for
"closest-*" or max for "farthest-*" (and side vs corner differences) to return
appropriate cx, cy and either a single radius for circles or separate radii for
ellipses; alternatively, if you prefer rejecting unsupported descriptors, have
getRadialGradientShape validate against isGradientDescriptor's accepted keywords
and throw or return null for unimplemented tokens so callers can handle the
error.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 67607f51-561e-4115-be61-80e701c52a14

📥 Commits

Reviewing files that changed from the base of the PR and between 4563641 and 038d6c4.

📒 Files selected for processing (3)
  • src/lib/exporter/frameRenderer.ts
  • src/lib/exporter/gradientParser.test.ts
  • src/lib/exporter/gradientParser.ts

@siddharthvaddem siddharthvaddem merged commit adc0cf7 into siddharthvaddem:main Mar 20, 2026
5 checks passed
@ryujh030820 ryujh030820 deleted the fix/gradient-export-rendering branch March 20, 2026 01:54
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.

2 participants