Browse Source

feat: show image in preview

Peng Xiao 3 years ago
parent
commit
073bd0b00d

+ 7 - 2
tldraw/apps/tldraw-logseq/src/lib/preview-manager.tsx

@@ -1,4 +1,4 @@
-import { BoundsUtils, TLDocumentModel, TLShapeConstructor, TLViewport } from '@tldraw/core'
+import { BoundsUtils, TLAsset, TLDocumentModel, TLShapeConstructor, TLViewport } from '@tldraw/core'
 import ReactDOMServer from 'react-dom/server'
 import { Shape, shapes } from './shapes'
 
@@ -16,6 +16,7 @@ const getShapeClass = (type: string): TLShapeConstructor<Shape> => {
 export class PreviewManager {
   shapes: Shape[] | undefined
   pageId: string | undefined
+  assets: TLAsset[] | undefined
   constructor(serializedApp?: TLDocumentModel<Shape>) {
     if (serializedApp) {
       this.load(serializedApp)
@@ -25,6 +26,7 @@ export class PreviewManager {
   load(snapshot: TLDocumentModel) {
     const page = snapshot.pages.find(p => snapshot.currentPageId === p.id)
     this.pageId = page?.id
+    this.assets = snapshot.assets
     this.shapes = page?.shapes.map(s => {
       const ShapeClass = getShapeClass(s.type)
       return new ShapeClass(s)
@@ -90,7 +92,10 @@ export class PreviewManager {
             const transformArr = [`translate(${tx}, ${ty})`, `rotate(${r}, ${rdx}, ${rdy})`]
             return (
               <g transform={transformArr.join(' ')} key={s.id}>
-                {s.getShapeSVGJsx(true)}
+                {s.getShapeSVGJsx({
+                  preview: true,
+                  assets: this.assets,
+                })}
               </g>
             )
           })}

+ 38 - 1
tldraw/apps/tldraw-logseq/src/lib/shapes/ImageShape.tsx

@@ -1,7 +1,7 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
 import * as React from 'react'
 import { HTMLContainer, TLComponentProps } from '@tldraw/react'
-import { TLImageShape, TLImageShapeProps } from '@tldraw/core'
+import { TLAsset, TLImageShape, TLImageShapeProps } from '@tldraw/core'
 import { observer } from 'mobx-react-lite'
 import type { CustomStyleProps } from './style-props'
 
@@ -75,4 +75,41 @@ export class ImageShape extends TLImageShape<ImageShapeProps> {
     } = this
     return <rect width={w} height={h} fill="transparent" />
   })
+
+  getShapeSVGJsx({ assets }: { assets: TLAsset[] }) {
+    // Do not need to consider the original point here
+    const bounds = this.getBounds()
+    const {
+      assetId,
+      clipping,
+      size: [w, h],
+    } = this.props
+    const asset = assets.find(ass => ass.id === assetId)
+
+    if (asset) {
+      const [t, r, b, l] = Array.isArray(clipping)
+        ? clipping
+        : [clipping, clipping, clipping, clipping]
+
+      return (
+        <foreignObject width={bounds.width} height={bounds.height}>
+          <img
+            src={asset.src}
+            draggable={false}
+            style={{
+              position: 'relative',
+              top: -t,
+              left: -l,
+              width: w + (l - r),
+              height: h + (t - b),
+              objectFit: this.props.objectFit,
+              pointerEvents: 'all',
+            }}
+          />
+        </foreignObject>
+      )
+    } else {
+      return super.getShapeSVGJsx({})
+    }
+  }
 }

+ 2 - 2
tldraw/apps/tldraw-logseq/src/lib/shapes/LineShape.tsx

@@ -87,7 +87,7 @@ export class LineShape extends TLLineShape<LineShapeProps> {
         <SVGContainer opacity={isErasing ? 0.2 : opacity} id={id + '_svg'}>
           <LabelMask id={id} bounds={bounds} labelSize={labelSize} offset={offset} scale={scale} />
           <g pointerEvents="none" mask={label || isEditing ? `url(#${id}_clip)` : ``}>
-            {this.getShapeSVGJsx()}
+            {this.getShapeSVGJsx({ preview: false })}
           </g>
         </SVGContainer>
       </div>
@@ -146,7 +146,7 @@ export class LineShape extends TLLineShape<LineShapeProps> {
     return withClampedStyles(props)
   }
 
-  getShapeSVGJsx(preview = false) {
+  getShapeSVGJsx({ preview }: any) {
     const {
       stroke,
       fill,

+ 1 - 1
tldraw/apps/tldraw-logseq/src/lib/shapes/LogseqPortalShape.tsx

@@ -314,7 +314,7 @@ export class LogseqPortalShape extends TLBoxShape<LogseqPortalShapeProps> {
     return withClampedStyles(props)
   }
 
-  getShapeSVGJsx(preview = false) {
+  getShapeSVGJsx({ preview }: any) {
     // Do not need to consider the original point here
     const bounds = this.getBounds()
     return (

+ 1 - 1
tldraw/apps/tldraw-logseq/src/lib/shapes/text/getTextSize.ts

@@ -78,5 +78,5 @@ export function getTextLabelSize(text: string, font: string) {
     saveCached(text, font, [width, height])
   }
 
-  return getCached(text, font)
+  return getCached(text, font)!
 }

+ 1 - 1
tldraw/packages/core/src/lib/shapes/TLShape/TLShape.tsx

@@ -352,7 +352,7 @@ export abstract class TLShape<P extends TLShapeProps = TLShapeProps, M = any> {
    * Get a svg group element that can be used to render the shape with only the props data. In the
    * base, draw any shape as a box. Can be overridden by subclasses.
    */
-  getShapeSVGJsx(preview = false) {
+  getShapeSVGJsx(opts: any) {
     // Do not need to consider the original point here
     const bounds = this.getBounds()
     const { stroke, strokeWidth, opacity, fill } = this.props as any