From 0ed7e55c4c7475b5dc4013c60534fe3eef8ebe02 Mon Sep 17 00:00:00 2001 From: Steve Ruiz Date: Sat, 25 Dec 2021 18:39:50 +0000 Subject: [PATCH] Make core asset types more generic, update docs. --- guides/documentation.md | 3 +++ packages/core/README.md | 22 ++++++++++++---- packages/core/src/types.ts | 23 ++--------------- packages/tldraw/src/state/TldrawApp.ts | 14 +++++------ .../src/state/shapes/ImageUtil/ImageUtil.tsx | 4 +-- .../src/state/shapes/VideoUtil/VideoUtil.tsx | 9 ++++--- packages/tldraw/src/types.ts | 25 +++++++++++++++++-- 7 files changed, 60 insertions(+), 40 deletions(-) diff --git a/guides/documentation.md b/guides/documentation.md index d9b9e9314..ac68b9d80 100644 --- a/guides/documentation.md +++ b/guides/documentation.md @@ -93,6 +93,7 @@ const myDocument: TDDocument = { }, }, }, + assets: {}, } function App() { @@ -102,6 +103,8 @@ function App() { **Tip:** The pages and pageStates in tldraw are objects containing `TLPage` and `TLPageState` objects from the [@tldraw/core](https://github.com/tldraw/core) library. +**Tip:** The `assets` in tldraw is a table of `TDAssets` (images and videos). + **Important:** In the `pages` object, each `TLPage` object must be keyed under its `id` property. Likewise, each `TLPageState` object must be keyed under its `id`. In addition, each `TLPageState` object must have an `id` that matches its corresponding page. ## Shapes diff --git a/packages/core/README.md b/packages/core/README.md index 30cab634d..89644834f 100644 --- a/packages/core/README.md +++ b/packages/core/README.md @@ -81,11 +81,12 @@ function App() { To avoid unnecessary renders, be sure to pass "stable" values as props to the `Renderer`. Either define these values outside of the parent component, or place them in React state, or memoize them with `React.useMemo`. -| Prop | Type | Description | -| ------------ | ------------------------------- | ---------------------------------------------- | -| `page` | [`TLPage`](#tlpage) | The current page object. | -| `pageState` | [`TLPageState`](#tlpagestate) | The current page's state. | -| `shapeUtils` | [`TLShapeUtils`](#tlshapeutils) | The shape utilities used to render the shapes. | +| Prop | Type | Description | +| ------------ | ------------------------------- | ------------------------------------------------ | +| `page` | [`TLPage`](#tlpage) | The current page object. | +| `pageState` | [`TLPageState`](#tlpagestate) | The current page's state. | +| `shapeUtils` | [`TLShapeUtils`](#tlshapeutils) | The shape utilities used to render the shapes. | +| `assets` | [`TLAssets`](#tlassets) | A table of assets used by shapes in the project. | In addition to these required props, the Renderer accents many other **optional** props. @@ -206,6 +207,17 @@ An object describing the current page. It contains: | `bindingId` | `string` | (optional) The currently editing binding. | | `brush` | `TLBounds` | (optional) A `Bounds` for the current selection box | +### `TLAsset` + +An object describing the current page. It contains: + +| Property | Type | Description | +| -------- | -------- | -------------------------- | +| `id` | `string` | A unique id for the asset. | +| `type` | `string` | The type of the asset. | + +Specific asset types may describe additional properties. + ### `TLShape` An object that describes a shape on the page. The shapes in your document should extend this interface with other properties. See [Shape Type](#shape-type). diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index 4daf272af..666dd882e 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -6,30 +6,11 @@ import type React from 'react' export type TLAssets = Record -export enum TLAssetType { - Image = 'image', - Video = 'video', -} - -export interface TLBaseAsset { +export interface TLAsset { id: string - type: TLAssetType + type: string } -export interface TLImageAsset extends TLBaseAsset { - type: TLAssetType.Image - src: string - size: number[] -} - -export interface TLVideoAsset extends TLBaseAsset { - type: TLAssetType.Video - src: string - size: number[] -} - -export type TLAsset = TLImageAsset | TLVideoAsset - export type Patch = Partial<{ [P in keyof T]: T | Partial | Patch }> export type TLForwardedRef = diff --git a/packages/tldraw/src/state/TldrawApp.ts b/packages/tldraw/src/state/TldrawApp.ts index 393dac8a0..b9b61e2f9 100644 --- a/packages/tldraw/src/state/TldrawApp.ts +++ b/packages/tldraw/src/state/TldrawApp.ts @@ -15,8 +15,6 @@ import { Utils, TLBounds, TLDropEventHandler, - TLAssetType, - TLAsset, } from '@tldraw/core' import { FlipType, @@ -37,6 +35,8 @@ import { TDUser, SessionType, TDToolType, + TDAssetType, + TDAsset, } from '~types' import { migrate, @@ -214,7 +214,7 @@ export class TldrawApp extends StateManager { clipboard?: { shapes: TDShape[] bindings: TDBinding[] - assets: TLAsset[] + assets: TDAsset[] } rotationInfo = { @@ -1646,7 +1646,7 @@ export class TldrawApp extends StateManager { if (!shape.assetId) return return this.document.assets[shape.assetId] }) - .filter(Boolean) as TLAsset[] + .filter(Boolean) as TDAsset[] this.clipboard = { shapes: copyingShapes, bindings: copyingBindings, @@ -1690,7 +1690,7 @@ export class TldrawApp extends StateManager { */ paste = (point?: number[]) => { if (this.readOnly) return - const pasteInCurrentPage = (shapes: TDShape[], bindings: TDBinding[], assets: TLAsset[]) => { + const pasteInCurrentPage = (shapes: TDShape[], bindings: TDBinding[], assets: TDAsset[]) => { const idsMap: Record = {} const newAssets = assets.filter((asset) => this.document.assets[asset.id] === undefined) if (newAssets.length) { @@ -1773,7 +1773,7 @@ export class TldrawApp extends StateManager { type: string shapes: TDShape[] bindings: TDBinding[] - assets: TLAsset[] + assets: TDAsset[] } = JSON.parse(result) if (data.type !== 'tldr/clipboard') { throw Error('The pasted string was not from the Tldraw clipboard.') @@ -2821,7 +2821,7 @@ export class TldrawApp extends StateManager { let assetId = Utils.uniqueId() const pagePoint = this.getPagePoint(point) const shapeType = isImage ? TDShapeType.Image : TDShapeType.Video - const assetType = isImage ? TLAssetType.Image : TLAssetType.Video + const assetType = isImage ? TDAssetType.Image : TDAssetType.Video const size = isImage ? await getSizeFromDataurl(dataurl) : [401.42, 401.42] // special const match = Object.values(this.document.assets).find( (asset) => asset.type === assetType && asset.src === dataurl diff --git a/packages/tldraw/src/state/shapes/ImageUtil/ImageUtil.tsx b/packages/tldraw/src/state/shapes/ImageUtil/ImageUtil.tsx index 329cdc2a3..d53255645 100644 --- a/packages/tldraw/src/state/shapes/ImageUtil/ImageUtil.tsx +++ b/packages/tldraw/src/state/shapes/ImageUtil/ImageUtil.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import { Utils, HTMLContainer } from '@tldraw/core' -import { TDShapeType, TDMeta, ImageShape } from '~types' +import { TDShapeType, TDMeta, ImageShape, TDAsset, TDImageAsset } from '~types' import { GHOSTED_OPACITY } from '~constants' import { TDShapeUtil } from '../TDShapeUtil' import { @@ -89,7 +89,7 @@ export class ImageUtil extends TDShapeUtil { > { } Component = TDShapeUtil.Component( - ({ shape, asset, isBinding, isEditing, isGhost, meta, events, onShapeChange }, ref) => { + ( + { shape, asset = { src: '' }, isBinding, isEditing, isGhost, meta, events, onShapeChange }, + ref + ) => { const rVideo = React.useRef(null) const wrapperRef = React.useRef(null) @@ -137,7 +140,7 @@ export class VideoUtil extends TDShapeUtil { onTimeUpdate={handleSetCurrentTime} onLoadedMetadata={onImageLoad} > - + diff --git a/packages/tldraw/src/types.ts b/packages/tldraw/src/types.ts index 08c955d53..4bb3c635e 100644 --- a/packages/tldraw/src/types.ts +++ b/packages/tldraw/src/types.ts @@ -19,7 +19,7 @@ import type { TLBoundsHandleEventHandler, TLShapeBlurHandler, TLShapeCloneHandler, - TLAssets, + TLAsset, } from '@tldraw/core' /* -------------------------------------------------- */ @@ -133,7 +133,7 @@ export interface TDDocument { version: number pages: Record pageStates: Record - assets: TLAssets + assets: TDAssets } // The shape of a single page in the Tldraw document @@ -458,6 +458,27 @@ export type ShapeStyles = { scale?: number } +export enum TDAssetType { + Image = 'image', + Video = 'video', +} + +export interface TDImageAsset extends TLAsset { + type: TDAssetType.Image + src: string + size: number[] +} + +export interface TDVideoAsset extends TLAsset { + type: TDAssetType.Video + src: string + size: number[] +} + +export type TDAsset = TDImageAsset | TDVideoAsset + +export type TDAssets = Record + /* -------------------------------------------------- */ /* Type Helpers */ /* -------------------------------------------------- */