fix stuck pointer during text editing / palm hits (#316)
This commit is contained in:
parent
d5d999e86d
commit
62803443ef
35 changed files with 688 additions and 676 deletions
|
@ -25,7 +25,7 @@
|
||||||
"build:core": "lerna run build:core",
|
"build:core": "lerna run build:core",
|
||||||
"build:packages": "lerna run build:packages --stream",
|
"build:packages": "lerna run build:packages --stream",
|
||||||
"build:apps": "lerna run build:apps",
|
"build:apps": "lerna run build:apps",
|
||||||
"start": "lerna run start --stream --parallel",
|
"start": "yarn build:packages && lerna run start --stream --parallel",
|
||||||
"start:core": "lerna run start:core --stream --parallel",
|
"start:core": "lerna run start:core --stream --parallel",
|
||||||
"start:www": "yarn build:packages && lerna run start --parallel & cd apps/www && yarn dev",
|
"start:www": "yarn build:packages && lerna run start --parallel & cd apps/www && yarn dev",
|
||||||
"start:electron": "lerna run start:electron --stream --parallel",
|
"start:electron": "lerna run start:electron --stream --parallel",
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||||
import type { TLShape, TLBounds, TLComponentProps } from '~types'
|
import type { TLShape, TLBounds, TLComponentProps } from '../types'
|
||||||
import { TLShapeUtil } from './TLShapeUtil'
|
import { TLShapeUtil } from './TLShapeUtil'
|
||||||
import { render } from '@testing-library/react'
|
import { render } from '@testing-library/react'
|
||||||
import { SVGContainer } from '~components'
|
import { SVGContainer } from '~components'
|
||||||
import Utils from '~utils'
|
import Utils from '../utils'
|
||||||
|
|
||||||
export interface BoxShape extends TLShape {
|
export interface BoxShape extends TLShape {
|
||||||
type: 'box'
|
type: 'box'
|
|
@ -1,8 +1,8 @@
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import Utils from '~utils'
|
import Utils from '../utils'
|
||||||
import { intersectPolylineBounds } from '@tldraw/intersect'
|
import { intersectPolylineBounds } from '@tldraw/intersect'
|
||||||
import type { TLBounds, TLComponentProps, TLForwardedRef, TLShape, TLUser } from '~types'
|
import type { TLBounds, TLComponentProps, TLForwardedRef, TLShape, TLUser } from '../types'
|
||||||
|
|
||||||
export abstract class TLShapeUtil<T extends TLShape, E extends Element = any, M = any> {
|
export abstract class TLShapeUtil<T extends TLShape, E extends Element = any, M = any> {
|
||||||
refMap = new Map<string, React.RefObject<E>>()
|
refMap = new Map<string, React.RefObject<E>>()
|
|
@ -1,4 +1,4 @@
|
||||||
import type { TLShape } from '~types'
|
import type { TLShape } from '../types'
|
||||||
import type { TLShapeUtil } from './TLShapeUtil'
|
import type { TLShapeUtil } from './TLShapeUtil'
|
||||||
|
|
||||||
export type TLShapeUtilsMap<T extends TLShape> = {
|
export type TLShapeUtilsMap<T extends TLShape> = {
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { renderWithContext } from '~test'
|
import { renderWithContext } from '~test'
|
||||||
import { Handles } from './handles'
|
import { Handles } from './handles'
|
||||||
import { boxShape } from '~shape-utils/TLShapeUtil.spec'
|
import { boxShape } from '~TLShapeUtil/TLShapeUtil.spec'
|
||||||
import { screen } from '@testing-library/react'
|
import { screen } from '@testing-library/react'
|
||||||
|
|
||||||
describe('handles', () => {
|
describe('handles', () => {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { BoundsBg } from '~components/bounds/bounds-bg'
|
||||||
import { Handles } from '~components/handles'
|
import { Handles } from '~components/handles'
|
||||||
import { ShapeNode } from '~components/shape'
|
import { ShapeNode } from '~components/shape'
|
||||||
import { ShapeIndicator } from '~components/shape-indicator'
|
import { ShapeIndicator } from '~components/shape-indicator'
|
||||||
import type { TLShapeUtil } from '~shape-utils'
|
import type { TLShapeUtil } from '~TLShapeUtil'
|
||||||
|
|
||||||
interface PageProps<T extends TLShape, M extends Record<string, unknown>> {
|
interface PageProps<T extends TLShape, M extends Record<string, unknown>> {
|
||||||
page: TLPage<T, TLBinding>
|
page: TLPage<T, TLBinding>
|
||||||
|
|
|
@ -8,12 +8,13 @@ import type {
|
||||||
TLTheme,
|
TLTheme,
|
||||||
TLBounds,
|
TLBounds,
|
||||||
TLBinding,
|
TLBinding,
|
||||||
|
TLSnapLine,
|
||||||
|
TLUsers,
|
||||||
} from '../../types'
|
} from '../../types'
|
||||||
import { Canvas } from '../canvas'
|
import { Canvas } from '../canvas'
|
||||||
import { Inputs } from '../../inputs'
|
import { Inputs } from '../../inputs'
|
||||||
import { useTLTheme, TLContext, TLContextType } from '../../hooks'
|
import { useTLTheme, TLContext, TLContextType } from '../../hooks'
|
||||||
import type { TLSnapLine, TLUsers } from '~index'
|
import type { TLShapeUtilsMap } from '../../TLShapeUtil'
|
||||||
import type { TLShapeUtilsMap } from '~shape-utils'
|
|
||||||
|
|
||||||
export interface RendererProps<T extends TLShape, M = any> extends Partial<TLCallbacks<T>> {
|
export interface RendererProps<T extends TLShape, M = any> extends Partial<TLCallbacks<T>> {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { renderWithSvg } from '~test'
|
import { renderWithSvg } from '~test'
|
||||||
import { ShapeIndicator } from './shape-indicator'
|
import { ShapeIndicator } from './shape-indicator'
|
||||||
import { boxShape } from '~shape-utils/TLShapeUtil.spec'
|
import { boxShape } from '~TLShapeUtil/TLShapeUtil.spec'
|
||||||
|
|
||||||
describe('shape indicator', () => {
|
describe('shape indicator', () => {
|
||||||
test('mounts component without crashing', () => {
|
test('mounts component without crashing', () => {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import type { TLComponentProps, TLShape } from '~types'
|
import type { TLComponentProps, TLShape } from '~types'
|
||||||
import type { TLShapeUtil } from '~shape-utils'
|
import type { TLShapeUtil } from '~TLShapeUtil'
|
||||||
|
|
||||||
interface RenderedShapeProps<T extends TLShape, E extends Element, M>
|
interface RenderedShapeProps<T extends TLShape, E extends Element, M>
|
||||||
extends TLComponentProps<T, E, M> {
|
extends TLComponentProps<T, E, M> {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import type { IShapeTreeNode, TLShape } from '~types'
|
import type { IShapeTreeNode, TLShape } from '~types'
|
||||||
import { Shape } from './shape'
|
import { Shape } from './shape'
|
||||||
import type { TLShapeUtilsMap } from '~shape-utils'
|
import type { TLShapeUtilsMap } from '~TLShapeUtil'
|
||||||
|
|
||||||
interface ShapeNodeProps<T extends TLShape> extends IShapeTreeNode<T> {
|
interface ShapeNodeProps<T extends TLShape> extends IShapeTreeNode<T> {
|
||||||
utils: TLShapeUtilsMap<TLShape>
|
utils: TLShapeUtilsMap<TLShape>
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { renderWithContext } from '~test'
|
import { renderWithContext } from '~test'
|
||||||
import { Shape } from './shape'
|
import { Shape } from './shape'
|
||||||
import { BoxUtil, boxShape } from '~shape-utils/TLShapeUtil.spec'
|
import { BoxUtil, boxShape } from '~TLShapeUtil/TLShapeUtil.spec'
|
||||||
import type { TLShapeUtil } from '~shape-utils'
|
import type { TLShapeUtil } from '~TLShapeUtil'
|
||||||
import type { TLShape } from '~types'
|
import type { TLShape } from '~types'
|
||||||
|
|
||||||
describe('shape', () => {
|
describe('shape', () => {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { RenderedShape } from './rendered-shape'
|
||||||
import { Container } from '~components/container'
|
import { Container } from '~components/container'
|
||||||
import { useTLContext } from '~hooks'
|
import { useTLContext } from '~hooks'
|
||||||
import { useForceUpdate } from '~hooks/useForceUpdate'
|
import { useForceUpdate } from '~hooks/useForceUpdate'
|
||||||
import type { TLShapeUtil } from '~shape-utils'
|
import type { TLShapeUtil } from '~TLShapeUtil'
|
||||||
|
|
||||||
interface ShapeProps<T extends TLShape, M> extends IShapeTreeNode<T, M> {
|
interface ShapeProps<T extends TLShape, M> extends IShapeTreeNode<T, M> {
|
||||||
utils: TLShapeUtil<T>
|
utils: TLShapeUtil<T>
|
||||||
|
|
|
@ -28,6 +28,9 @@ export function useBoundsEvents() {
|
||||||
const onPointerUp = React.useCallback(
|
const onPointerUp = React.useCallback(
|
||||||
(e: React.PointerEvent) => {
|
(e: React.PointerEvent) => {
|
||||||
if (e.button !== 0) return
|
if (e.button !== 0) return
|
||||||
|
|
||||||
|
inputs.activePointer = undefined
|
||||||
|
|
||||||
if (!inputs.pointerIsValid(e)) return
|
if (!inputs.pointerIsValid(e)) return
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
const isDoubleClick = inputs.isDoubleClick()
|
const isDoubleClick = inputs.isDoubleClick()
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import type { TLBoundsEdge, TLBoundsCorner } from '~types'
|
import type { TLBoundsEdge, TLBoundsCorner } from '../types'
|
||||||
import { useTLContext } from './useTLContext'
|
import { useTLContext } from './useTLContext'
|
||||||
|
|
||||||
export function useBoundsHandleEvents(
|
export function useBoundsHandleEvents(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import type { TLPageState } from '~types'
|
import type { TLPageState } from '../types'
|
||||||
|
|
||||||
export function useCameraCss(
|
export function useCameraCss(
|
||||||
layerRef: React.RefObject<HTMLDivElement>,
|
layerRef: React.RefObject<HTMLDivElement>,
|
||||||
|
|
|
@ -37,6 +37,9 @@ export function useCanvasEvents() {
|
||||||
const onPointerUp = React.useCallback(
|
const onPointerUp = React.useCallback(
|
||||||
(e: React.PointerEvent) => {
|
(e: React.PointerEvent) => {
|
||||||
if (e.button !== 0) return
|
if (e.button !== 0) return
|
||||||
|
|
||||||
|
inputs.activePointer = undefined
|
||||||
|
|
||||||
if (!inputs.pointerIsValid(e)) return
|
if (!inputs.pointerIsValid(e)) return
|
||||||
const isDoubleClick = inputs.isDoubleClick()
|
const isDoubleClick = inputs.isDoubleClick()
|
||||||
const info = inputs.pointerUp(e, 'canvas')
|
const info = inputs.pointerUp(e, 'canvas')
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { TLBinding, TLPage, TLPageState, TLShape } from '~types'
|
import type { TLBinding, TLPage, TLPageState, TLShape } from '../types'
|
||||||
|
|
||||||
export function useHandles<T extends TLShape>(page: TLPage<T, TLBinding>, pageState: TLPageState) {
|
export function useHandles<T extends TLShape>(page: TLPage<T, TLBinding>, pageState: TLPageState) {
|
||||||
const { selectedIds } = pageState
|
const { selectedIds } = pageState
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useTLContext } from '~hooks'
|
import { useTLContext } from '../hooks'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
|
|
||||||
export function useKeyEvents() {
|
export function useKeyEvents() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import type { TLBounds } from '~types'
|
import type { TLBounds } from '../types'
|
||||||
|
|
||||||
export function usePosition(bounds: TLBounds, rotation = 0) {
|
export function usePosition(bounds: TLBounds, rotation = 0) {
|
||||||
const rBounds = React.useRef<HTMLDivElement>(null)
|
const rBounds = React.useRef<HTMLDivElement>(null)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
/* eslint-disable @typescript-eslint/ban-ts-comment */
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { useTLContext } from '~hooks'
|
import { useTLContext } from './useTLContext'
|
||||||
|
|
||||||
export function usePreventNavigation(rCanvas: React.RefObject<HTMLDivElement>): void {
|
export function usePreventNavigation(rCanvas: React.RefObject<HTMLDivElement>): void {
|
||||||
const { bounds } = useTLContext()
|
const { bounds } = useTLContext()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useTLContext } from '~hooks'
|
import { useTLContext } from '../hooks'
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import { Utils } from '~utils'
|
import { Utils } from '../utils'
|
||||||
import type { TLBounds } from '~types'
|
import type { TLBounds } from '../types'
|
||||||
|
|
||||||
export function useResizeObserver<T extends Element>(
|
export function useResizeObserver<T extends Element>(
|
||||||
ref: React.RefObject<T>,
|
ref: React.RefObject<T>,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect } from 'react'
|
import { useEffect } from 'react'
|
||||||
import Utils from '~utils'
|
import Utils from '../utils'
|
||||||
import { useTLContext } from './useTLContext'
|
import { useTLContext } from './useTLContext'
|
||||||
|
|
||||||
// Send event on iOS when a user presses the "Done" key while editing a text element.
|
// Send event on iOS when a user presses the "Done" key while editing a text element.
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import type { TLPage, TLPageState, TLShape, TLBounds, TLBinding } from '~types'
|
import type { TLPage, TLPageState, TLShape, TLBounds, TLBinding } from '../types'
|
||||||
import Utils from '~utils'
|
import Utils from '../utils'
|
||||||
import { useTLContext } from '~hooks'
|
import { useTLContext } from './useTLContext'
|
||||||
import type { TLShapeUtil, TLShapeUtilsMap } from '~shape-utils'
|
import type { TLShapeUtil, TLShapeUtilsMap } from '../TLShapeUtil'
|
||||||
|
|
||||||
function canvasToScreen(point: number[], camera: TLPageState['camera']): number[] {
|
function canvasToScreen(point: number[], camera: TLPageState['camera']): number[] {
|
||||||
return [(point[0] + camera.point[0]) * camera.zoom, (point[1] + camera.point[1]) * camera.zoom]
|
return [(point[0] + camera.point[0]) * camera.zoom, (point[1] + camera.point[1]) * camera.zoom]
|
||||||
|
|
|
@ -43,6 +43,9 @@ export function useShapeEvents(id: string) {
|
||||||
const onPointerUp = React.useCallback(
|
const onPointerUp = React.useCallback(
|
||||||
(e: React.PointerEvent) => {
|
(e: React.PointerEvent) => {
|
||||||
if (e.button !== 0) return
|
if (e.button !== 0) return
|
||||||
|
|
||||||
|
inputs.activePointer = undefined
|
||||||
|
|
||||||
if (!inputs.pointerIsValid(e)) return
|
if (!inputs.pointerIsValid(e)) return
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
const isDoubleClick = inputs.isDoubleClick()
|
const isDoubleClick = inputs.isDoubleClick()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
import type { Inputs } from '~inputs'
|
import type { Inputs } from '~inputs'
|
||||||
import type { TLCallbacks, TLShape, TLBounds, TLPageState } from '~types'
|
import type { TLCallbacks, TLShape, TLBounds, TLPageState } from '~types'
|
||||||
import type { TLShapeUtilsMap } from '~shape-utils'
|
import type { TLShapeUtilsMap } from '~TLShapeUtil'
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
export interface TLContextType<T extends TLShape> {
|
export interface TLContextType<T extends TLShape> {
|
||||||
|
|
|
@ -2,4 +2,4 @@ export * from './components'
|
||||||
export * from './types'
|
export * from './types'
|
||||||
export * from './utils'
|
export * from './utils'
|
||||||
export * from './inputs'
|
export * from './inputs'
|
||||||
export * from './shape-utils'
|
export * from './TLShapeUtil'
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import type React from 'react'
|
import type React from 'react'
|
||||||
import type { TLKeyboardInfo, TLPointerInfo } from './types'
|
import type { TLBounds, TLKeyboardInfo, TLPointerInfo } from './types'
|
||||||
import { Utils } from './utils'
|
import { Utils } from './utils'
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
import type { TLBounds } from '~index'
|
|
||||||
|
|
||||||
const DOUBLE_CLICK_DURATION = 250
|
const DOUBLE_CLICK_DURATION = 250
|
||||||
|
|
||||||
|
@ -32,12 +31,16 @@ export class Inputs {
|
||||||
|
|
||||||
pointerIsValid(e: TouchEvent | React.TouchEvent | PointerEvent | React.PointerEvent) {
|
pointerIsValid(e: TouchEvent | React.TouchEvent | PointerEvent | React.PointerEvent) {
|
||||||
if ('pointerId' in e) {
|
if ('pointerId' in e) {
|
||||||
if (this.activePointer && this.activePointer !== e.pointerId) return false
|
if (this.activePointer && this.activePointer !== e.pointerId) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('touches' in e) {
|
if ('touches' in e) {
|
||||||
const touch = e.changedTouches[0]
|
const touch = e.changedTouches[0]
|
||||||
if (this.activePointer && this.activePointer !== touch.identifier) return false
|
if (this.activePointer && this.activePointer !== touch.identifier) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { mockUtils } from './mockUtils'
|
||||||
import { useTLTheme, TLContext, TLContextType } from '../hooks'
|
import { useTLTheme, TLContext, TLContextType } from '../hooks'
|
||||||
import { Inputs } from '~inputs'
|
import { Inputs } from '~inputs'
|
||||||
import type { TLShape } from '~index'
|
import type { TLShape } from '~index'
|
||||||
import type { BoxShape } from '~shape-utils/TLShapeUtil.spec'
|
import type { BoxShape } from '~TLShapeUtil/TLShapeUtil.spec'
|
||||||
|
|
||||||
export const ContextWrapper: React.FC = ({ children }) => {
|
export const ContextWrapper: React.FC = ({ children }) => {
|
||||||
useTLTheme()
|
useTLTheme()
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { BoxShape } from '~shape-utils/TLShapeUtil.spec'
|
import type { BoxShape } from '~TLShapeUtil/TLShapeUtil.spec'
|
||||||
import type { TLBinding, TLPage, TLPageState } from '~types'
|
import type { TLBinding, TLPage, TLPageState } from '~types'
|
||||||
|
|
||||||
export const mockDocument: { page: TLPage<BoxShape, TLBinding>; pageState: TLPageState } = {
|
export const mockDocument: { page: TLPage<BoxShape, TLBinding>; pageState: TLPageState } = {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { BoxUtil } from '~shape-utils/TLShapeUtil.spec'
|
import { BoxUtil } from '~TLShapeUtil/TLShapeUtil.spec'
|
||||||
|
|
||||||
export const mockUtils = {
|
export const mockUtils = {
|
||||||
box: new BoxUtil(),
|
box: new BoxUtil(),
|
||||||
|
|
|
@ -75,9 +75,9 @@ export interface TLComponentProps<T extends TLShape, E = any, M = any> {
|
||||||
isSelected: boolean
|
isSelected: boolean
|
||||||
isGhost?: boolean
|
isGhost?: boolean
|
||||||
isChildOfSelected?: boolean
|
isChildOfSelected?: boolean
|
||||||
meta: M extends any ? M : never
|
meta: M
|
||||||
onShapeChange?: TLCallbacks<T>['onShapeChange']
|
onShapeChange?: TLShapeChangeHandler<T, any>
|
||||||
onShapeBlur?: TLCallbacks<T>['onShapeBlur']
|
onShapeBlur?: TLShapeBlurHandler<any>
|
||||||
events: {
|
events: {
|
||||||
onPointerDown: (e: React.PointerEvent<E>) => void
|
onPointerDown: (e: React.PointerEvent<E>) => void
|
||||||
onPointerUp: (e: React.PointerEvent<E>) => void
|
onPointerUp: (e: React.PointerEvent<E>) => void
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
"@radix-ui/react-radio-group": "^0.1.1",
|
"@radix-ui/react-radio-group": "^0.1.1",
|
||||||
"@radix-ui/react-tooltip": "^0.1.1",
|
"@radix-ui/react-tooltip": "^0.1.1",
|
||||||
"@stitches/react": "^1.2.5",
|
"@stitches/react": "^1.2.5",
|
||||||
"@tldraw/core": "latest",
|
"@tldraw/core": "^1.0.4",
|
||||||
"@tldraw/intersect": "latest",
|
"@tldraw/intersect": "latest",
|
||||||
"@tldraw/vec": "latest",
|
"@tldraw/vec": "latest",
|
||||||
"perfect-freehand": "^1.0.16",
|
"perfect-freehand": "^1.0.16",
|
||||||
|
|
|
@ -14,6 +14,7 @@ import { getEllipseIndicatorPathTDSnapshot, getEllipsePath } from './ellipseHelp
|
||||||
|
|
||||||
type T = EllipseShape
|
type T = EllipseShape
|
||||||
type E = SVGSVGElement
|
type E = SVGSVGElement
|
||||||
|
type M = TDMeta
|
||||||
|
|
||||||
export class EllipseUtil extends TDShapeUtil<T, E> {
|
export class EllipseUtil extends TDShapeUtil<T, E> {
|
||||||
type = TDShapeType.Ellipse as const
|
type = TDShapeType.Ellipse as const
|
||||||
|
@ -128,7 +129,7 @@ export class EllipseUtil extends TDShapeUtil<T, E> {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
Indicator = TDShapeUtil.Indicator<T>(({ shape }) => {
|
Indicator = TDShapeUtil.Indicator<T, M>(({ shape }) => {
|
||||||
return <path d={getEllipseIndicatorPathTDSnapshot(shape, this.getCenter(shape))} />
|
return <path d={getEllipseIndicatorPathTDSnapshot(shape, this.getCenter(shape))} />
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue