Exporting Character Sheets
Relevant source files
The following files were used as context for generating this wiki page:
The Character Sheet Maker provides a "Local-First" experience, allowing users to design, customize, and save their character sheets. A core part of this functionality is the ability to export the final sheet into common, portable formats. This system converts the on-screen HTML canvas into high-quality PNG images or A4-sized PDF documents, which can be saved locally, printed, or shared.
The entire export process is handled on the client-side using JavaScript libraries to capture the state of the character sheet canvas and package it for download. The user initiates this process through the main application header.
Sources: README.md, src/lib/exportUtils.ts
Architecture and Dependencies
The export functionality is built upon two key third-party libraries defined in the project's dependencies. The core logic is encapsulated within the exportUtils.ts module, which is then invoked by the UI components.
Sources: package.json, src/lib/exportUtils.ts
Core Libraries
| Library | Version | Purpose |
|---|---|---|
html-to-image | ^1.11.13 | Converts a DOM node (the character sheet canvas) into a PNG data URL. |
jspdf | ^3.0.4 | Creates a PDF document and embeds the generated image into it. |
Sources: package.json:20-21
Component & Module Interaction
The following diagram illustrates how the UI components and utility modules interact to perform an export.
This diagram shows that the TopBar component, rendered within the Editor page, contains the trigger for export actions. These actions call functions in exportUtils.ts, which in turn use external libraries to read the #rpg-sheet-canvas element from the Canvas component and produce a file for download.
Sources: src/pages/Editor.tsx:13, src/components/layout/TopBar.tsx:44-56, src/lib/exportUtils.ts, src/components/sheet/Canvas.tsx:28
User Interface
The export functionality is exposed to the user through a dropdown menu in the TopBar component, which is present at the top of the editor view.
Sources: src/components/layout/TopBar.tsx
Export Dropdown
An "Export" button, styled with an icon and text, acts as the trigger for a DropdownMenu. This menu presents the user with two options: "Download PNG" and "Download PDF".
| Menu Item | Icon | Action Triggered |
|---|---|---|
Download PNG | FileImage | downloadAsImage() |
Download PDF | FileText | downloadAsPDF() |
Each DropdownMenuItem has an onClick event handler that calls the corresponding export function from exportUtils.ts.
Sources: src/components/layout/TopBar.tsx:44-56, src/components/ui/dropdown-menu.tsx
// src/components/layout/TopBar.tsx:44-56
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button /* ... */ >
<Download size={14} />
Export
<ChevronDown size={12} />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="w-40 dark:text-white">
<DropdownMenuItem onClick={downloadAsImage} /* ... */ >
<FileImage size={14} />
<span>Download PNG</span>
</DropdownMenuItem>
<DropdownMenuItem onClick={downloadAsPDF} /* ... */ >
<FileText size={14} />
<span>Download PDF</span>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
Export Process
The core logic resides in src/lib/exportUtils.ts, which provides two asynchronous functions: downloadAsImage and downloadAsPDF. Both functions target the same DOM element: <div id="rpg-sheet-canvas">.
Sources: src/lib/exportUtils.ts:4, 24, src/components/sheet/Canvas.tsx:28
PNG Export
The downloadAsImage function handles the direct conversion of the canvas to a PNG image.
The sequence diagram below shows the user interaction and function calls for a PNG export.
The process is as follows:
- The function retrieves the DOM element with the ID
rpg-sheet-canvas. - It calls
toPngfromhtml-to-image, passing the element and configuration options.pixelRatio: 2is used to generate a higher-resolution image, preserving quality.cacheBust: trueensures the latest version of the canvas is captured.
- A temporary
<a>(anchor) element is created in memory. - The
hrefis set to thedataUrlreturned bytoPng, and thedownloadattribute is set to the desired filename. - The link's
click()method is called to initiate the browser's download process.
Sources: src/lib/exportUtils.ts:3-18
PDF Export
The downloadAsPDF function is a multi-step process that first generates an image and then embeds it into a PDF document.
The sequence diagram below shows the user interaction and function calls for a PDF export.
The process is as follows:
- An image is generated using
toPng, identical to the first step of the PNG export. - A new
jsPDFinstance is created, configured for a portrait A4 page in millimeters. - The properties of the generated image (width, height) are retrieved.
- To prevent stretching, a proportional height for the PDF image is calculated based on the A4 page width.
- The image is added to the PDF document at position (0, 0) with the calculated dimensions.
- The
save()method is called on the PDF instance to trigger the download.
Sources: src/lib/exportUtils.ts:20-40
Content Filtering
To ensure a clean output, certain non-content elements are excluded from the exported image. A filter function is defined in exportUtils.ts for this purpose, although it is not currently implemented in the downloadAsImage or downloadAsPDF calls. The function is designed to check if a node contains specific classes and exclude it if it does.
The classes intended for exclusion are:
react-grid-placeholder: The visual placeholder for a grid item being dragged.grid-drag-handle: A handle for dragging elements (not currently visible in the codebase but planned for).
Sources: src/lib/exportUtils.ts:42-47