@tldraw/editor 4.6.0-next.fe1474dc57d8 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cjs/index.d.ts +412 -179
- package/dist-cjs/index.js +12 -23
- package/dist-cjs/index.js.map +2 -2
- package/dist-cjs/lib/TldrawEditor.js +3 -0
- package/dist-cjs/lib/TldrawEditor.js.map +2 -2
- package/dist-cjs/lib/components/default-components/CanvasOverlays.js +180 -0
- package/dist-cjs/lib/components/default-components/CanvasOverlays.js.map +7 -0
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js +44 -249
- package/dist-cjs/lib/components/default-components/DefaultCanvas.js.map +3 -3
- package/dist-cjs/lib/editor/Editor.js +78 -28
- package/dist-cjs/lib/editor/Editor.js.map +2 -2
- package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js +98 -0
- package/dist-cjs/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.js.map +7 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js +14 -0
- package/dist-cjs/lib/editor/managers/ThemeManager/defaultThemes.js.map +2 -2
- package/dist-cjs/lib/editor/overlays/OverlayManager.js +154 -0
- package/dist-cjs/lib/editor/overlays/OverlayManager.js.map +7 -0
- package/dist-cjs/lib/editor/overlays/OverlayUtil.js +92 -0
- package/dist-cjs/lib/editor/overlays/OverlayUtil.js.map +7 -0
- package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js +161 -0
- package/dist-cjs/lib/editor/overlays/ShapeIndicatorOverlayUtil.js.map +7 -0
- package/dist-cjs/lib/editor/overlays/getOverlayDisplayValues.js +39 -0
- package/dist-cjs/lib/editor/overlays/getOverlayDisplayValues.js.map +7 -0
- package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js +3 -0
- package/dist-cjs/lib/editor/shapes/BaseFrameLikeShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js +25 -23
- package/dist-cjs/lib/editor/shapes/ShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js +32 -2
- package/dist-cjs/lib/editor/shapes/group/GroupShapeUtil.js.map +2 -2
- package/dist-cjs/lib/editor/types/event-types.js.map +2 -2
- package/dist-cjs/lib/exports/fetchCache.js +1 -1
- package/dist-cjs/lib/exports/fetchCache.js.map +2 -2
- package/dist-cjs/lib/hooks/EditorComponentsContext.js.map +2 -2
- package/dist-cjs/lib/hooks/useCanvasEvents.js +3 -3
- package/dist-cjs/lib/hooks/useCanvasEvents.js.map +2 -2
- package/dist-cjs/lib/hooks/useEditorComponents.js +0 -28
- package/dist-cjs/lib/hooks/useEditorComponents.js.map +2 -2
- package/dist-cjs/lib/hooks/usePeerIds.js +1 -36
- package/dist-cjs/lib/hooks/usePeerIds.js.map +2 -2
- package/dist-cjs/lib/hooks/useShapeCulling.js +2 -1
- package/dist-cjs/lib/hooks/useShapeCulling.js.map +2 -2
- package/dist-cjs/lib/options.js +0 -1
- package/dist-cjs/lib/options.js.map +2 -2
- package/dist-cjs/lib/utils/reparenting.js +20 -7
- package/dist-cjs/lib/utils/reparenting.js.map +2 -2
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js +3 -0
- package/dist-cjs/lib/utils/sync/TLLocalSyncClient.js.map +2 -2
- package/dist-cjs/version.js +4 -4
- package/dist-cjs/version.js.map +1 -1
- package/dist-esm/index.d.mts +412 -179
- package/dist-esm/index.mjs +19 -41
- package/dist-esm/index.mjs.map +2 -2
- package/dist-esm/lib/TldrawEditor.mjs +3 -0
- package/dist-esm/lib/TldrawEditor.mjs.map +2 -2
- package/dist-esm/lib/components/default-components/CanvasOverlays.mjs +160 -0
- package/dist-esm/lib/components/default-components/CanvasOverlays.mjs.map +7 -0
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs +45 -250
- package/dist-esm/lib/components/default-components/DefaultCanvas.mjs.map +3 -3
- package/dist-esm/lib/editor/Editor.mjs +78 -29
- package/dist-esm/lib/editor/Editor.mjs.map +2 -2
- package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs +83 -0
- package/dist-esm/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.mjs.map +7 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs +14 -0
- package/dist-esm/lib/editor/managers/ThemeManager/defaultThemes.mjs.map +2 -2
- package/dist-esm/lib/editor/overlays/OverlayManager.mjs +136 -0
- package/dist-esm/lib/editor/overlays/OverlayManager.mjs.map +7 -0
- package/dist-esm/lib/editor/overlays/OverlayUtil.mjs +72 -0
- package/dist-esm/lib/editor/overlays/OverlayUtil.mjs.map +7 -0
- package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs +141 -0
- package/dist-esm/lib/editor/overlays/ShapeIndicatorOverlayUtil.mjs.map +7 -0
- package/dist-esm/lib/editor/overlays/getOverlayDisplayValues.mjs +19 -0
- package/dist-esm/lib/editor/overlays/getOverlayDisplayValues.mjs.map +7 -0
- package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs +3 -0
- package/dist-esm/lib/editor/shapes/BaseFrameLikeShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs +25 -23
- package/dist-esm/lib/editor/shapes/ShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs +32 -2
- package/dist-esm/lib/editor/shapes/group/GroupShapeUtil.mjs.map +2 -2
- package/dist-esm/lib/editor/types/event-types.mjs.map +2 -2
- package/dist-esm/lib/exports/fetchCache.mjs +2 -2
- package/dist-esm/lib/exports/fetchCache.mjs.map +2 -2
- package/dist-esm/lib/hooks/EditorComponentsContext.mjs.map +2 -2
- package/dist-esm/lib/hooks/useCanvasEvents.mjs +3 -3
- package/dist-esm/lib/hooks/useCanvasEvents.mjs.map +2 -2
- package/dist-esm/lib/hooks/useEditorComponents.mjs +0 -28
- package/dist-esm/lib/hooks/useEditorComponents.mjs.map +2 -2
- package/dist-esm/lib/hooks/usePeerIds.mjs +2 -40
- package/dist-esm/lib/hooks/usePeerIds.mjs.map +2 -2
- package/dist-esm/lib/hooks/useShapeCulling.mjs +2 -1
- package/dist-esm/lib/hooks/useShapeCulling.mjs.map +2 -2
- package/dist-esm/lib/options.mjs +0 -1
- package/dist-esm/lib/options.mjs.map +2 -2
- package/dist-esm/lib/utils/reparenting.mjs +20 -7
- package/dist-esm/lib/utils/reparenting.mjs.map +2 -2
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs +3 -0
- package/dist-esm/lib/utils/sync/TLLocalSyncClient.mjs.map +2 -2
- package/dist-esm/version.mjs +4 -4
- package/dist-esm/version.mjs.map +1 -1
- package/editor.css +4 -239
- package/package.json +7 -7
- package/src/index.ts +17 -39
- package/src/lib/TldrawEditor.tsx +9 -0
- package/src/lib/components/default-components/CanvasOverlays.tsx +208 -0
- package/src/lib/components/default-components/DefaultCanvas.tsx +49 -324
- package/src/lib/editor/Editor.test.ts +3 -1
- package/src/lib/editor/Editor.ts +80 -24
- package/src/lib/editor/managers/CollaboratorsManager/CollaboratorsManager.ts +98 -0
- package/src/lib/editor/managers/ThemeManager/defaultThemes.ts +14 -0
- package/src/lib/editor/overlays/OverlayManager.ts +183 -0
- package/src/lib/editor/overlays/OverlayUtil.ts +143 -0
- package/src/lib/editor/overlays/ShapeIndicatorOverlayUtil.ts +216 -0
- package/src/lib/editor/overlays/getOverlayDisplayValues.ts +51 -0
- package/src/lib/editor/shapes/BaseFrameLikeShapeUtil.tsx +9 -2
- package/src/lib/editor/shapes/ShapeUtil.ts +34 -26
- package/src/lib/editor/shapes/group/GroupShapeUtil.tsx +40 -3
- package/src/lib/editor/types/event-types.ts +2 -0
- package/src/lib/exports/fetchCache.ts +2 -4
- package/src/lib/exports/getSvgJsx.test.ts +3 -1
- package/src/lib/hooks/EditorComponentsContext.tsx +0 -27
- package/src/lib/hooks/useCanvasEvents.ts +13 -8
- package/src/lib/hooks/useEditorComponents.tsx +0 -28
- package/src/lib/hooks/usePeerIds.ts +6 -55
- package/src/lib/hooks/useShapeCulling.tsx +3 -1
- package/src/lib/options.ts +0 -7
- package/src/lib/utils/reparenting.ts +22 -9
- package/src/lib/utils/sync/TLLocalSyncClient.ts +3 -0
- package/src/version.ts +4 -4
- package/dist-cjs/lib/components/GeometryDebuggingView.js +0 -115
- package/dist-cjs/lib/components/GeometryDebuggingView.js.map +0 -7
- package/dist-cjs/lib/components/LiveCollaborators.js +0 -152
- package/dist-cjs/lib/components/LiveCollaborators.js.map +0 -7
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js +0 -234
- package/dist-cjs/lib/components/default-components/CanvasShapeIndicators.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultBrush.js +0 -38
- package/dist-cjs/lib/components/default-components/DefaultBrush.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js +0 -71
- package/dist-cjs/lib/components/default-components/DefaultCollaboratorHint.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultCursor.js +0 -59
- package/dist-cjs/lib/components/default-components/DefaultCursor.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultHandle.js +0 -56
- package/dist-cjs/lib/components/default-components/DefaultHandle.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultHandles.js +0 -28
- package/dist-cjs/lib/components/default-components/DefaultHandles.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultScribble.js +0 -51
- package/dist-cjs/lib/components/default-components/DefaultScribble.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultSelectionForeground.js +0 -69
- package/dist-cjs/lib/components/default-components/DefaultSelectionForeground.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js +0 -107
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicator.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicatorErrorFallback.js +0 -28
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicatorErrorFallback.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js +0 -102
- package/dist-cjs/lib/components/default-components/DefaultShapeIndicators.js.map +0 -7
- package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js +0 -170
- package/dist-cjs/lib/components/default-components/DefaultSnapIndictor.js.map +0 -7
- package/dist-cjs/lib/hooks/useHandleEvents.js +0 -100
- package/dist-cjs/lib/hooks/useHandleEvents.js.map +0 -7
- package/dist-cjs/lib/hooks/useSelectionEvents.js +0 -98
- package/dist-cjs/lib/hooks/useSelectionEvents.js.map +0 -7
- package/dist-esm/lib/components/GeometryDebuggingView.mjs +0 -95
- package/dist-esm/lib/components/GeometryDebuggingView.mjs.map +0 -7
- package/dist-esm/lib/components/LiveCollaborators.mjs +0 -135
- package/dist-esm/lib/components/LiveCollaborators.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs +0 -214
- package/dist-esm/lib/components/default-components/CanvasShapeIndicators.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultBrush.mjs +0 -18
- package/dist-esm/lib/components/default-components/DefaultBrush.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs +0 -41
- package/dist-esm/lib/components/default-components/DefaultCollaboratorHint.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultCursor.mjs +0 -29
- package/dist-esm/lib/components/default-components/DefaultCursor.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultHandle.mjs +0 -26
- package/dist-esm/lib/components/default-components/DefaultHandle.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultHandles.mjs +0 -8
- package/dist-esm/lib/components/default-components/DefaultHandles.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs +0 -21
- package/dist-esm/lib/components/default-components/DefaultScribble.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs +0 -39
- package/dist-esm/lib/components/default-components/DefaultSelectionForeground.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs +0 -77
- package/dist-esm/lib/components/default-components/DefaultShapeIndicator.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs +0 -8
- package/dist-esm/lib/components/default-components/DefaultShapeIndicatorErrorFallback.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs +0 -82
- package/dist-esm/lib/components/default-components/DefaultShapeIndicators.mjs.map +0 -7
- package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs +0 -142
- package/dist-esm/lib/components/default-components/DefaultSnapIndictor.mjs.map +0 -7
- package/dist-esm/lib/hooks/useHandleEvents.mjs +0 -70
- package/dist-esm/lib/hooks/useHandleEvents.mjs.map +0 -7
- package/dist-esm/lib/hooks/useSelectionEvents.mjs +0 -78
- package/dist-esm/lib/hooks/useSelectionEvents.mjs.map +0 -7
- package/src/lib/components/GeometryDebuggingView.tsx +0 -108
- package/src/lib/components/LiveCollaborators.tsx +0 -180
- package/src/lib/components/default-components/CanvasShapeIndicators.tsx +0 -300
- package/src/lib/components/default-components/DefaultBrush.tsx +0 -35
- package/src/lib/components/default-components/DefaultCollaboratorHint.tsx +0 -52
- package/src/lib/components/default-components/DefaultCursor.tsx +0 -59
- package/src/lib/components/default-components/DefaultHandle.tsx +0 -42
- package/src/lib/components/default-components/DefaultHandles.tsx +0 -15
- package/src/lib/components/default-components/DefaultScribble.tsx +0 -31
- package/src/lib/components/default-components/DefaultSelectionForeground.tsx +0 -50
- package/src/lib/components/default-components/DefaultShapeIndicator.tsx +0 -104
- package/src/lib/components/default-components/DefaultShapeIndicatorErrorFallback.tsx +0 -9
- package/src/lib/components/default-components/DefaultShapeIndicators.tsx +0 -118
- package/src/lib/components/default-components/DefaultSnapIndictor.tsx +0 -174
- package/src/lib/hooks/useHandleEvents.ts +0 -88
- package/src/lib/hooks/useSelectionEvents.ts +0 -97
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { TLScribble } from '@tldraw/tlschema'
|
|
2
|
-
import classNames from 'classnames'
|
|
3
|
-
import { getSvgPathFromPoints } from '../../utils/getSvgPathFromPoints'
|
|
4
|
-
|
|
5
|
-
/** @public */
|
|
6
|
-
export interface TLScribbleProps {
|
|
7
|
-
userId?: string
|
|
8
|
-
scribble: TLScribble
|
|
9
|
-
zoom: number
|
|
10
|
-
color?: string
|
|
11
|
-
opacity?: number
|
|
12
|
-
className?: string
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** @public @react */
|
|
16
|
-
export function DefaultScribble({ scribble, zoom, color, opacity, className }: TLScribbleProps) {
|
|
17
|
-
if (!scribble.points.length) return null
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<svg className={className ? classNames('tl-overlays__item', className) : className}>
|
|
21
|
-
<path
|
|
22
|
-
className="tl-scribble"
|
|
23
|
-
d={getSvgPathFromPoints(scribble.points, false)}
|
|
24
|
-
stroke={color ?? `var(--tl-color-${scribble.color})`}
|
|
25
|
-
fill="none"
|
|
26
|
-
strokeWidth={8 / zoom}
|
|
27
|
-
opacity={opacity ?? scribble.opacity}
|
|
28
|
-
/>
|
|
29
|
-
</svg>
|
|
30
|
-
)
|
|
31
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { useValue } from '@tldraw/state-react'
|
|
2
|
-
import classNames from 'classnames'
|
|
3
|
-
import { useRef } from 'react'
|
|
4
|
-
import { useEditor } from '../../hooks/useEditor'
|
|
5
|
-
import { useTransform } from '../../hooks/useTransform'
|
|
6
|
-
import { Box } from '../../primitives/Box'
|
|
7
|
-
import { toDomPrecision } from '../../primitives/utils'
|
|
8
|
-
|
|
9
|
-
/** @public */
|
|
10
|
-
export interface TLSelectionForegroundProps {
|
|
11
|
-
bounds: Box
|
|
12
|
-
rotation: number
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** @public @react */
|
|
16
|
-
export function DefaultSelectionForeground({ bounds, rotation }: TLSelectionForegroundProps) {
|
|
17
|
-
const editor = useEditor()
|
|
18
|
-
const rSvg = useRef<SVGSVGElement>(null)
|
|
19
|
-
|
|
20
|
-
const onlyShape = useValue('only selected shape', () => editor.getOnlySelectedShape(), [editor])
|
|
21
|
-
|
|
22
|
-
// if all shapes have an expandBy for the selection outline, we can expand by the l
|
|
23
|
-
const expandOutlineBy = onlyShape
|
|
24
|
-
? editor.getShapeUtil(onlyShape).expandSelectionOutlinePx(onlyShape)
|
|
25
|
-
: 0
|
|
26
|
-
|
|
27
|
-
useTransform(rSvg, bounds?.x, bounds?.y, 1, rotation, {
|
|
28
|
-
x: -expandOutlineBy,
|
|
29
|
-
y: -expandOutlineBy,
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
bounds =
|
|
33
|
-
expandOutlineBy instanceof Box
|
|
34
|
-
? bounds.clone().expand(expandOutlineBy).zeroFix()
|
|
35
|
-
: bounds.clone().expandBy(expandOutlineBy).zeroFix()
|
|
36
|
-
|
|
37
|
-
return (
|
|
38
|
-
<svg
|
|
39
|
-
ref={rSvg}
|
|
40
|
-
className="tl-overlays__item tl-selection__fg"
|
|
41
|
-
data-testid="selection-foreground"
|
|
42
|
-
>
|
|
43
|
-
<rect
|
|
44
|
-
className={classNames('tl-selection__fg__outline')}
|
|
45
|
-
width={toDomPrecision(bounds.width)}
|
|
46
|
-
height={toDomPrecision(bounds.height)}
|
|
47
|
-
/>
|
|
48
|
-
</svg>
|
|
49
|
-
)
|
|
50
|
-
}
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import { useQuickReactor, useStateTracking, useValue } from '@tldraw/state-react'
|
|
2
|
-
import { TLShape, TLShapeId } from '@tldraw/tlschema'
|
|
3
|
-
import classNames from 'classnames'
|
|
4
|
-
import { memo, useLayoutEffect, useRef } from 'react'
|
|
5
|
-
import type { Editor } from '../../editor/Editor'
|
|
6
|
-
import { ShapeUtil } from '../../editor/shapes/ShapeUtil'
|
|
7
|
-
import { useEditorComponents } from '../../hooks/EditorComponentsContext'
|
|
8
|
-
import { useEditor } from '../../hooks/useEditor'
|
|
9
|
-
import { OptionalErrorBoundary } from '../ErrorBoundary'
|
|
10
|
-
|
|
11
|
-
// need an extra layer of indirection here to allow hooks to be used inside the indicator render
|
|
12
|
-
const EvenInnererIndicator = memo(
|
|
13
|
-
({ shape, util }: { shape: TLShape; util: ShapeUtil<any> }) => {
|
|
14
|
-
return useStateTracking('Indicator: ' + shape.type, () =>
|
|
15
|
-
// always fetch the latest shape from the store even if the props/meta have not changed, to avoid
|
|
16
|
-
// calling the render method with stale data.
|
|
17
|
-
util.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id) as TLShape)
|
|
18
|
-
)
|
|
19
|
-
},
|
|
20
|
-
(prevProps, nextProps) => {
|
|
21
|
-
return (
|
|
22
|
-
prevProps.shape.props === nextProps.shape.props &&
|
|
23
|
-
prevProps.shape.meta === nextProps.shape.meta
|
|
24
|
-
)
|
|
25
|
-
}
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
const InnerIndicator = memo(({ editor, id }: { editor: Editor; id: TLShapeId }) => {
|
|
29
|
-
const shape = useValue('shape for indicator', () => editor.store.get(id), [editor, id])
|
|
30
|
-
|
|
31
|
-
const { ShapeIndicatorErrorFallback } = useEditorComponents()
|
|
32
|
-
|
|
33
|
-
if (!shape || shape.isLocked) return null
|
|
34
|
-
|
|
35
|
-
const util = editor.getShapeUtil(shape)
|
|
36
|
-
|
|
37
|
-
// If canvas indicators are enabled and the shape uses them, it will be rendered by CanvasShapeIndicators
|
|
38
|
-
if (editor.options.useCanvasIndicators && !util.useLegacyIndicator()) return null
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<OptionalErrorBoundary
|
|
42
|
-
fallback={ShapeIndicatorErrorFallback}
|
|
43
|
-
onError={(error) =>
|
|
44
|
-
editor.annotateError(error, { origin: 'react.shapeIndicator', willCrashApp: false })
|
|
45
|
-
}
|
|
46
|
-
>
|
|
47
|
-
<EvenInnererIndicator key={shape.id} shape={shape} util={util} />
|
|
48
|
-
</OptionalErrorBoundary>
|
|
49
|
-
)
|
|
50
|
-
})
|
|
51
|
-
|
|
52
|
-
/** @public */
|
|
53
|
-
export interface TLShapeIndicatorProps {
|
|
54
|
-
userId?: string
|
|
55
|
-
shapeId: TLShapeId
|
|
56
|
-
color?: string | undefined
|
|
57
|
-
opacity?: number
|
|
58
|
-
className?: string
|
|
59
|
-
hidden?: boolean
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/** @public @react */
|
|
63
|
-
export const DefaultShapeIndicator = memo(function DefaultShapeIndicator({
|
|
64
|
-
shapeId,
|
|
65
|
-
className,
|
|
66
|
-
color,
|
|
67
|
-
hidden,
|
|
68
|
-
opacity,
|
|
69
|
-
}: TLShapeIndicatorProps) {
|
|
70
|
-
const editor = useEditor()
|
|
71
|
-
|
|
72
|
-
const rIndicator = useRef<SVGSVGElement>(null)
|
|
73
|
-
|
|
74
|
-
useQuickReactor(
|
|
75
|
-
'indicator transform',
|
|
76
|
-
() => {
|
|
77
|
-
if (hidden) return
|
|
78
|
-
const elm = rIndicator.current
|
|
79
|
-
if (!elm) return
|
|
80
|
-
const pageTransform = editor.getShapePageTransform(shapeId)
|
|
81
|
-
if (!pageTransform) return
|
|
82
|
-
elm.style.setProperty('transform', pageTransform.toCssString())
|
|
83
|
-
},
|
|
84
|
-
[editor, shapeId, hidden]
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
useLayoutEffect(() => {
|
|
88
|
-
const elm = rIndicator.current
|
|
89
|
-
if (!elm) return
|
|
90
|
-
elm.style.setProperty('display', hidden ? 'none' : 'block')
|
|
91
|
-
}, [hidden])
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<svg ref={rIndicator} className={classNames('tl-overlays__item', className)} aria-hidden="true">
|
|
95
|
-
<g
|
|
96
|
-
className="tl-shape-indicator"
|
|
97
|
-
stroke={color ?? 'var(--tl-color-selected)'}
|
|
98
|
-
opacity={opacity}
|
|
99
|
-
>
|
|
100
|
-
<InnerIndicator editor={editor} id={shapeId} />
|
|
101
|
-
</g>
|
|
102
|
-
</svg>
|
|
103
|
-
)
|
|
104
|
-
})
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ComponentType } from 'react'
|
|
2
|
-
|
|
3
|
-
/** @public */
|
|
4
|
-
export type TLShapeIndicatorErrorFallbackComponent = ComponentType<{ error: unknown }>
|
|
5
|
-
|
|
6
|
-
/** @internal */
|
|
7
|
-
export const DefaultShapeIndicatorErrorFallback: TLShapeIndicatorErrorFallbackComponent = () => {
|
|
8
|
-
return <circle cx={4} cy={4} r={8} strokeWidth="1" stroke="red" />
|
|
9
|
-
}
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
import { useValue } from '@tldraw/state-react'
|
|
2
|
-
import { TLShapeId } from '@tldraw/tlschema'
|
|
3
|
-
import { memo, useRef } from 'react'
|
|
4
|
-
import { useEditorComponents } from '../../hooks/EditorComponentsContext'
|
|
5
|
-
import { useEditor } from '../../hooks/useEditor'
|
|
6
|
-
|
|
7
|
-
/** @public */
|
|
8
|
-
export interface TLShapeIndicatorsProps {
|
|
9
|
-
/** Whether to hide all of the indicators */
|
|
10
|
-
hideAll?: boolean
|
|
11
|
-
/** Whether to show all of the indicators */
|
|
12
|
-
showAll?: boolean
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/** @public @react */
|
|
16
|
-
export const DefaultShapeIndicators = memo(function DefaultShapeIndicators({
|
|
17
|
-
hideAll,
|
|
18
|
-
showAll,
|
|
19
|
-
}: TLShapeIndicatorsProps) {
|
|
20
|
-
const editor = useEditor()
|
|
21
|
-
|
|
22
|
-
if (hideAll && showAll)
|
|
23
|
-
throw Error('You cannot set both hideAll and showAll props to true, cmon now')
|
|
24
|
-
|
|
25
|
-
const rPreviousSelectedShapeIds = useRef<Set<TLShapeId>>(new Set())
|
|
26
|
-
|
|
27
|
-
const idsToDisplay = useValue(
|
|
28
|
-
'should display selected ids',
|
|
29
|
-
() => {
|
|
30
|
-
const prev = rPreviousSelectedShapeIds.current
|
|
31
|
-
const next = new Set<TLShapeId>()
|
|
32
|
-
|
|
33
|
-
const instanceState = editor.getInstanceState()
|
|
34
|
-
|
|
35
|
-
const isChangingStyle = instanceState.isChangingStyle
|
|
36
|
-
|
|
37
|
-
// todo: this is tldraw specific and is duplicated at the tldraw layer. What should we do here instead?
|
|
38
|
-
|
|
39
|
-
const isIdleOrEditing = editor.isInAny('select.idle', 'select.editing_shape')
|
|
40
|
-
|
|
41
|
-
const isInSelectState = editor.isInAny(
|
|
42
|
-
'select.brushing',
|
|
43
|
-
'select.scribble_brushing',
|
|
44
|
-
'select.pointing_shape',
|
|
45
|
-
'select.pointing_selection',
|
|
46
|
-
'select.pointing_handle'
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
// We hide all indicators if we're changing style or in certain interactions
|
|
50
|
-
// todo: move this to some kind of Tool.hideIndicators property
|
|
51
|
-
if (isChangingStyle || !(isIdleOrEditing || isInSelectState)) {
|
|
52
|
-
rPreviousSelectedShapeIds.current = next
|
|
53
|
-
return next
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// We always want to show indicators for the selected shapes, if any
|
|
57
|
-
for (const id of editor.getSelectedShapeIds()) {
|
|
58
|
-
next.add(id)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// If we're idle or editing a shape, we want to also show an indicator for the hovered shape, if any
|
|
62
|
-
if (isIdleOrEditing && instanceState.isHoveringCanvas && !instanceState.isCoarsePointer) {
|
|
63
|
-
const hovered = editor.getHoveredShapeId()
|
|
64
|
-
if (hovered) next.add(hovered)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Ok, has anything changed?
|
|
68
|
-
|
|
69
|
-
// If the number of items in the set is different, then the selection has changed. This catches most changes.
|
|
70
|
-
if (prev.size !== next.size) {
|
|
71
|
-
rPreviousSelectedShapeIds.current = next
|
|
72
|
-
return next
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
// Set difference check
|
|
76
|
-
for (const id of next) {
|
|
77
|
-
if (!prev.has(id)) {
|
|
78
|
-
rPreviousSelectedShapeIds.current = next
|
|
79
|
-
return next
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return prev
|
|
84
|
-
},
|
|
85
|
-
[editor]
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
// Show indicators only for the shapes that are currently being rendered (ie that are on screen)
|
|
89
|
-
const renderingShapes = useValue('rendering shapes', () => editor.getRenderingShapes(), [editor])
|
|
90
|
-
|
|
91
|
-
const { ShapeIndicator } = useEditorComponents()
|
|
92
|
-
|
|
93
|
-
// Filter out shapes that have canvas indicator support - only render shapes that use legacy SVG indicators
|
|
94
|
-
// When useCanvasIndicators is disabled, render all shapes via SVG
|
|
95
|
-
const shapesToRender = useValue(
|
|
96
|
-
'shapes to render for svg indicators',
|
|
97
|
-
() => {
|
|
98
|
-
if (!editor.options.useCanvasIndicators) return renderingShapes
|
|
99
|
-
return renderingShapes.filter(({ id }) => {
|
|
100
|
-
const shape = editor.getShape(id)
|
|
101
|
-
if (!shape) return false
|
|
102
|
-
const util = editor.getShapeUtil(shape)
|
|
103
|
-
return util.useLegacyIndicator()
|
|
104
|
-
})
|
|
105
|
-
},
|
|
106
|
-
[editor, renderingShapes]
|
|
107
|
-
)
|
|
108
|
-
|
|
109
|
-
if (!ShapeIndicator) return null
|
|
110
|
-
|
|
111
|
-
return shapesToRender.map(({ id }) => (
|
|
112
|
-
<ShapeIndicator
|
|
113
|
-
key={id + '_indicator'}
|
|
114
|
-
shapeId={id}
|
|
115
|
-
hidden={!showAll && (hideAll || !idsToDisplay.has(id))}
|
|
116
|
-
/>
|
|
117
|
-
))
|
|
118
|
-
})
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
import classNames from 'classnames'
|
|
2
|
-
import * as React from 'react'
|
|
3
|
-
import {
|
|
4
|
-
type GapsSnapIndicator,
|
|
5
|
-
type PointsSnapIndicator,
|
|
6
|
-
type SnapIndicator,
|
|
7
|
-
} from '../../editor/managers/SnapManager/SnapManager'
|
|
8
|
-
import { rangeIntersection } from '../../primitives/utils'
|
|
9
|
-
|
|
10
|
-
function PointsSnapIndicator({ points, zoom }: { zoom: number } & PointsSnapIndicator) {
|
|
11
|
-
const l = 2.5 / zoom
|
|
12
|
-
|
|
13
|
-
const minX = points.reduce((acc, p) => Math.min(acc, p.x), Infinity)
|
|
14
|
-
const maxX = points.reduce((acc, p) => Math.max(acc, p.x), -Infinity)
|
|
15
|
-
const minY = points.reduce((acc, p) => Math.min(acc, p.y), Infinity)
|
|
16
|
-
const maxY = points.reduce((acc, p) => Math.max(acc, p.y), -Infinity)
|
|
17
|
-
|
|
18
|
-
const useNWtoSEdireciton = points.some((p) => p.x === minX && p.y === minY)
|
|
19
|
-
let firstX: number, firstY: number, secondX: number, secondY: number
|
|
20
|
-
if (useNWtoSEdireciton) {
|
|
21
|
-
firstX = minX
|
|
22
|
-
firstY = minY
|
|
23
|
-
secondX = maxX
|
|
24
|
-
secondY = maxY
|
|
25
|
-
} else {
|
|
26
|
-
firstX = minX
|
|
27
|
-
firstY = maxY
|
|
28
|
-
secondX = maxX
|
|
29
|
-
secondY = minY
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return (
|
|
33
|
-
<g className="tl-snap-indicator" stroke="lime">
|
|
34
|
-
<line x1={firstX} y1={firstY} x2={secondX} y2={secondY} />
|
|
35
|
-
{points.map((p, i) => (
|
|
36
|
-
<g transform={`translate(${p.x},${p.y})`} key={i}>
|
|
37
|
-
<path
|
|
38
|
-
className="tl-snap-point"
|
|
39
|
-
d={`M ${-l},${-l} L ${l},${l} M ${-l},${l} L ${l},${-l}`}
|
|
40
|
-
/>
|
|
41
|
-
</g>
|
|
42
|
-
))}
|
|
43
|
-
</g>
|
|
44
|
-
)
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function GapsSnapIndicator({ gaps, direction, zoom }: { zoom: number } & GapsSnapIndicator) {
|
|
48
|
-
const l = 3.5 / zoom
|
|
49
|
-
|
|
50
|
-
let edgeIntersection: number[] | null = [-Infinity, +Infinity]
|
|
51
|
-
let nextEdgeIntersection: number[] | null = null
|
|
52
|
-
|
|
53
|
-
const horizontal = direction === 'horizontal'
|
|
54
|
-
|
|
55
|
-
// find intersection of all gaps so we can render a straight line through it;
|
|
56
|
-
// some range intersections may return null, in which case we skip that gap.
|
|
57
|
-
for (const gap of gaps) {
|
|
58
|
-
nextEdgeIntersection = rangeIntersection(
|
|
59
|
-
edgeIntersection[0],
|
|
60
|
-
edgeIntersection[1],
|
|
61
|
-
horizontal ? gap.startEdge[0].y : gap.startEdge[0].x,
|
|
62
|
-
horizontal ? gap.startEdge[1].y : gap.startEdge[1].x
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
if (nextEdgeIntersection) {
|
|
66
|
-
edgeIntersection = nextEdgeIntersection
|
|
67
|
-
} else {
|
|
68
|
-
continue
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
nextEdgeIntersection = rangeIntersection(
|
|
72
|
-
edgeIntersection[0],
|
|
73
|
-
edgeIntersection[1],
|
|
74
|
-
horizontal ? gap.endEdge[0].y : gap.endEdge[0].x,
|
|
75
|
-
horizontal ? gap.endEdge[1].y : gap.endEdge[1].x
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
if (nextEdgeIntersection) {
|
|
79
|
-
edgeIntersection = nextEdgeIntersection
|
|
80
|
-
} else {
|
|
81
|
-
continue
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (edgeIntersection === null) {
|
|
86
|
-
return null
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const midPoint = (edgeIntersection[0] + edgeIntersection[1]) / 2
|
|
90
|
-
|
|
91
|
-
return (
|
|
92
|
-
<g className="tl-snap-indicator" stroke="cyan">
|
|
93
|
-
{gaps.map(({ startEdge, endEdge }, i) => (
|
|
94
|
-
<React.Fragment key={i}>
|
|
95
|
-
{horizontal ? (
|
|
96
|
-
// horizontal gap
|
|
97
|
-
<>
|
|
98
|
-
{/* start edge */}
|
|
99
|
-
<line
|
|
100
|
-
x1={startEdge[0].x}
|
|
101
|
-
y1={midPoint - 2 * l}
|
|
102
|
-
x2={startEdge[1].x}
|
|
103
|
-
y2={midPoint + 2 * l}
|
|
104
|
-
/>
|
|
105
|
-
{/* end edge */}
|
|
106
|
-
<line
|
|
107
|
-
x1={endEdge[0].x}
|
|
108
|
-
y1={midPoint - 2 * l}
|
|
109
|
-
x2={endEdge[1].x}
|
|
110
|
-
y2={midPoint + 2 * l}
|
|
111
|
-
/>
|
|
112
|
-
{/* joining line */}
|
|
113
|
-
<line x1={startEdge[0].x} y1={midPoint} x2={endEdge[0].x} y2={midPoint} />
|
|
114
|
-
{/* center point marker */}
|
|
115
|
-
<line
|
|
116
|
-
x1={(startEdge[0].x + endEdge[0].x) / 2}
|
|
117
|
-
y1={midPoint - l}
|
|
118
|
-
x2={(startEdge[0].x + endEdge[0].x) / 2}
|
|
119
|
-
y2={midPoint + l}
|
|
120
|
-
/>
|
|
121
|
-
</>
|
|
122
|
-
) : (
|
|
123
|
-
// vertical gap
|
|
124
|
-
<>
|
|
125
|
-
{/* start edge */}
|
|
126
|
-
<line
|
|
127
|
-
x1={midPoint - 2 * l}
|
|
128
|
-
y1={startEdge[0].y}
|
|
129
|
-
x2={midPoint + 2 * l}
|
|
130
|
-
y2={startEdge[1].y}
|
|
131
|
-
/>
|
|
132
|
-
{/* end edge */}
|
|
133
|
-
<line
|
|
134
|
-
x1={midPoint - 2 * l}
|
|
135
|
-
y1={endEdge[0].y}
|
|
136
|
-
x2={midPoint + 2 * l}
|
|
137
|
-
y2={endEdge[1].y}
|
|
138
|
-
/>
|
|
139
|
-
{/* joining line */}
|
|
140
|
-
<line x1={midPoint} y1={startEdge[0].y} x2={midPoint} y2={endEdge[0].y} />
|
|
141
|
-
{/* center point marker */}
|
|
142
|
-
<line
|
|
143
|
-
x1={midPoint - l}
|
|
144
|
-
y1={(startEdge[0].y + endEdge[0].y) / 2}
|
|
145
|
-
x2={midPoint + l}
|
|
146
|
-
y2={(startEdge[0].y + endEdge[0].y) / 2}
|
|
147
|
-
/>
|
|
148
|
-
</>
|
|
149
|
-
)}
|
|
150
|
-
</React.Fragment>
|
|
151
|
-
))}
|
|
152
|
-
</g>
|
|
153
|
-
)
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/** @public */
|
|
157
|
-
export interface TLSnapIndicatorProps {
|
|
158
|
-
className?: string
|
|
159
|
-
line: SnapIndicator
|
|
160
|
-
zoom: number
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** @public @react */
|
|
164
|
-
export function DefaultSnapIndicator({ className, line, zoom }: TLSnapIndicatorProps) {
|
|
165
|
-
return (
|
|
166
|
-
<svg className={classNames('tl-overlays__item', className)} aria-hidden="true">
|
|
167
|
-
{line.type === 'points' ? (
|
|
168
|
-
<PointsSnapIndicator {...line} zoom={zoom} />
|
|
169
|
-
) : line.type === 'gaps' ? (
|
|
170
|
-
<GapsSnapIndicator {...line} zoom={zoom} />
|
|
171
|
-
) : null}
|
|
172
|
-
</svg>
|
|
173
|
-
)
|
|
174
|
-
}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { TLArrowShape, TLLineShape, TLShapeId } from '@tldraw/tlschema'
|
|
2
|
-
import * as React from 'react'
|
|
3
|
-
import { Editor } from '../editor/Editor'
|
|
4
|
-
import { loopToHtmlElement, releasePointerCapture, setPointerCapture } from '../utils/dom'
|
|
5
|
-
import { getPointerInfo } from '../utils/getPointerInfo'
|
|
6
|
-
import { useEditor } from './useEditor'
|
|
7
|
-
|
|
8
|
-
function getHandle(editor: Editor, id: TLShapeId, handleId: string) {
|
|
9
|
-
const shape = editor.getShape<TLArrowShape | TLLineShape>(id)!
|
|
10
|
-
const handles = editor.getShapeHandles(shape)!
|
|
11
|
-
return { shape, handle: handles.find((h) => h.id === handleId) }
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function useHandleEvents(id: TLShapeId, handleId: string) {
|
|
15
|
-
const editor = useEditor()
|
|
16
|
-
|
|
17
|
-
return React.useMemo(() => {
|
|
18
|
-
const onPointerDown = (e: React.PointerEvent) => {
|
|
19
|
-
if (editor.wasEventAlreadyHandled(e)) return
|
|
20
|
-
|
|
21
|
-
// Must set pointer capture on an HTML element!
|
|
22
|
-
const target = loopToHtmlElement(e.currentTarget)
|
|
23
|
-
setPointerCapture(target, e)
|
|
24
|
-
|
|
25
|
-
const { shape, handle } = getHandle(editor, id, handleId)
|
|
26
|
-
|
|
27
|
-
if (!handle) return
|
|
28
|
-
|
|
29
|
-
editor.dispatch({
|
|
30
|
-
type: 'pointer',
|
|
31
|
-
target: 'handle',
|
|
32
|
-
handle,
|
|
33
|
-
shape,
|
|
34
|
-
name: 'pointer_down',
|
|
35
|
-
...getPointerInfo(editor, e),
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Track the last screen point
|
|
40
|
-
let lastX: number, lastY: number
|
|
41
|
-
|
|
42
|
-
const onPointerMove = (e: React.PointerEvent) => {
|
|
43
|
-
if (editor.wasEventAlreadyHandled(e)) return
|
|
44
|
-
if (e.clientX === lastX && e.clientY === lastY) return
|
|
45
|
-
lastX = e.clientX
|
|
46
|
-
lastY = e.clientY
|
|
47
|
-
|
|
48
|
-
const { shape, handle } = getHandle(editor, id, handleId)
|
|
49
|
-
|
|
50
|
-
if (!handle) return
|
|
51
|
-
|
|
52
|
-
editor.dispatch({
|
|
53
|
-
type: 'pointer',
|
|
54
|
-
target: 'handle',
|
|
55
|
-
handle,
|
|
56
|
-
shape,
|
|
57
|
-
name: 'pointer_move',
|
|
58
|
-
...getPointerInfo(editor, e),
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const onPointerUp = (e: React.PointerEvent) => {
|
|
63
|
-
if (editor.wasEventAlreadyHandled(e)) return
|
|
64
|
-
|
|
65
|
-
const target = loopToHtmlElement(e.currentTarget)
|
|
66
|
-
releasePointerCapture(target, e)
|
|
67
|
-
|
|
68
|
-
const { shape, handle } = getHandle(editor, id, handleId)
|
|
69
|
-
|
|
70
|
-
if (!handle) return
|
|
71
|
-
|
|
72
|
-
editor.dispatch({
|
|
73
|
-
type: 'pointer',
|
|
74
|
-
target: 'handle',
|
|
75
|
-
handle,
|
|
76
|
-
shape,
|
|
77
|
-
name: 'pointer_up',
|
|
78
|
-
...getPointerInfo(editor, e),
|
|
79
|
-
})
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
return {
|
|
83
|
-
onPointerDown,
|
|
84
|
-
onPointerMove,
|
|
85
|
-
onPointerUp,
|
|
86
|
-
}
|
|
87
|
-
}, [editor, id, handleId])
|
|
88
|
-
}
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { useMemo } from 'react'
|
|
2
|
-
import { RIGHT_MOUSE_BUTTON } from '../constants'
|
|
3
|
-
import { TLSelectionHandle } from '../editor/types/selection-types'
|
|
4
|
-
import { loopToHtmlElement, releasePointerCapture, setPointerCapture } from '../utils/dom'
|
|
5
|
-
import { getPointerInfo } from '../utils/getPointerInfo'
|
|
6
|
-
import { useEditor } from './useEditor'
|
|
7
|
-
|
|
8
|
-
/** @public */
|
|
9
|
-
export function useSelectionEvents(handle: TLSelectionHandle) {
|
|
10
|
-
const editor = useEditor()
|
|
11
|
-
|
|
12
|
-
const events = useMemo(
|
|
13
|
-
function selectionEvents() {
|
|
14
|
-
const onPointerDown: React.PointerEventHandler = (e) => {
|
|
15
|
-
if (editor.wasEventAlreadyHandled(e)) return
|
|
16
|
-
|
|
17
|
-
if (e.button === RIGHT_MOUSE_BUTTON) {
|
|
18
|
-
editor.dispatch({
|
|
19
|
-
type: 'pointer',
|
|
20
|
-
target: 'selection',
|
|
21
|
-
handle,
|
|
22
|
-
name: 'right_click',
|
|
23
|
-
...getPointerInfo(editor, e),
|
|
24
|
-
})
|
|
25
|
-
return
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (e.button !== 0) return
|
|
29
|
-
|
|
30
|
-
// Because the events are probably set on SVG elements,
|
|
31
|
-
// we need to instead place pointer capture on the first HTML
|
|
32
|
-
// element above the event's target; and set a listener to
|
|
33
|
-
// remove pointer capture when the pointer is released.
|
|
34
|
-
|
|
35
|
-
const elm = loopToHtmlElement(e.currentTarget)
|
|
36
|
-
|
|
37
|
-
function releaseCapture() {
|
|
38
|
-
elm.removeEventListener('pointerup', releaseCapture)
|
|
39
|
-
releasePointerCapture(elm, e)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
setPointerCapture(elm, e)
|
|
43
|
-
elm.addEventListener('pointerup', releaseCapture)
|
|
44
|
-
|
|
45
|
-
editor.dispatch({
|
|
46
|
-
name: 'pointer_down',
|
|
47
|
-
type: 'pointer',
|
|
48
|
-
target: 'selection',
|
|
49
|
-
handle,
|
|
50
|
-
...getPointerInfo(editor, e),
|
|
51
|
-
})
|
|
52
|
-
editor.markEventAsHandled(e)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Track the last screen point
|
|
56
|
-
let lastX: number, lastY: number
|
|
57
|
-
|
|
58
|
-
function onPointerMove(e: React.PointerEvent) {
|
|
59
|
-
if (editor.wasEventAlreadyHandled(e)) return
|
|
60
|
-
if (e.button !== 0) return
|
|
61
|
-
if (e.clientX === lastX && e.clientY === lastY) return
|
|
62
|
-
lastX = e.clientX
|
|
63
|
-
lastY = e.clientY
|
|
64
|
-
|
|
65
|
-
editor.dispatch({
|
|
66
|
-
name: 'pointer_move',
|
|
67
|
-
type: 'pointer',
|
|
68
|
-
target: 'selection',
|
|
69
|
-
handle,
|
|
70
|
-
...getPointerInfo(editor, e),
|
|
71
|
-
})
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const onPointerUp: React.PointerEventHandler = (e) => {
|
|
75
|
-
if (editor.wasEventAlreadyHandled(e)) return
|
|
76
|
-
if (e.button !== 0) return
|
|
77
|
-
|
|
78
|
-
editor.dispatch({
|
|
79
|
-
name: 'pointer_up',
|
|
80
|
-
type: 'pointer',
|
|
81
|
-
target: 'selection',
|
|
82
|
-
handle,
|
|
83
|
-
...getPointerInfo(editor, e),
|
|
84
|
-
})
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
onPointerDown,
|
|
89
|
-
onPointerMove,
|
|
90
|
-
onPointerUp,
|
|
91
|
-
}
|
|
92
|
-
},
|
|
93
|
-
[editor, handle]
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
return events
|
|
97
|
-
}
|