Commit 3494067
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
- apps
- dotcom/client/src/tla
- utils
- examples/e2e/tests/export-snapshots.spec.tsx-snapshots
- packages/editor
- src/lib
- editor
- types
- exports
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
| 92 | + | |
92 | 93 | | |
93 | 94 | | |
94 | 95 | | |
| |||
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
230 | 230 | | |
231 | 231 | | |
232 | 232 | | |
233 | | - | |
| 233 | + | |
234 | 234 | | |
235 | 235 | | |
236 | 236 | | |
| |||
346 | 346 | | |
347 | 347 | | |
348 | 348 | | |
349 | | - | |
| 349 | + | |
350 | 350 | | |
351 | 351 | | |
352 | 352 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
| 57 | + | |
58 | 58 | | |
59 | 59 | | |
60 | 60 | | |
| |||
0 commit comments