Skip to content

Commit 3494067

Browse files
steveruizokhuppy-bot[bot]claude
authored
fix(export): trim exports to visual content bounds with auto padding (tldraw#8202)
In order to prevent visual overflow (thick strokes, arrowheads, etc.) from being clipped in exports while avoiding unnecessary whitespace, this PR introduces an `'auto'` padding mode that renders with default padding then trims to actual visual content bounds. Clean reimplementation of [`fix/export-visual-overflow`](https://github.com/tldraw/tldraw/tree/fix/export-visual-overflow). ### Change type - [x] `improvement` ### Test plan 1. Export shapes with visual overflow (thick borders, arrowheads extending beyond bounds) 2. Verify the export captures the full visual content without clipping 3. Verify no extra whitespace around the content 4. Test with explicit numeric padding — should behave as before (fixed padding, no trimming) 5. Test frame exports — should still use frame bounds without padding - [x] Unit tests - [x] End to end tests ### API changes - Changed `TLSvgExportOptions.padding` from `number` to `number | 'auto'` - `'auto'` (default): renders with default padding, trims to visual content - `number`: fixed padding, no trimming (previous behavior with explicit padding) - Added `getSvgAsImageWithOptions` (internal) — returns `{ blob, width, height }` instead of bare `Blob` - Added `trimSvgToContent` (internal) — trims SVG viewBox to visual content bounds ### Release notes - Exports now automatically trim to visual content bounds, capturing overflow (strokes, arrowheads) without extra whitespace - The `padding` export option now accepts `'auto'` to enable this behavior (default) ### Code changes | Section | LOC change | | --------------- | ----------- | | Core code | +354 / -30 | | Tests | +103 / -101 | | Automated files | +3 / -1 (+ 44 binary snapshots) | | Apps | +3 / -3 | | Config/tooling | +1 / -0 | <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Medium Risk** > Changes core export rendering and introduces a new `'auto'` padding mode in the public `TLSvgExportOptions` API; incorrect trimming/cropping could affect all exported PNG/JPEG/WebP/SVG outputs. > > **Overview** > Exports now support a new **`padding: 'auto'` mode** (and make it the default behavior when `padding` isn’t a number) that renders with default padding to capture visual overflow, then trims back to the actual visual content bounds to avoid extra whitespace. > > This threads a new `trimPadding` value through `getSvgJsx` → `exportToSvg` → `Editor.getSvgElement/getSvgString` and updates `Editor.toImage` to trim both raster exports (via a new internal `getSvgAsImageWithOptions` canvas pipeline) and SVG exports (via a new internal `trimSvgToContent` that adjusts the SVG viewBox/dimensions). App export UI defaults were adjusted and the export calls now pass `'auto'` when padding is toggled off; related unit tests were updated to match the new bounds return shape and padding-applied signaling. > > <sup>Written by [Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit 880d9ec. This will update automatically on new commits. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY --> --------- Co-authored-by: huppy-bot[bot] <128400622+huppy-bot[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent e7da725 commit 3494067

54 files changed

Lines changed: 467 additions & 159 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ apps/examples/www/index.js
8989

9090
apps/examples/build.esbuild.json
9191

92+
test-results
9293
apps/examples/e2e/test-results
9394
apps/examples/playwright-report
9495
apps/dotcom/client/test-results

apps/dotcom/client/src/tla/components/TlaFileShareMenu/Tabs/TlaExportTab.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ function ExportImageButton() {
230230
}
231231

232232
const opts = {
233-
padding: exportPadding ? editor.options.defaultSvgPadding : 0,
233+
padding: exportPadding ? editor.options.defaultSvgPadding : ('auto' as const),
234234
background: exportBackground,
235235
darkMode: exportTheme === 'auto' ? undefined : exportTheme === 'dark',
236236
format: exportFormat as TLExportType,
@@ -346,7 +346,7 @@ async function getEditorImage(
346346
const result = await editor.toImage(shapes, {
347347
scale,
348348
format: 'png',
349-
padding: exportPadding ? editor.options.defaultSvgPadding : 0,
349+
padding: exportPadding ? editor.options.defaultSvgPadding : ('auto' as const),
350350
background: exportBackground,
351351
darkMode: exportTheme === 'auto' ? undefined : exportTheme === 'dark',
352352
})

apps/dotcom/client/src/tla/utils/local-session-state.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const defaultSessionState: TldrawAppSessionState = {
5454
exportFormat: 'png',
5555
exportTheme: 'auto',
5656
exportBackground: true,
57-
exportPadding: true,
57+
exportPadding: false,
5858
},
5959
sidebarWidth: 260,
6060
}
-663 Bytes
-663 Bytes
-415 Bytes
-415 Bytes
-1.23 KB
-1.31 KB
-1.72 KB

0 commit comments

Comments
 (0)