Add component for viewing an image of a snapshot (#2804)

This PR adds the `TldrawImage` component that displays a tldraw snapshot
as an SVG image.

![2024-02-15 at 12 29 52 - Coral
Cod](https://github.com/tldraw/tldraw/assets/15892272/14140e9e-7d6d-4dd3-88a3-86a6786325c5)

## Why

We've seen requests for this kind of thing from users. eg: GitBook, and
on discord:

<img width="710" alt="image"
src="https://github.com/tldraw/tldraw/assets/15892272/3d3a3e9d-66b9-42e7-81de-a70aa7165bdc">

The component provides a way to do that.
This PR also untangles various bits of editor state from image
exporting, which makes it easier for library users to export images more
agnostically. (ie: they can now export any shapes on any page in any
theme. previously, they had to change the user's state to do that).

## What else

- This PR also adds an **Image snapshot** example to demonstrate the new
component.
- We now pass an `isDarkMode` property to the `toSvg` method (inside the
`ctx` argument). This means that `toSvg` doesn't have to rely on editor
state anymore. I updated all our `toSvg` methods to use it.
- See code comments for more info.

## Any issues?

When you toggle to editing mode in the new example, text measurements
are initially wrong (until you edit the size of a text shape). Click on
the text shape to see how its indicator is wrong. Not sure why this is,
or if it's even related. Does it ring a bell with anyone? If not, I'll
take a closer look. (fixed, see comments --steve)

## Future work

Now that we've untangled image exporting from editor state, we could
expose some more helpful helpers for making this easier.

Fixes tld-2122

### Change Type

- [x] `minor` — New feature

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Test Plan

1. Open the **Image snapshot** example.
2. Try editing the image, saving the image, and making sure the image
updates.

- [ ] Unit Tests
- [ ] End to end tests

### Release Notes

- Dev: Added the `TldrawImage` component.

---------

Co-authored-by: Steve Ruiz <steveruizok@gmail.com>
This commit is contained in:
Lu Wilson 2024-02-16 13:54:48 +00:00 committed by GitHub
parent dd67577fea
commit 212eb88480
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
26 changed files with 1159 additions and 70 deletions

View file

@ -0,0 +1,10 @@
---
title: Tldraw image component
component: ./TldrawImageExample.tsx
category: ui
priority: 3
---
Display a tldraw snapshot as an image by using the `TldrawImage` component.
---

View file

@ -0,0 +1,107 @@
import { Box, Editor, StoreSnapshot, TLPageId, TLRecord, Tldraw, TldrawImage } from '@tldraw/tldraw'
import '@tldraw/tldraw/tldraw.css'
import { useState } from 'react'
import initialSnapshot from './snapshot.json'
// There's a guide at the bottom of this file!
export default function TldrawImageExample() {
const [editor, setEditor] = useState<Editor>()
const [snapshot, setSnapshot] = useState<StoreSnapshot<TLRecord>>(initialSnapshot)
const [currentPageId, setCurrentPageId] = useState<TLPageId | undefined>()
const [showBackground, setShowBackground] = useState(true)
const [isDarkMode, setIsDarkMode] = useState(false)
const [viewportPageBounds, setViewportPageBounds] = useState(new Box(0, 0, 600, 400))
const [isEditing, setIsEditing] = useState(false)
const [format, setFormat] = useState<'svg' | 'png'>('svg')
return (
<div style={{ padding: 30 }}>
<div>
<button
style={{ cursor: 'pointer', marginRight: 8 }}
onClick={() => {
if (isEditing) {
if (!editor) return
setIsDarkMode(editor.user.getIsDarkMode())
setShowBackground(editor.getInstanceState().exportBackground)
setViewportPageBounds(editor.getViewportPageBounds())
setCurrentPageId(editor.getCurrentPageId())
setSnapshot(editor.store.getSnapshot())
setIsEditing(false)
} else {
setIsEditing(true)
}
}}
>
{isEditing ? '✓ Save drawing' : '✎ Edit drawing'}
</button>
{!isEditing && (
<>
<label htmlFor="format" style={{ marginRight: 8 }}>
Format
</label>
<select
name="format"
value={format}
onChange={(e) => {
setFormat(e.currentTarget.value as 'svg' | 'png')
}}
>
<option value="svg">SVG</option>
<option value="png">PNG</option>
</select>
</>
)}
</div>
<div style={{ width: 600, height: 400, marginTop: 15 }}>
{isEditing ? (
<Tldraw
snapshot={snapshot}
onMount={(editor: Editor) => {
setEditor(editor)
editor.updateInstanceState({ isDebugMode: false })
editor.user.updateUserPreferences({ isDarkMode })
if (currentPageId) {
editor.setCurrentPage(currentPageId)
}
if (viewportPageBounds) {
editor.zoomToBounds(viewportPageBounds, { inset: 0 })
}
}}
/>
) : (
<TldrawImage
//[1]
snapshot={snapshot}
// [2]
pageId={currentPageId}
// [3]
background={showBackground}
darkMode={isDarkMode}
bounds={viewportPageBounds}
padding={0}
scale={1}
format={format}
/>
)}
</div>
</div>
)
}
/*
This example shows how to use the `TldrawImage` component to display a snapshot
as an image. The example also allows you to toggle between editing the snapshot
and viewing it.
[1] Pass your snapshot to the `snapshot` prop of the `TldrawImage` component.
[2] You can specify which page to display by using the `pageId` prop. By
default, the first page is shown.
[3] You can customize the appearance of the image by passing other props to the
`TldrawImage` component. For example, you can toggle the background, set the
dark mode, and specify the viewport bounds.
*/

View file

@ -0,0 +1,454 @@
{
"store": {
"document:document": {
"gridSize": 10,
"name": "",
"meta": {},
"id": "document:document",
"typeName": "document"
},
"page:3qj9EtNgqSCW_6knX2K9_": {
"meta": {},
"id": "page:3qj9EtNgqSCW_6knX2K9_",
"name": "Page 1",
"index": "a1",
"typeName": "page"
},
"asset:imageAssetA": {
"type": "image",
"props": {
"w": 1200,
"h": 800,
"name": "",
"isAnimated": false,
"mimeType": "png",
"src": ""
},
"meta": {},
"id": "asset:imageAssetA",
"typeName": "asset"
},
"shape:EHeAIsYe4xu1-kGxK-Tl_": {
"x": 108.01190683749454,
"y": 138.58783300957418,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "draw",
"props": {
"segments": [
{
"type": "free",
"points": [
{ "x": 0, "y": 0, "z": 0.5 },
{ "x": -0.07, "y": 0.07, "z": 0.5 },
{ "x": -0.03, "y": 0.14, "z": 0.5 },
{ "x": 0.47, "y": 0.14, "z": 0.5 },
{ "x": 3.54, "y": 0.14, "z": 0.5 },
{ "x": 10.47, "y": -1.05, "z": 0.5 },
{ "x": 17.57, "y": -3.65, "z": 0.5 },
{ "x": 24.13, "y": -7.67, "z": 0.5 },
{ "x": 31.36, "y": -13.59, "z": 0.5 },
{ "x": 36.65, "y": -20.16, "z": 0.5 },
{ "x": 39.27, "y": -26.49, "z": 0.5 },
{ "x": 40.12, "y": -32.21, "z": 0.5 },
{ "x": 40.11, "y": -37.65, "z": 0.5 },
{ "x": 39.45, "y": -41.67, "z": 0.5 },
{ "x": 36.85, "y": -44.45, "z": 0.5 },
{ "x": 33.68, "y": -46.36, "z": 0.5 },
{ "x": 30.91, "y": -46.85, "z": 0.5 },
{ "x": 27.84, "y": -46.77, "z": 0.5 },
{ "x": 24.96, "y": -45.3, "z": 0.5 },
{ "x": 22.43, "y": -42.1, "z": 0.5 },
{ "x": 20.4, "y": -36.5, "z": 0.5 },
{ "x": 19.37, "y": -26.9, "z": 0.5 },
{ "x": 19.17, "y": -14.09, "z": 0.5 },
{ "x": 21.12, "y": 1.65, "z": 0.5 },
{ "x": 25.48, "y": 20.19, "z": 0.5 },
{ "x": 29.24, "y": 36.72, "z": 0.5 },
{ "x": 31.85, "y": 53.01, "z": 0.5 },
{ "x": 33.37, "y": 70.4, "z": 0.5 },
{ "x": 33.2, "y": 84.67, "z": 0.5 },
{ "x": 30.57, "y": 95.01, "z": 0.5 },
{ "x": 24.99, "y": 101.14, "z": 0.5 },
{ "x": 17.55, "y": 103.88, "z": 0.5 },
{ "x": 9.92, "y": 104.49, "z": 0.5 },
{ "x": 3.66, "y": 104.01, "z": 0.5 },
{ "x": -0.64, "y": 102.5, "z": 0.5 },
{ "x": -2.92, "y": 100.27, "z": 0.5 },
{ "x": -3.6, "y": 96.97, "z": 0.5 },
{ "x": -0.45, "y": 91.45, "z": 0.5 },
{ "x": 9.15, "y": 83.2, "z": 0.5 },
{ "x": 24.06, "y": 72.39, "z": 0.5 },
{ "x": 40.16, "y": 59.82, "z": 0.5 },
{ "x": 54.06, "y": 45.99, "z": 0.5 },
{ "x": 63.61, "y": 33.29, "z": 0.5 },
{ "x": 69.31, "y": 20.87, "z": 0.5 },
{ "x": 72.36, "y": 8.36, "z": 0.5 },
{ "x": 73.05, "y": -0.07, "z": 0.5 },
{ "x": 72.5, "y": -5.4, "z": 0.5 },
{ "x": 71, "y": -9.15, "z": 0.5 },
{ "x": 69.23, "y": -11.13, "z": 0.5 },
{ "x": 67.7, "y": -12.08, "z": 0.5 },
{ "x": 66.64, "y": -12.35, "z": 0.5 },
{ "x": 66.07, "y": -12.29, "z": 0.5 },
{ "x": 65.59, "y": -10.98, "z": 0.5 },
{ "x": 64.91, "y": -5.01, "z": 0.5 },
{ "x": 63.56, "y": 6.47, "z": 0.5 },
{ "x": 61.24, "y": 21.76, "z": 0.5 },
{ "x": 59.27, "y": 36.74, "z": 0.5 },
{ "x": 58.63, "y": 50.8, "z": 0.5 },
{ "x": 58.56, "y": 64.21, "z": 0.5 },
{ "x": 59.69, "y": 72.89, "z": 0.5 },
{ "x": 62.94, "y": 78.64, "z": 0.5 },
{ "x": 66.62, "y": 82.15, "z": 0.5 },
{ "x": 70.67, "y": 82.79, "z": 0.5 },
{ "x": 75.98, "y": 81.09, "z": 0.5 },
{ "x": 81.97, "y": 75.87, "z": 0.5 },
{ "x": 87.87, "y": 68.39, "z": 0.5 },
{ "x": 92.7, "y": 59.73, "z": 0.5 },
{ "x": 95.82, "y": 50.99, "z": 0.5 },
{ "x": 96.92, "y": 44.55, "z": 0.5 },
{ "x": 97.02, "y": 39.91, "z": 0.5 },
{ "x": 96.56, "y": 36.38, "z": 0.5 },
{ "x": 95.41, "y": 34.37, "z": 0.5 },
{ "x": 94.09, "y": 33.59, "z": 0.5 },
{ "x": 92.51, "y": 33.65, "z": 0.5 },
{ "x": 90.9, "y": 36.01, "z": 0.5 },
{ "x": 89.8, "y": 42.11, "z": 0.5 },
{ "x": 89.36, "y": 50.78, "z": 0.5 },
{ "x": 90.17, "y": 60.6, "z": 0.5 },
{ "x": 92.22, "y": 67.78, "z": 0.5 },
{ "x": 95.07, "y": 71.7, "z": 0.5 },
{ "x": 98.44, "y": 73.97, "z": 0.5 },
{ "x": 101.62, "y": 74.13, "z": 0.5 },
{ "x": 105.05, "y": 70.76, "z": 0.5 },
{ "x": 108.93, "y": 63.31, "z": 0.5 },
{ "x": 112.09, "y": 54.51, "z": 0.5 },
{ "x": 113.75, "y": 47.54, "z": 0.5 },
{ "x": 114.33, "y": 42.98, "z": 0.5 },
{ "x": 114.57, "y": 40.11, "z": 0.5 },
{ "x": 114.53, "y": 39.06, "z": 0.5 },
{ "x": 114.21, "y": 39.22, "z": 0.5 },
{ "x": 113.61, "y": 41.78, "z": 0.5 },
{ "x": 113.24, "y": 47.65, "z": 0.5 },
{ "x": 113.2, "y": 54.77, "z": 0.5 },
{ "x": 113.59, "y": 59.94, "z": 0.5 },
{ "x": 115.15, "y": 63.14, "z": 0.5 },
{ "x": 117.5, "y": 65.35, "z": 0.5 },
{ "x": 119.82, "y": 65.98, "z": 0.5 },
{ "x": 122.17, "y": 64.83, "z": 0.5 },
{ "x": 124.45, "y": 60.83, "z": 0.5 },
{ "x": 126.38, "y": 54.53, "z": 0.5 },
{ "x": 127.57, "y": 48.58, "z": 0.5 },
{ "x": 128.02, "y": 43.71, "z": 0.5 },
{ "x": 128.14, "y": 40, "z": 0.5 },
{ "x": 128.14, "y": 37.99, "z": 0.5 },
{ "x": 128.05, "y": 37.08, "z": 0.5 },
{ "x": 127.96, "y": 36.89, "z": 0.5 },
{ "x": 128.34, "y": 37.5, "z": 0.5 },
{ "x": 131.02, "y": 39.91, "z": 0.5 },
{ "x": 137.11, "y": 44.76, "z": 0.5 },
{ "x": 145.28, "y": 51.58, "z": 0.5 },
{ "x": 153.49, "y": 59.87, "z": 0.5 },
{ "x": 159.26, "y": 69.47, "z": 0.5 },
{ "x": 161.58, "y": 81.66, "z": 0.5 },
{ "x": 158.71, "y": 94.96, "z": 0.5 },
{ "x": 147.18, "y": 107.43, "z": 0.5 },
{ "x": 132.52, "y": 116.36, "z": 0.5 },
{ "x": 119.46, "y": 120.3, "z": 0.5 },
{ "x": 109.14, "y": 121.49, "z": 0.5 },
{ "x": 102.95, "y": 119.79, "z": 0.5 },
{ "x": 100.5, "y": 114.09, "z": 0.5 },
{ "x": 105.6, "y": 103.93, "z": 0.5 },
{ "x": 120.72, "y": 89.8, "z": 0.5 },
{ "x": 143.19, "y": 72.46, "z": 0.5 },
{ "x": 167.67, "y": 53.41, "z": 0.5 },
{ "x": 185.27, "y": 37.82, "z": 0.5 },
{ "x": 193.79, "y": 26.69, "z": 0.5 },
{ "x": 197.17, "y": 17.76, "z": 0.5 },
{ "x": 194.75, "y": 11.87, "z": 0.5 },
{ "x": 185.34, "y": 9.07, "z": 0.5 },
{ "x": 172.73, "y": 8.91, "z": 0.5 },
{ "x": 162.58, "y": 10.74, "z": 0.5 },
{ "x": 155.42, "y": 13.45, "z": 0.5 },
{ "x": 151.3, "y": 15.61, "z": 0.5 },
{ "x": 150.03, "y": 17.66, "z": 0.5 }
]
}
],
"color": "black",
"fill": "none",
"dash": "draw",
"size": "l",
"isComplete": true,
"isClosed": false,
"isPen": false
},
"parentId": "page:3qj9EtNgqSCW_6knX2K9_",
"index": "a1",
"id": "shape:EHeAIsYe4xu1-kGxK-Tl_",
"typeName": "shape"
},
"shape:v0c3Ac-kUqB5C8cLsyT_E": {
"x": 325.71484375,
"y": 165.9453125,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 139.38919029117903,
"text": "hey hey hey",
"font": "draw",
"align": "middle",
"autoSize": false,
"scale": 1.178662627660688
},
"parentId": "page:3qj9EtNgqSCW_6knX2K9_",
"index": "a2",
"id": "shape:v0c3Ac-kUqB5C8cLsyT_E",
"typeName": "shape"
},
"page:2E1xHBVQtZUB5fzXfSUPl": {
"meta": {},
"id": "page:2E1xHBVQtZUB5fzXfSUPl",
"name": "Page 2",
"index": "a2",
"typeName": "page"
},
"shape:qZ9C8PqSv6tSWya7LpL1t": {
"x": 144.09765625,
"y": 139.14829380718655,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "text",
"props": {
"color": "black",
"size": "m",
"w": 74.73082091700364,
"text": "Page",
"font": "draw",
"align": "middle",
"autoSize": false,
"scale": 1.6823620652062432
},
"parentId": "page:2E1xHBVQtZUB5fzXfSUPl",
"index": "a1",
"id": "shape:qZ9C8PqSv6tSWya7LpL1t",
"typeName": "shape"
},
"shape:935Jl5xP5gxCs4JGaE81D": {
"x": 293.97412290107434,
"y": 137.07222276594962,
"rotation": 0,
"isLocked": false,
"opacity": 1,
"meta": {},
"type": "draw",
"props": {
"segments": [
{
"type": "free",
"points": [
{ "x": 0, "y": 0, "z": 0.5 },
{ "x": -0.07, "y": 0, "z": 0.5 },
{ "x": -0.15, "y": -0.07, "z": 0.5 },
{ "x": -0.15, "y": -0.13, "z": 0.5 },
{ "x": -0.15, "y": -0.3, "z": 0.5 },
{ "x": -0.15, "y": -0.57, "z": 0.5 },
{ "x": -0.15, "y": -1.21, "z": 0.5 },
{ "x": -0.15, "y": -2.07, "z": 0.5 },
{ "x": -0.15, "y": -2.93, "z": 0.5 },
{ "x": -0.15, "y": -3.79, "z": 0.5 },
{ "x": 0.72, "y": -5.84, "z": 0.5 },
{ "x": 2.02, "y": -8.45, "z": 0.5 },
{ "x": 3.62, "y": -10.87, "z": 0.5 },
{ "x": 5.3, "y": -13.09, "z": 0.5 },
{ "x": 9.45, "y": -17.77, "z": 0.5 },
{ "x": 10.99, "y": -19.35, "z": 0.5 },
{ "x": 12.21, "y": -20.59, "z": 0.5 },
{ "x": 17.21, "y": -25.22, "z": 0.5 },
{ "x": 20.05, "y": -27.37, "z": 0.5 },
{ "x": 22.88, "y": -29.39, "z": 0.5 },
{ "x": 25.87, "y": -31.19, "z": 0.5 },
{ "x": 28.6, "y": -32.74, "z": 0.5 },
{ "x": 29.98, "y": -33.01, "z": 0.5 },
{ "x": 31.22, "y": -33.16, "z": 0.5 },
{ "x": 36.02, "y": -33.8, "z": 0.5 },
{ "x": 38.11, "y": -33.82, "z": 0.5 },
{ "x": 41.03, "y": -33.82, "z": 0.5 },
{ "x": 44.67, "y": -33.82, "z": 0.5 },
{ "x": 47.41, "y": -33.82, "z": 0.5 },
{ "x": 49.29, "y": -33.56, "z": 0.5 },
{ "x": 50.76, "y": -33.13, "z": 0.5 },
{ "x": 51.93, "y": -32.45, "z": 0.5 },
{ "x": 52.89, "y": -31.61, "z": 0.5 },
{ "x": 53.67, "y": -30.82, "z": 0.5 },
{ "x": 54.27, "y": -30.1, "z": 0.5 },
{ "x": 54.93, "y": -29.21, "z": 0.5 },
{ "x": 55.59, "y": -28.3, "z": 0.5 },
{ "x": 55.97, "y": -27.29, "z": 0.5 },
{ "x": 56.22, "y": -26.26, "z": 0.5 },
{ "x": 56.39, "y": -25.3, "z": 0.5 },
{ "x": 56.51, "y": -24.46, "z": 0.5 },
{ "x": 56.54, "y": -23.28, "z": 0.5 },
{ "x": 56.54, "y": -22.04, "z": 0.5 },
{ "x": 56.66, "y": -20.78, "z": 0.5 },
{ "x": 56.8, "y": -19.55, "z": 0.5 },
{ "x": 56.83, "y": -17.43, "z": 0.5 },
{ "x": 56.83, "y": -15.23, "z": 0.5 },
{ "x": 56.83, "y": -13.16, "z": 0.5 },
{ "x": 56.83, "y": -11.22, "z": 0.5 },
{ "x": 56.38, "y": -9.22, "z": 0.5 },
{ "x": 55.89, "y": -7.28, "z": 0.5 },
{ "x": 54.78, "y": -4.61, "z": 0.5 },
{ "x": 52.96, "y": -0.39, "z": 0.5 },
{ "x": 51.48, "y": 2.96, "z": 0.5 },
{ "x": 47.31, "y": 10.43, "z": 0.5 },
{ "x": 40.34, "y": 21.06, "z": 0.5 },
{ "x": 34.42, "y": 28.68, "z": 0.5 },
{ "x": 30.28, "y": 33.6, "z": 0.5 },
{ "x": 27.27, "y": 37.05, "z": 0.5 },
{ "x": 25.13, "y": 39.37, "z": 0.5 },
{ "x": 21.82, "y": 42.92, "z": 0.5 },
{ "x": 17.82, "y": 47.17, "z": 0.5 },
{ "x": 15.34, "y": 49.73, "z": 0.5 },
{ "x": 13.9, "y": 51.19, "z": 0.5 },
{ "x": 11.34, "y": 53.73, "z": 0.5 },
{ "x": 8.28, "y": 56.8, "z": 0.5 },
{ "x": 5.59, "y": 59.34, "z": 0.5 },
{ "x": 3.26, "y": 61.47, "z": 0.5 },
{ "x": 2.07, "y": 62.53, "z": 0.5 },
{ "x": 1.33, "y": 63.14, "z": 0.5 },
{ "x": 0, "y": 64.42, "z": 0.5 },
{ "x": -1.45, "y": 65.88, "z": 0.5 },
{ "x": -2.44, "y": 66.86, "z": 0.5 },
{ "x": -3.21, "y": 67.63, "z": 0.5 },
{ "x": -3.85, "y": 68.27, "z": 0.5 },
{ "x": -4.46, "y": 68.88, "z": 0.5 },
{ "x": -4.73, "y": 69.23, "z": 0.5 },
{ "x": -4.91, "y": 69.5, "z": 0.5 },
{ "x": -5.01, "y": 69.67, "z": 0.5 },
{ "x": -5.1, "y": 69.83, "z": 0.5 },
{ "x": -5.1, "y": 69.92, "z": 0.5 },
{ "x": -5.1, "y": 69.99, "z": 0.5 },
{ "x": -5.03, "y": 70, "z": 0.5 },
{ "x": -4.44, "y": 69.89, "z": 0.5 },
{ "x": -3.48, "y": 69.5, "z": 0.5 },
{ "x": -2.76, "y": 69.01, "z": 0.5 },
{ "x": -1.38, "y": 68.32, "z": 0.5 },
{ "x": 0.4, "y": 67.51, "z": 0.5 },
{ "x": 3.06, "y": 66.45, "z": 0.5 },
{ "x": 6.29, "y": 65.24, "z": 0.5 },
{ "x": 9.81, "y": 64.23, "z": 0.5 },
{ "x": 13.24, "y": 63.43, "z": 0.5 },
{ "x": 17.8, "y": 62.5, "z": 0.5 },
{ "x": 22.71, "y": 61.56, "z": 0.5 },
{ "x": 28.7, "y": 60.72, "z": 0.5 },
{ "x": 34.89, "y": 59.94, "z": 0.5 },
{ "x": 42.4, "y": 59.29, "z": 0.5 },
{ "x": 50.03, "y": 58.71, "z": 0.5 },
{ "x": 57.97, "y": 58.58, "z": 0.5 },
{ "x": 65.61, "y": 58.58, "z": 0.5 },
{ "x": 73.79, "y": 58.58, "z": 0.5 },
{ "x": 81.93, "y": 58.58, "z": 0.5 },
{ "x": 89.91, "y": 58.58, "z": 0.5 },
{ "x": 97.54, "y": 58.58, "z": 0.5 },
{ "x": 101.72, "y": 58.58, "z": 0.5 },
{ "x": 104.83, "y": 58.58, "z": 0.5 },
{ "x": 110.48, "y": 58.58, "z": 0.5 },
{ "x": 117.33, "y": 58.75, "z": 0.5 },
{ "x": 119.83, "y": 59.08, "z": 0.5 },
{ "x": 124.73, "y": 59.89, "z": 0.5 },
{ "x": 129.54, "y": 60.77, "z": 0.5 },
{ "x": 131.86, "y": 61.42, "z": 0.5 },
{ "x": 134.07, "y": 62.11, "z": 0.5 },
{ "x": 135.85, "y": 62.57, "z": 0.5 },
{ "x": 137.3, "y": 62.85, "z": 0.5 },
{ "x": 138.44, "y": 63.19, "z": 0.5 },
{ "x": 139.28, "y": 63.56, "z": 0.5 },
{ "x": 139.96, "y": 63.9, "z": 0.5 },
{ "x": 140.48, "y": 64.22, "z": 0.5 },
{ "x": 140.93, "y": 64.47, "z": 0.5 },
{ "x": 141.32, "y": 64.65, "z": 0.5 },
{ "x": 141.57, "y": 64.84, "z": 0.5 },
{ "x": 141.72, "y": 65.01, "z": 0.5 },
{ "x": 141.84, "y": 65.17, "z": 0.5 },
{ "x": 141.92, "y": 65.33, "z": 0.5 },
{ "x": 141.94, "y": 65.43, "z": 0.5 },
{ "x": 141.94, "y": 65.51, "z": 0.5 },
{ "x": 141.94, "y": 65.58, "z": 0.5 },
{ "x": 141.94, "y": 65.65, "z": 0.5 },
{ "x": 141.94, "y": 65.73, "z": 0.5 },
{ "x": 141.94, "y": 65.8, "z": 0.5 },
{ "x": 141.94, "y": 65.88, "z": 0.5 },
{ "x": 141.94, "y": 65.95, "z": 0.5 },
{ "x": 141.94, "y": 66.03, "z": 0.5 },
{ "x": 141.94, "y": 66.1, "z": 0.5 },
{ "x": 141.94, "y": 66.18, "z": 0.5 },
{ "x": 141.86, "y": 66.29, "z": 0.5 },
{ "x": 141.69, "y": 66.37, "z": 0.5 },
{ "x": 141.45, "y": 66.42, "z": 0.5 },
{ "x": 141.12, "y": 66.5, "z": 0.5 }
]
}
],
"color": "black",
"fill": "none",
"dash": "draw",
"size": "xl",
"isComplete": true,
"isClosed": false,
"isPen": false
},
"parentId": "page:2E1xHBVQtZUB5fzXfSUPl",
"index": "a2",
"id": "shape:935Jl5xP5gxCs4JGaE81D",
"typeName": "shape"
}
},
"schema": {
"schemaVersion": 1,
"storeVersion": 4,
"recordVersions": {
"asset": {
"version": 1,
"subTypeKey": "type",
"subTypeVersions": { "image": 3, "video": 3, "bookmark": 1 }
},
"camera": { "version": 1 },
"document": { "version": 2 },
"instance": { "version": 24 },
"instance_page_state": { "version": 5 },
"page": { "version": 1 },
"shape": {
"version": 3,
"subTypeKey": "type",
"subTypeVersions": {
"group": 0,
"text": 1,
"bookmark": 2,
"draw": 1,
"geo": 8,
"note": 5,
"line": 1,
"frame": 0,
"arrow": 3,
"highlight": 0,
"embed": 4,
"image": 3,
"video": 2
}
},
"instance_presence": { "version": 5 },
"pointer": { "version": 1 }
}
}
}

View file

@ -5,8 +5,6 @@ category: ui
priority: 3
---
...
---
The `Tldraw` component can be used inline with a set height and width.