Skip to content

Fix CV PDF export layout and preserve scroll-reveal animations#57

Open
google-labs-jules[bot] wants to merge 2 commits into
mainfrom
jules/fix-cv-pdf-export-animations-js0-83eeafcc-b4e6-4091-9a98-f56c1a48db57
Open

Fix CV PDF export layout and preserve scroll-reveal animations#57
google-labs-jules[bot] wants to merge 2 commits into
mainfrom
jules/fix-cv-pdf-export-animations-js0-83eeafcc-b4e6-4091-9a98-f56c1a48db57

Conversation

@google-labs-jules

Copy link
Copy Markdown
Contributor

Summary

This PR resolves critical rendering issues with the client-side CV PDF export functionality. It ensures a complete, clean PDF render (with off-screen elements fully visible and web-only interactive links omitted) while completely preserving the integrity and state of scroll-reveal animations on the live web page post-export.

Why These Changes are Necessary

Previously, generating a PDF of the CV was prone to timing mismatches and layout issues:

  1. Race Conditions: The PDF compilation (html2pdf) was triggered synchronously right after setting showLinks = false. Because Svelte's DOM updates are batched, the snapshot was often taken before the DOM updated, resulting in web-only links appearing in the final PDF.
  2. Broken Scroll Animations: Off-screen elements that had not yet been scrolled into view lacked reveal styles and rendered as blank spaces. Attempting to force visibility on individual elements permanently broke the IntersectionObserver bindings and animation states, ruining the interactive web experience once the export was complete.

Key Architectural Decisions

  • Asynchronous DOM Synchronization: We transitioned exportCVPDF() in src/routes/cv/+page.svelte to an async flow. By utilizing Svelte's native tick(), we guarantee that Svelte's reactive rendering queue finishes updating the DOM and web-only elements are fully omitted before the PDF compiler takes its snapshot.
  • Parent-Level CSS Overrides: Instead of dynamically stripping or mutating .reveal and .reveal-stagger classes on individual elements (which broke active observers), we keep these classes static. During the export process, we temporarily append an .exporting-pdf class to document.body.
  • Non-destructive Visibility Overrides: Under the .exporting-pdf scope, we apply clean CSS overrides to force complete visibility and bypass transforms/transitions on all revealable elements for the PDF engine without modifying their actual state:
    .exporting-pdf .reveal {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
  • Guaranteed State Restoration: We wrapped the compilation sequence inside a try...finally block. This guarantees that regardless of compilation success or failure, the .exporting-pdf class is removed and showLinks is restored, bringing back default interactive behaviors with zero UI flicker, layout shift, or page reloads.

Detailed Changes

  • src/routes/cv/+page.svelte:
    • Refactored exportCVPDF to be async.
    • Added await tick() after updating showLinks = false.
    • Handled the dynamic addition and removal of the .exporting-pdf class on document.body inside a try...finally block.
    • Removed dynamic class toggles for reveal sections, making .reveal and .reveal-stagger static.
  • src/app.css:
    • Implemented print-bypass styles under the .exporting-pdf class to force instant layout rendering for hidden off-screen elements.

Verification & Acceptance Criteria

  • All text sections are perfectly captured in the generated PDF, regardless of scroll position.
  • Interactive web-only links are cleanly excluded from the PDF layout.
  • Scroll animations on the live site remain fully functional and smooth immediately after downloading.
  • Zero layout shifts, flashes, or flickers are observed on the live UI during the generation sequence.

@google-labs-jules

Copy link
Copy Markdown
Contributor Author

[CI/CD Fix Attempt 1] Fixed Prettier formatting issue in src/routes/cv/+page.svelte that was causing the CI lint step to fail.

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.

0 participants