Prechádzať zdrojové kódy

fix: some text shape related issues

Peng Xiao 3 rokov pred
rodič
commit
6fbd67333e

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

@@ -7,7 +7,7 @@ import * as React from 'react'
 import { Arrow } from './arrow/Arrow'
 import { getArrowPath } from './arrow/arrowHelpers'
 import { CustomStyleProps, withClampedStyles } from './style-props'
-import { getTextLabelSize } from './text/getTextSize'
+import { getTextLabelSize } from '@tldraw/core'
 import { LabelMask } from './text/LabelMask'
 import { TextLabel } from './text/TextLabel'
 
@@ -53,8 +53,7 @@ export class LineShape extends TLLineShape<LineShapeProps> {
       label,
       id,
     } = this.props
-    const app = useApp()
-    const labelSize = label || isEditing ? getTextLabelSize(label, font) : [0, 0]
+    const labelSize = label || isEditing ? getTextLabelSize(label, font, 4) : [0, 0]
     const midPoint = Vec.med(start.point, end.point)
     const dist = Vec.dist(start.point, end.point)
     const scale = Math.max(
@@ -69,7 +68,6 @@ export class LineShape extends TLLineShape<LineShapeProps> {
     const handleLabelChange = React.useCallback(
       (label: string) => {
         this.update?.({ label })
-        app.persist()
       },
       [label]
     )
@@ -105,7 +103,7 @@ export class LineShape extends TLLineShape<LineShapeProps> {
       handles: { start, end },
     } = this.props
     const bounds = this.getBounds()
-    const labelSize = label ? getTextLabelSize(label, font) : [0, 0]
+    const labelSize = label ? getTextLabelSize(label, font, 4) : [0, 0]
     const midPoint = Vec.med(start.point, end.point)
     const dist = Vec.dist(start.point, end.point)
     const scale = Math.max(

+ 11 - 8
tldraw/apps/tldraw-logseq/src/lib/shapes/TextShape.tsx

@@ -1,6 +1,13 @@
 /* eslint-disable @typescript-eslint/no-explicit-any */
-import { TextUtils, TLBounds, TLResizeStartInfo, TLTextShape, TLTextShapeProps } from '@tldraw/core'
-import { HTMLContainer, TLComponentProps, TLTextMeasure } from '@tldraw/react'
+import {
+  getTextLabelSize,
+  TextUtils,
+  TLBounds,
+  TLResizeStartInfo,
+  TLTextShape,
+  TLTextShapeProps,
+} from '@tldraw/core'
+import { HTMLContainer, TLComponentProps } from '@tldraw/react'
 import { action, computed } from 'mobx'
 import { observer } from 'mobx-react-lite'
 import * as React from 'react'
@@ -163,7 +170,7 @@ export class TextShape extends TLTextShape<TextShapeProps> {
 
     React.useLayoutEffect(() => {
       const { fontFamily, fontSize, fontWeight, lineHeight, padding } = this.props
-      const { width, height } = this.measure.measureText(
+      const [width, height] = getTextLabelSize(
         text,
         { fontFamily, fontSize, fontWeight, lineHeight },
         padding
@@ -255,10 +262,6 @@ export class TextShape extends TLTextShape<TextShapeProps> {
     return withClampedStyles(this, props)
   }
 
-  // Custom
-
-  private measure = new TLTextMeasure()
-
   getAutoSizedBoundingBox(props = {} as Partial<TextShapeProps>) {
     const {
       text = this.props.text,
@@ -268,7 +271,7 @@ export class TextShape extends TLTextShape<TextShapeProps> {
       lineHeight = this.props.lineHeight,
       padding = this.props.padding,
     } = props
-    const { width, height } = this.measure.measureText(
+    const [width, height] = getTextLabelSize(
       text,
       { fontFamily, fontSize, lineHeight, fontWeight },
       padding

+ 2 - 4
tldraw/apps/tldraw-logseq/src/lib/shapes/text/TextLabel.tsx

@@ -1,7 +1,6 @@
 import { TextUtils } from '@tldraw/core'
 import * as React from 'react'
-import { LETTER_SPACING } from './constants'
-import { getTextLabelSize } from './getTextSize'
+import { getTextLabelSize } from '@tldraw/core'
 import { TextAreaUtils } from './TextAreaUtils'
 
 const stopPropagation = (e: KeyboardEvent | React.SyntheticEvent<any, Event>) => e.stopPropagation()
@@ -122,7 +121,7 @@ export const TextLabel = React.memo(function TextLabel({
   React.useLayoutEffect(() => {
     const elm = rInnerWrapper.current
     if (!elm) return
-    const size = getTextLabelSize(text, font)
+    const size = getTextLabelSize(text, font, 4)
     elm.style.transform = `scale(${scale}, ${scale}) translate(${offsetX}px, ${offsetY}px)`
     elm.style.width = size[0] + 1 + 'px'
     elm.style.height = size[1] + 1 + 'px'
@@ -136,7 +135,6 @@ export const TextLabel = React.memo(function TextLabel({
         style={{
           font,
           color,
-          letterSpacing: LETTER_SPACING,
           pointerEvents: text ? 'all' : 'none',
           userSelect: isEditing ? 'text' : 'none',
         }}

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

@@ -1,2 +1 @@
-export const LETTER_SPACING = '-0.03em'
 export const GHOSTED_OPACITY = 0.3

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

@@ -1,82 +0,0 @@
-import { LETTER_SPACING } from './constants'
-
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-let melm: any
-
-function getMeasurementDiv() {
-  // A div used for measurement
-  document.getElementById('__textLabelMeasure')?.remove()
-
-  const pre = document.createElement('pre')
-  pre.id = '__textLabelMeasure'
-
-  Object.assign(pre.style, {
-    whiteSpace: 'pre',
-    width: 'auto',
-    border: '1px solid transparent',
-    padding: '4px',
-    margin: '0px',
-    letterSpacing: LETTER_SPACING,
-    opacity: '0',
-    position: 'absolute',
-    top: '-500px',
-    left: '0px',
-    zIndex: '9999',
-    pointerEvents: 'none',
-    userSelect: 'none',
-    alignmentBaseline: 'mathematical',
-    dominantBaseline: 'mathematical',
-  })
-
-  pre.tabIndex = -1
-
-  document.body.appendChild(pre)
-  return pre
-}
-
-if (typeof window !== 'undefined') {
-  melm = getMeasurementDiv()
-}
-
-const cache = new Map<string, [number, number]>()
-const getKey = (text: string, font: string) => {
-  return `${text}-${font}`
-}
-const hasCached = (text: string, font: string) => {
-  const key = getKey(text, font)
-  return cache.has(key)
-}
-const getCached = (text: string, font: string) => {
-  const key = getKey(text, font)
-  return cache.get(key)
-}
-const saveCached = (text: string, font: string, size: [number, number]) => {
-  const key = getKey(text, font)
-  cache.set(key, size)
-}
-
-export function getTextLabelSize(text: string, font: string) {
-  if (!text) {
-    return [16, 32]
-  }
-
-  if (!hasCached(text, font)) {
-    if (!melm) {
-      // We're in SSR
-      return [10, 10]
-    }
-
-    if (!melm.parent) document.body.appendChild(melm)
-
-    melm.textContent = text
-    melm.style.font = font
-
-    // In tests, offsetWidth and offsetHeight will be 0
-    const width = melm.offsetWidth || 1
-    const height = melm.offsetHeight || 1
-
-    saveCached(text, font, [width, height])
-  }
-
-  return getCached(text, font)!
-}

+ 1 - 1
tldraw/packages/core/src/lib/tools/TLSelectTool/states/EditingShapeState.ts

@@ -22,7 +22,7 @@ export class EditingShapeState<
 
   onExit = () => {
     // cleanup text shapes
-    if ('text' in this.editingShape.props) {
+    if (this.editingShape && 'text' in this.editingShape.props) {
       // @ts-expect-error better typing
       const newText = this.editingShape.props['text'].trim()
 

+ 101 - 0
tldraw/packages/core/src/utils/getTextSize.ts

@@ -0,0 +1,101 @@
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
+let melm: any
+
+interface TLTextMeasureStyles {
+  fontStyle?: string
+  fontVariant?: string
+  fontWeight?: number
+  fontSize: number
+  fontFamily: string
+  lineHeight: number
+}
+
+function getMeasurementDiv() {
+  // A div used for measurement
+  document.getElementById('__textLabelMeasure')?.remove()
+
+  const pre = document.createElement('pre')
+  pre.id = '__textLabelMeasure'
+
+  Object.assign(pre.style, {
+    whiteSpace: 'pre',
+    width: 'auto',
+    borderLeft: '2px solid transparent',
+    borderRight: '1px solid transparent',
+    borderBottom: '2px solid transparent',
+    padding: '0px',
+    margin: '0px',
+    opacity: '0',
+    position: 'absolute',
+    top: '-500px',
+    left: '0px',
+    zIndex: '9999',
+    userSelect: 'none',
+    pointerEvents: 'none',
+  })
+
+  pre.tabIndex = -1
+
+  document.body.appendChild(pre)
+  return pre
+}
+
+if (typeof window !== 'undefined') {
+  melm = getMeasurementDiv()
+}
+
+const cache = new Map<string, [number, number]>()
+const getKey = (text: string, font: string, padding: number) => {
+  return `${text}-${font}-${padding}`
+}
+const hasCached = (text: string, font: string, padding: number) => {
+  const key = getKey(text, font, padding)
+  return cache.has(key)
+}
+const getCached = (text: string, font: string, padding: number) => {
+  const key = getKey(text, font, padding)
+  return cache.get(key)
+}
+const saveCached = (text: string, font: string, padding: number, size: [number, number]) => {
+  const key = getKey(text, font, padding)
+  cache.set(key, size)
+}
+
+export function getTextLabelSize(text: string, fontOrStyles: string | TLTextMeasureStyles, padding = 0) {
+  if (!text) {
+    return [16, 32]
+  }
+
+  let font: string
+
+  if (typeof fontOrStyles === 'string') {
+    font = fontOrStyles
+  } else {
+    font = `${fontOrStyles.fontStyle ?? 'normal'} ${fontOrStyles.fontVariant ?? 'normal'} ${
+      fontOrStyles.fontWeight ?? 'normal'
+    } ${fontOrStyles.fontSize}px/${fontOrStyles.fontSize * fontOrStyles.lineHeight}px ${
+      fontOrStyles.fontFamily
+    }`
+  }
+
+  if (!hasCached(text, font, padding)) {
+    if (!melm) {
+      // We're in SSR
+      return [10, 10]
+    }
+
+    if (!melm.parent) document.body.appendChild(melm)
+
+    melm.innerHTML = `${text}&#8203;`
+    melm.style.font = font
+    melm.style.padding = padding + 'px'
+
+    // In tests, offsetWidth and offsetHeight will be 0
+    const width = melm.offsetWidth || 1
+    const height = melm.offsetHeight || 1
+
+    saveCached(text, font, padding, [width, height])
+  }
+
+  return getCached(text, font, padding)!
+}

+ 1 - 0
tldraw/packages/core/src/utils/index.ts

@@ -7,6 +7,7 @@ export * from './PolygonUtils'
 export * from './SvgPathUtils'
 export * from './DataUtils'
 export * from './TextUtils'
+export * from './getTextSize'
 
 export function uniqueId() {
   return uuid.v1()

+ 0 - 6
tldraw/packages/react/src/hooks/useCanvasEvents.ts

@@ -52,12 +52,6 @@ export function useCanvasEvents() {
 
     const onDrop = async (e: React.DragEvent<Element>) => {
       e.preventDefault()
-      Array.from(e.dataTransfer.items).forEach(item => {
-        const type = item.type
-        item.getAsString(s => {
-          console.log(type, ":", s)
-        })
-      })
 
       if (!e.dataTransfer.files?.length) return
       const point = [e.clientX, e.clientY]

+ 0 - 63
tldraw/packages/react/src/lib/TLTextMeasure/TLTextMeasure.ts

@@ -1,63 +0,0 @@
-import { uniqueId } from '@tldraw/core'
-
-export interface TLTextMeasureStyles {
-  fontStyle?: string
-  fontVariant?: string
-  fontWeight?: number
-  fontSize: number
-  fontFamily: string
-  lineHeight: number
-}
-
-export class TLTextMeasure {
-  private elm: HTMLPreElement
-
-  constructor() {
-    const pre = document.createElement('pre')
-    const id = uniqueId()
-
-    pre.id = `__textMeasure_${id}`
-
-    Object.assign(pre.style, {
-      whiteSpace: 'pre',
-      width: 'auto',
-      borderLeft: '2px solid transparent',
-      borderRight: '1px solid transparent',
-      borderBottom: '2px solid transparent',
-      padding: '0px',
-      margin: '0px',
-      opacity: '0',
-      position: 'absolute',
-      top: '-500px',
-      left: '0px',
-      zIndex: '9999',
-      userSelect: 'none',
-      pointerEvents: 'none',
-    })
-
-    pre.tabIndex = -1
-    document.body.appendChild(pre)
-    this.elm = pre
-  }
-
-  measureText = (text: string, styles: TLTextMeasureStyles, padding = 0) => {
-    const { elm } = this
-
-    elm.style.setProperty(
-      'font',
-      `${styles.fontStyle ?? 'normal'} ${styles.fontVariant ?? 'normal'} ${
-        styles.fontWeight ?? 'normal'
-      } ${styles.fontSize}px/${styles.fontSize * styles.lineHeight}px ${styles.fontFamily}`
-    )
-    elm.style.padding = padding + 'px'
-    elm.innerHTML = `${text}&#8203;`
-
-    const width = elm.offsetWidth ?? 1
-    const height = elm.offsetHeight ?? 1
-
-    return {
-      width,
-      height,
-    }
-  }
-}

+ 0 - 1
tldraw/packages/react/src/lib/TLTextMeasure/index.ts

@@ -1 +0,0 @@
-export * from './TLTextMeasure'

+ 0 - 1
tldraw/packages/react/src/lib/index.ts

@@ -1,4 +1,3 @@
 export * from './shapes'
 export * from './TLReactShape'
 export * from './TLReactApp'
-export * from './TLTextMeasure'