fix(export): render gradient backgrounds correctly in exported video#672
fix(export): render gradient backgrounds correctly in exported video#672soufian3hm wants to merge 1 commit into
Conversation
Gradient wallpapers were parsed with `params.split(",")`, which splits the
commas inside `rgba()`/`hsla()` color functions. The color regex then matched
the bare token `rgba`, `addColorStop` threw, and the outer try/catch fell back
to a solid black background — so every rgba()/radial preset exported as black.
For hex presets the leading direction token (`120deg`, `to right`, …) consumed
color-stop index 0, pushing the first color to offset 0.5 and ignoring the
explicit `0%/100%` stops, so even those gradients rendered wrong.
Extract a parenthesis-aware, position-honoring parser into a pure, unit-tested
helper (`parseGradientBackground`) and use it from both the modern and legacy
frame renderers. Canvas geometry is unchanged to keep the fix minimal.
|
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
📝 WalkthroughWalkthroughA new ChangesGradient parsing extraction and integration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
|
Summary
Gradient wallpaper backgrounds render correctly in the editor preview (real CSS) but are corrupted in the exported video. Depending on the preset, the export shows either a solid black background or a mangled gradient with shifted color stops. This affects the entire built-in gradient palette (
GRADIENTSinSettingsPanel.tsx, ~24 presets).Root cause
Both frame renderers parsed the gradient string with a naive
params.split(","):This is wrong in two independent ways:
rgba()/hsla()colors get shredded.rgba(114,167,232,1)is split into the fragmentsrgba(114,167,232,1). The color regex (…|[a-z]+) then matches the literal tokenrgba,addColorStop()throws on the invalid color, and the surroundingtry/catchfalls back to filling the canvas black. Everyrgba(...)andradial-gradientpreset (about half the palette) exports as a black background.Color-stop offsets are taken from the split-token index. A leading direction token (
120deg,to right, …) occupies index 0, so the first real color is placed at offset1/(n-1)= 0.5 instead of 0, and the explicit0% / 100%stop positions in the string are ignored. So even pure-hex presets render with the gradient compressed into the bottom half of the frame.Reproduction of the current behavior on real presets:
linear-gradient( 111.6deg, rgba(114,167,232,1) 9.4%, … )radial-gradient( circle farthest-corner at …, rgba(80,12,139,0.87) 0%, … )linear-gradient(120deg, #d4fc79 0%, #96e6a1 100%)Fix
Extract a parenthesis-aware, position-honoring parser into a new pure helper,
src/lib/exporter/gradientBackground.ts(parseGradientBackground):rgba()/hsla()colors stay intact;to …,<angle>deg,circle … at …) so it is not mistaken for a color;%stop positions, distributes evenly when omitted, interpolates interior gaps, and clamps offsets to a non-decreasing[0, 1]range soaddColorStopnever throws.Both the modern (
modernFrameRenderer.ts) and legacy (frameRenderer.ts) renderers now consume this helper. Canvas geometry is intentionally unchanged (linear stays top→bottom, radial stays centered) to keep the change minimal and low-risk — honoring the gradient angle is a separate enhancement.Why it works
The new tokenizer keeps
rgba(231, 148, 6, 1)(commas and spaces included) as a single color, and offsets come from the parsed stop positions instead of the split index, so the exported gradient matches the editor preview. Validated against all 24 built-in presets.Risks
Low. The helper is pure and isolated; the renderer diff only swaps the inline parser for a function call while preserving the existing fallback-to-black behavior for unparseable input. No public API or geometry change.
Testing
src/lib/exporter/gradientBackground.test.ts(11 cases): rgba preservation, direction stripping, radial shape stripping, explicit/even/interpolated stop positions, clamping/ordering, named colors, and a sweep asserting every built-in preset parses into valid, ordered, non-rgba-fragment stops.vitest run src/lib/exporter/gradientBackground.test.ts→ 11 passed; full local timeline/exporter unit suites green (18/18 in the focused run).tsc --noEmit: no errors introduced in the changed files.Summary by CodeRabbit
Refactor
Tests