kopia lustrzana https://github.com/Tldraw/Tldraw
filter snappable shapes, give viewport information to sessions
rodzic
f8a7e3a681
commit
91b4184162
|
@ -1,357 +1,322 @@
|
||||||
import type React from 'react'
|
import type React from 'react';
|
||||||
import { MutableRefObject } from 'react-router/node_modules/@types/react'
|
|
||||||
export declare type Patch<T> = Partial<{
|
export declare type Patch<T> = Partial<{
|
||||||
[P in keyof T]: T | Partial<T> | Patch<T[P]>
|
[P in keyof T]: T | Partial<T> | Patch<T[P]>;
|
||||||
}>
|
}>;
|
||||||
|
declare type ForwardedRef<T> = ((instance: T | null) => void) | React.MutableRefObject<T | null> | null;
|
||||||
export interface TLPage<T extends TLShape, B extends TLBinding> {
|
export interface TLPage<T extends TLShape, B extends TLBinding> {
|
||||||
id: string
|
id: string;
|
||||||
name?: string
|
name?: string;
|
||||||
childIndex?: number
|
childIndex?: number;
|
||||||
shapes: Record<string, T>
|
shapes: Record<string, T>;
|
||||||
bindings: Record<string, B>
|
bindings: Record<string, B>;
|
||||||
}
|
}
|
||||||
export interface TLPageState {
|
export interface TLPageState {
|
||||||
id: string
|
id: string;
|
||||||
selectedIds: string[]
|
selectedIds: string[];
|
||||||
camera: {
|
camera: {
|
||||||
point: number[]
|
point: number[];
|
||||||
zoom: number
|
zoom: number;
|
||||||
}
|
};
|
||||||
brush?: TLBounds
|
brush?: TLBounds | null;
|
||||||
pointedId?: string | null
|
pointedId?: string | null;
|
||||||
hoveredId?: string | null
|
hoveredId?: string | null;
|
||||||
editingId?: string | null
|
editingId?: string | null;
|
||||||
bindingId?: string | null
|
bindingId?: string | null;
|
||||||
boundsRotation?: number
|
boundsRotation?: number;
|
||||||
currentParentId?: string | null
|
currentParentId?: string | null;
|
||||||
}
|
}
|
||||||
|
export interface TLUser<T extends TLShape> {
|
||||||
|
id: string;
|
||||||
|
color: string;
|
||||||
|
point: number[];
|
||||||
|
selectedIds: string[];
|
||||||
|
activeShapes: T[];
|
||||||
|
}
|
||||||
|
export declare type TLUsers<T extends TLShape, U extends TLUser<T> = TLUser<T>> = Record<string, U>;
|
||||||
|
export declare type TLSnapLine = number[][];
|
||||||
export interface TLHandle {
|
export interface TLHandle {
|
||||||
id: string
|
id: string;
|
||||||
index: number
|
index: number;
|
||||||
point: number[]
|
point: number[];
|
||||||
canBind?: boolean
|
canBind?: boolean;
|
||||||
bindingId?: string
|
bindingId?: string;
|
||||||
}
|
}
|
||||||
export interface TLShape {
|
export interface TLShape {
|
||||||
id: string
|
id: string;
|
||||||
type: string
|
type: string;
|
||||||
parentId: string
|
parentId: string;
|
||||||
childIndex: number
|
childIndex: number;
|
||||||
name: string
|
name: string;
|
||||||
point: number[]
|
point: number[];
|
||||||
rotation?: number
|
rotation?: number;
|
||||||
children?: string[]
|
children?: string[];
|
||||||
handles?: Record<string, TLHandle>
|
handles?: Record<string, TLHandle>;
|
||||||
isLocked?: boolean
|
isLocked?: boolean;
|
||||||
isHidden?: boolean
|
isHidden?: boolean;
|
||||||
isEditing?: boolean
|
isEditing?: boolean;
|
||||||
isGenerated?: boolean
|
isGenerated?: boolean;
|
||||||
isAspectRatioLocked?: boolean
|
isAspectRatioLocked?: boolean;
|
||||||
}
|
}
|
||||||
export declare type TLShapeUtils<
|
export declare type TLShapeUtils<T extends TLShape = any, E extends Element = any, M = any, K = any> = Record<string, TLShapeUtil<T, E, M, K>>;
|
||||||
T extends TLShape = any,
|
|
||||||
E extends Element = any,
|
|
||||||
M = any,
|
|
||||||
K = any
|
|
||||||
> = Record<string, TLShapeUtil<T, E, M, K>>
|
|
||||||
export interface TLRenderInfo<T extends TLShape, E = any, M = any> {
|
export interface TLRenderInfo<T extends TLShape, E = any, M = any> {
|
||||||
shape: T
|
shape: T;
|
||||||
isEditing: boolean
|
isEditing: boolean;
|
||||||
isBinding: boolean
|
isBinding: boolean;
|
||||||
isHovered: boolean
|
isHovered: boolean;
|
||||||
isSelected: boolean
|
isSelected: boolean;
|
||||||
isCurrentParent: boolean
|
isCurrentParent: boolean;
|
||||||
meta: M extends any ? M : never
|
meta: M extends any ? M : never;
|
||||||
onShapeChange?: TLCallbacks<T>['onShapeChange']
|
onShapeChange?: TLCallbacks<T>['onShapeChange'];
|
||||||
onShapeBlur?: TLCallbacks<T>['onShapeBlur']
|
onShapeBlur?: TLCallbacks<T>['onShapeBlur'];
|
||||||
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;
|
||||||
onPointerEnter: (e: React.PointerEvent<E>) => void
|
onPointerEnter: (e: React.PointerEvent<E>) => void;
|
||||||
onPointerMove: (e: React.PointerEvent<E>) => void
|
onPointerMove: (e: React.PointerEvent<E>) => void;
|
||||||
onPointerLeave: (e: React.PointerEvent<E>) => void
|
onPointerLeave: (e: React.PointerEvent<E>) => void;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
export interface TLShapeProps<T extends TLShape, E = any, M = any> extends TLRenderInfo<T, E, M> {
|
export interface TLShapeProps<T extends TLShape, E = any, M = any> extends TLRenderInfo<T, E, M> {
|
||||||
ref: MutableRefObject<E>
|
ref: ForwardedRef<E>;
|
||||||
shape: T
|
shape: T;
|
||||||
}
|
}
|
||||||
export interface TLTool {
|
export interface TLTool {
|
||||||
id: string
|
id: string;
|
||||||
name: string
|
name: string;
|
||||||
}
|
}
|
||||||
export interface TLBinding<M = any> {
|
export interface TLBinding<M = any> {
|
||||||
id: string
|
id: string;
|
||||||
type: string
|
type: string;
|
||||||
toId: string
|
toId: string;
|
||||||
fromId: string
|
fromId: string;
|
||||||
meta: M
|
meta: M;
|
||||||
}
|
}
|
||||||
export interface TLTheme {
|
export interface TLTheme {
|
||||||
brushFill?: string
|
accent?: string;
|
||||||
brushStroke?: string
|
brushFill?: string;
|
||||||
selectFill?: string
|
brushStroke?: string;
|
||||||
selectStroke?: string
|
selectFill?: string;
|
||||||
background?: string
|
selectStroke?: string;
|
||||||
foreground?: string
|
background?: string;
|
||||||
|
foreground?: string;
|
||||||
}
|
}
|
||||||
export declare type TLWheelEventHandler = (
|
export declare type TLWheelEventHandler = (info: TLPointerInfo<string>, e: React.WheelEvent<Element> | WheelEvent) => void;
|
||||||
info: TLPointerInfo<string>,
|
export declare type TLPinchEventHandler = (info: TLPointerInfo<string>, e: React.WheelEvent<Element> | WheelEvent | React.TouchEvent<Element> | TouchEvent | React.PointerEvent<Element> | PointerEventInit) => void;
|
||||||
e: React.WheelEvent<Element> | WheelEvent
|
export declare type TLShapeChangeHandler<T, K = any> = (shape: {
|
||||||
) => void
|
id: string;
|
||||||
export declare type TLPinchEventHandler = (
|
} & Partial<T>, info?: K) => void;
|
||||||
info: TLPointerInfo<string>,
|
export declare type TLShapeBlurHandler<K = any> = (info?: K) => void;
|
||||||
e:
|
export declare type TLKeyboardEventHandler = (key: string, info: TLKeyboardInfo, e: KeyboardEvent) => void;
|
||||||
| React.WheelEvent<Element>
|
export declare type TLPointerEventHandler = (info: TLPointerInfo<string>, e: React.PointerEvent) => void;
|
||||||
| WheelEvent
|
export declare type TLShapeCloneHandler = (info: TLPointerInfo<'top' | 'right' | 'bottom' | 'left' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'>, e: React.PointerEvent) => void;
|
||||||
| React.TouchEvent<Element>
|
export declare type TLShapeLinkHandler = (info: TLPointerInfo<'link'>, e: React.PointerEvent) => void;
|
||||||
| TouchEvent
|
export declare type TLCanvasEventHandler = (info: TLPointerInfo<'canvas'>, e: React.PointerEvent) => void;
|
||||||
| React.PointerEvent<Element>
|
export declare type TLBoundsEventHandler = (info: TLPointerInfo<'bounds'>, e: React.PointerEvent) => void;
|
||||||
| PointerEventInit
|
export declare type TLBoundsHandleEventHandler = (info: TLPointerInfo<TLBoundsCorner | TLBoundsEdge | 'rotate' | 'center' | 'left' | 'right'>, e: React.PointerEvent) => void;
|
||||||
) => void
|
|
||||||
export declare type TLPointerEventHandler = (
|
|
||||||
info: TLPointerInfo<string>,
|
|
||||||
e: React.PointerEvent
|
|
||||||
) => void
|
|
||||||
export declare type TLCanvasEventHandler = (
|
|
||||||
info: TLPointerInfo<'canvas'>,
|
|
||||||
e: React.PointerEvent
|
|
||||||
) => void
|
|
||||||
export declare type TLBoundsEventHandler = (
|
|
||||||
info: TLPointerInfo<'bounds'>,
|
|
||||||
e: React.PointerEvent
|
|
||||||
) => void
|
|
||||||
export declare type TLBoundsHandleEventHandler = (
|
|
||||||
info: TLPointerInfo<TLBoundsCorner | TLBoundsEdge | 'rotate'>,
|
|
||||||
e: React.PointerEvent
|
|
||||||
) => void
|
|
||||||
export interface TLCallbacks<T extends TLShape> {
|
export interface TLCallbacks<T extends TLShape> {
|
||||||
onPinchStart: TLPinchEventHandler
|
onPinchStart: TLPinchEventHandler;
|
||||||
onPinchEnd: TLPinchEventHandler
|
onPinchEnd: TLPinchEventHandler;
|
||||||
onPinch: TLPinchEventHandler
|
onPinch: TLPinchEventHandler;
|
||||||
onPan: TLWheelEventHandler
|
onPan: TLWheelEventHandler;
|
||||||
onZoom: TLWheelEventHandler
|
onZoom: TLWheelEventHandler;
|
||||||
onPointerMove: TLPointerEventHandler
|
onPointerMove: TLPointerEventHandler;
|
||||||
onPointerUp: TLPointerEventHandler
|
onPointerUp: TLPointerEventHandler;
|
||||||
onPointerDown: TLPointerEventHandler
|
onPointerDown: TLPointerEventHandler;
|
||||||
onPointCanvas: TLCanvasEventHandler
|
onPointCanvas: TLCanvasEventHandler;
|
||||||
onDoubleClickCanvas: TLCanvasEventHandler
|
onDoubleClickCanvas: TLCanvasEventHandler;
|
||||||
onRightPointCanvas: TLCanvasEventHandler
|
onRightPointCanvas: TLCanvasEventHandler;
|
||||||
onDragCanvas: TLCanvasEventHandler
|
onDragCanvas: TLCanvasEventHandler;
|
||||||
onReleaseCanvas: TLCanvasEventHandler
|
onReleaseCanvas: TLCanvasEventHandler;
|
||||||
onPointShape: TLPointerEventHandler
|
onPointShape: TLPointerEventHandler;
|
||||||
onDoubleClickShape: TLPointerEventHandler
|
onDoubleClickShape: TLPointerEventHandler;
|
||||||
onRightPointShape: TLPointerEventHandler
|
onRightPointShape: TLPointerEventHandler;
|
||||||
onDragShape: TLPointerEventHandler
|
onDragShape: TLPointerEventHandler;
|
||||||
onHoverShape: TLPointerEventHandler
|
onHoverShape: TLPointerEventHandler;
|
||||||
onUnhoverShape: TLPointerEventHandler
|
onUnhoverShape: TLPointerEventHandler;
|
||||||
onReleaseShape: TLPointerEventHandler
|
onReleaseShape: TLPointerEventHandler;
|
||||||
onPointBounds: TLBoundsEventHandler
|
onPointBounds: TLBoundsEventHandler;
|
||||||
onDoubleClickBounds: TLBoundsEventHandler
|
onDoubleClickBounds: TLBoundsEventHandler;
|
||||||
onRightPointBounds: TLBoundsEventHandler
|
onRightPointBounds: TLBoundsEventHandler;
|
||||||
onDragBounds: TLBoundsEventHandler
|
onDragBounds: TLBoundsEventHandler;
|
||||||
onHoverBounds: TLBoundsEventHandler
|
onHoverBounds: TLBoundsEventHandler;
|
||||||
onUnhoverBounds: TLBoundsEventHandler
|
onUnhoverBounds: TLBoundsEventHandler;
|
||||||
onReleaseBounds: TLBoundsEventHandler
|
onReleaseBounds: TLBoundsEventHandler;
|
||||||
onPointBoundsHandle: TLBoundsHandleEventHandler
|
onPointBoundsHandle: TLBoundsHandleEventHandler;
|
||||||
onDoubleClickBoundsHandle: TLBoundsHandleEventHandler
|
onDoubleClickBoundsHandle: TLBoundsHandleEventHandler;
|
||||||
onRightPointBoundsHandle: TLBoundsHandleEventHandler
|
onRightPointBoundsHandle: TLBoundsHandleEventHandler;
|
||||||
onDragBoundsHandle: TLBoundsHandleEventHandler
|
onDragBoundsHandle: TLBoundsHandleEventHandler;
|
||||||
onHoverBoundsHandle: TLBoundsHandleEventHandler
|
onHoverBoundsHandle: TLBoundsHandleEventHandler;
|
||||||
onUnhoverBoundsHandle: TLBoundsHandleEventHandler
|
onUnhoverBoundsHandle: TLBoundsHandleEventHandler;
|
||||||
onReleaseBoundsHandle: TLBoundsHandleEventHandler
|
onReleaseBoundsHandle: TLBoundsHandleEventHandler;
|
||||||
onPointHandle: TLPointerEventHandler
|
onPointHandle: TLPointerEventHandler;
|
||||||
onDoubleClickHandle: TLPointerEventHandler
|
onDoubleClickHandle: TLPointerEventHandler;
|
||||||
onRightPointHandle: TLPointerEventHandler
|
onRightPointHandle: TLPointerEventHandler;
|
||||||
onDragHandle: TLPointerEventHandler
|
onDragHandle: TLPointerEventHandler;
|
||||||
onHoverHandle: TLPointerEventHandler
|
onHoverHandle: TLPointerEventHandler;
|
||||||
onUnhoverHandle: TLPointerEventHandler
|
onUnhoverHandle: TLPointerEventHandler;
|
||||||
onReleaseHandle: TLPointerEventHandler
|
onReleaseHandle: TLPointerEventHandler;
|
||||||
onRenderCountChange: (ids: string[]) => void
|
onShapeChange: TLShapeChangeHandler<T, any>;
|
||||||
onShapeChange: (
|
onShapeBlur: TLShapeBlurHandler<any>;
|
||||||
shape: {
|
onShapeClone: TLShapeCloneHandler;
|
||||||
id: string
|
onRenderCountChange: (ids: string[]) => void;
|
||||||
} & Partial<T>
|
onError: (error: Error) => void;
|
||||||
) => void
|
onBoundsChange: (bounds: TLBounds) => void;
|
||||||
onShapeBlur: () => void
|
onKeyDown: TLKeyboardEventHandler;
|
||||||
onError: (error: Error) => void
|
onKeyUp: TLKeyboardEventHandler;
|
||||||
}
|
}
|
||||||
export interface TLBounds {
|
export interface TLBounds {
|
||||||
minX: number
|
minX: number;
|
||||||
minY: number
|
minY: number;
|
||||||
maxX: number
|
maxX: number;
|
||||||
maxY: number
|
maxY: number;
|
||||||
width: number
|
width: number;
|
||||||
height: number
|
height: number;
|
||||||
rotation?: number
|
rotation?: number;
|
||||||
|
}
|
||||||
|
export interface TLBoundsWithCenter extends TLBounds {
|
||||||
|
midX: number;
|
||||||
|
midY: number;
|
||||||
}
|
}
|
||||||
export declare type TLIntersection = {
|
export declare type TLIntersection = {
|
||||||
didIntersect: boolean
|
didIntersect: boolean;
|
||||||
message: string
|
message: string;
|
||||||
points: number[][]
|
points: number[][];
|
||||||
}
|
};
|
||||||
export declare enum TLBoundsEdge {
|
export declare enum TLBoundsEdge {
|
||||||
Top = 'top_edge',
|
Top = "top_edge",
|
||||||
Right = 'right_edge',
|
Right = "right_edge",
|
||||||
Bottom = 'bottom_edge',
|
Bottom = "bottom_edge",
|
||||||
Left = 'left_edge',
|
Left = "left_edge"
|
||||||
}
|
}
|
||||||
export declare enum TLBoundsCorner {
|
export declare enum TLBoundsCorner {
|
||||||
TopLeft = 'top_left_corner',
|
TopLeft = "top_left_corner",
|
||||||
TopRight = 'top_right_corner',
|
TopRight = "top_right_corner",
|
||||||
BottomRight = 'bottom_right_corner',
|
BottomRight = "bottom_right_corner",
|
||||||
BottomLeft = 'bottom_left_corner',
|
BottomLeft = "bottom_left_corner"
|
||||||
}
|
}
|
||||||
export interface TLPointerInfo<T extends string = string> {
|
export interface TLPointerInfo<T extends string = string> {
|
||||||
target: T
|
target: T;
|
||||||
pointerId: number
|
pointerId: number;
|
||||||
origin: number[]
|
origin: number[];
|
||||||
point: number[]
|
point: number[];
|
||||||
delta: number[]
|
delta: number[];
|
||||||
pressure: number
|
pressure: number;
|
||||||
shiftKey: boolean
|
shiftKey: boolean;
|
||||||
ctrlKey: boolean
|
ctrlKey: boolean;
|
||||||
metaKey: boolean
|
metaKey: boolean;
|
||||||
altKey: boolean
|
altKey: boolean;
|
||||||
|
spaceKey: boolean;
|
||||||
}
|
}
|
||||||
export interface TLKeyboardInfo {
|
export interface TLKeyboardInfo {
|
||||||
origin: number[]
|
origin: number[];
|
||||||
point: number[]
|
point: number[];
|
||||||
key: string
|
key: string;
|
||||||
keys: string[]
|
keys: string[];
|
||||||
shiftKey: boolean
|
shiftKey: boolean;
|
||||||
ctrlKey: boolean
|
ctrlKey: boolean;
|
||||||
metaKey: boolean
|
metaKey: boolean;
|
||||||
altKey: boolean
|
altKey: boolean;
|
||||||
}
|
}
|
||||||
export interface TLTransformInfo<T extends TLShape> {
|
export interface TLTransformInfo<T extends TLShape> {
|
||||||
type: TLBoundsEdge | TLBoundsCorner
|
type: TLBoundsEdge | TLBoundsCorner;
|
||||||
initialShape: T
|
initialShape: T;
|
||||||
scaleX: number
|
scaleX: number;
|
||||||
scaleY: number
|
scaleY: number;
|
||||||
transformOrigin: number[]
|
transformOrigin: number[];
|
||||||
}
|
}
|
||||||
export interface TLBezierCurveSegment {
|
export interface TLBezierCurveSegment {
|
||||||
start: number[]
|
start: number[];
|
||||||
tangentStart: number[]
|
tangentStart: number[];
|
||||||
normalStart: number[]
|
normalStart: number[];
|
||||||
pressureStart: number
|
pressureStart: number;
|
||||||
end: number[]
|
end: number[];
|
||||||
tangentEnd: number[]
|
tangentEnd: number[];
|
||||||
normalEnd: number[]
|
normalEnd: number[];
|
||||||
pressureEnd: number
|
pressureEnd: number;
|
||||||
}
|
}
|
||||||
export declare type TLShapeUtil<
|
export declare enum SnapPoints {
|
||||||
T extends TLShape,
|
minX = "minX",
|
||||||
E extends Element,
|
midX = "midX",
|
||||||
M = any,
|
maxX = "maxX",
|
||||||
K = {
|
minY = "minY",
|
||||||
[key: string]: any
|
midY = "midY",
|
||||||
}
|
maxY = "maxY"
|
||||||
> = K & {
|
|
||||||
type: T['type']
|
|
||||||
defaultProps: T
|
|
||||||
Component(
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
props: TLRenderInfo<T, E, M>,
|
|
||||||
ref: React.MutableRefObject<E>
|
|
||||||
): React.ReactElement<TLRenderInfo<T, E, M>, E['tagName']>
|
|
||||||
Indicator(
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
props: {
|
|
||||||
shape: T
|
|
||||||
}
|
|
||||||
): React.ReactElement | null
|
|
||||||
getBounds(this: TLShapeUtil<T, E, M>, shape: T): TLBounds
|
|
||||||
refMap: Map<string, React.RefObject<E>>
|
|
||||||
boundsCache: WeakMap<TLShape, TLBounds>
|
|
||||||
isAspectRatioLocked: boolean
|
|
||||||
canEdit: boolean
|
|
||||||
canBind: boolean
|
|
||||||
getRotatedBounds(this: TLShapeUtil<T, E, M>, shape: T): TLBounds
|
|
||||||
hitTest(this: TLShapeUtil<T, E, M>, shape: T, point: number[]): boolean
|
|
||||||
hitTestBounds(this: TLShapeUtil<T, E, M>, shape: T, bounds: TLBounds): boolean
|
|
||||||
shouldRender(this: TLShapeUtil<T, E, M>, prev: T, next: T): boolean
|
|
||||||
getCenter(this: TLShapeUtil<T, E, M>, shape: T): number[]
|
|
||||||
getRef(this: TLShapeUtil<T, E, M>, shape: T): React.RefObject<E>
|
|
||||||
getBindingPoint<K extends TLShape>(
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
shape: T,
|
|
||||||
fromShape: K,
|
|
||||||
point: number[],
|
|
||||||
origin: number[],
|
|
||||||
direction: number[],
|
|
||||||
padding: number,
|
|
||||||
bindAnywhere: boolean
|
|
||||||
):
|
|
||||||
| {
|
|
||||||
point: number[]
|
|
||||||
distance: number
|
|
||||||
}
|
|
||||||
| undefined
|
|
||||||
create: (
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
props: {
|
|
||||||
id: string
|
|
||||||
} & Partial<T>
|
|
||||||
) => T
|
|
||||||
mutate: (this: TLShapeUtil<T, E, M>, shape: T, props: Partial<T>) => Partial<T>
|
|
||||||
transform: (
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
shape: T,
|
|
||||||
bounds: TLBounds,
|
|
||||||
info: TLTransformInfo<T>
|
|
||||||
) => Partial<T> | void
|
|
||||||
transformSingle: (
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
shape: T,
|
|
||||||
bounds: TLBounds,
|
|
||||||
info: TLTransformInfo<T>
|
|
||||||
) => Partial<T> | void
|
|
||||||
updateChildren: <K extends TLShape>(
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
shape: T,
|
|
||||||
children: K[]
|
|
||||||
) => Partial<K>[] | void
|
|
||||||
onChildrenChange: (this: TLShapeUtil<T, E, M>, shape: T, children: TLShape[]) => Partial<T> | void
|
|
||||||
onBindingChange: (
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
shape: T,
|
|
||||||
binding: TLBinding,
|
|
||||||
target: TLShape,
|
|
||||||
targetBounds: TLBounds,
|
|
||||||
center: number[]
|
|
||||||
) => Partial<T> | void
|
|
||||||
onHandleChange: (
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
shape: T,
|
|
||||||
handle: Partial<T['handles']>,
|
|
||||||
info: Partial<TLPointerInfo>
|
|
||||||
) => Partial<T> | void
|
|
||||||
onRightPointHandle: (
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
shape: T,
|
|
||||||
handle: Partial<T['handles']>,
|
|
||||||
info: Partial<TLPointerInfo>
|
|
||||||
) => Partial<T> | void
|
|
||||||
onDoubleClickHandle: (
|
|
||||||
this: TLShapeUtil<T, E, M>,
|
|
||||||
shape: T,
|
|
||||||
handle: Partial<T['handles']>,
|
|
||||||
info: Partial<TLPointerInfo>
|
|
||||||
) => Partial<T> | void
|
|
||||||
onDoubleClickBoundsHandle: (this: TLShapeUtil<T, E, M>, shape: T) => Partial<T> | void
|
|
||||||
onSessionComplete: (this: TLShapeUtil<T, E, M>, shape: T) => Partial<T> | void
|
|
||||||
onStyleChange: (this: TLShapeUtil<T, E, M>, shape: T) => Partial<T> | void
|
|
||||||
_Component: React.ForwardRefExoticComponent<any>
|
|
||||||
}
|
}
|
||||||
|
export declare type Snap = {
|
||||||
|
id: SnapPoints;
|
||||||
|
isSnapped: false;
|
||||||
|
} | {
|
||||||
|
id: SnapPoints;
|
||||||
|
isSnapped: true;
|
||||||
|
to: number;
|
||||||
|
B: TLBoundsWithCenter;
|
||||||
|
distance: number;
|
||||||
|
};
|
||||||
|
export declare type TLShapeUtil<T extends TLShape, E extends Element, M = any, K = {
|
||||||
|
[key: string]: any;
|
||||||
|
}> = K & {
|
||||||
|
type: T['type'];
|
||||||
|
defaultProps: T;
|
||||||
|
Component(this: TLShapeUtil<T, E, M>, props: TLRenderInfo<T, E, M>, ref: ForwardedRef<E>): React.ReactElement<TLRenderInfo<T, E, M>, E['tagName']>;
|
||||||
|
Indicator(this: TLShapeUtil<T, E, M>, props: {
|
||||||
|
shape: T;
|
||||||
|
meta: M;
|
||||||
|
isHovered: boolean;
|
||||||
|
isSelected: boolean;
|
||||||
|
}): React.ReactElement | null;
|
||||||
|
getBounds(this: TLShapeUtil<T, E, M>, shape: T): TLBounds;
|
||||||
|
refMap: Map<string, React.RefObject<E>>;
|
||||||
|
boundsCache: WeakMap<TLShape, TLBounds>;
|
||||||
|
isAspectRatioLocked: boolean;
|
||||||
|
canEdit: boolean;
|
||||||
|
canClone: boolean;
|
||||||
|
canBind: boolean;
|
||||||
|
isStateful: boolean;
|
||||||
|
showBounds: boolean;
|
||||||
|
getRotatedBounds(this: TLShapeUtil<T, E, M>, shape: T): TLBounds;
|
||||||
|
hitTest(this: TLShapeUtil<T, E, M>, shape: T, point: number[]): boolean;
|
||||||
|
hitTestBounds(this: TLShapeUtil<T, E, M>, shape: T, bounds: TLBounds): boolean;
|
||||||
|
shouldRender(this: TLShapeUtil<T, E, M>, prev: T, next: T): boolean;
|
||||||
|
getCenter(this: TLShapeUtil<T, E, M>, shape: T): number[];
|
||||||
|
getRef(this: TLShapeUtil<T, E, M>, shape: T): React.RefObject<E>;
|
||||||
|
getBindingPoint<K extends TLShape>(this: TLShapeUtil<T, E, M>, shape: T, fromShape: K, point: number[], origin: number[], direction: number[], padding: number, bindAnywhere: boolean): {
|
||||||
|
point: number[];
|
||||||
|
distance: number;
|
||||||
|
} | undefined;
|
||||||
|
create: (this: TLShapeUtil<T, E, M>, props: {
|
||||||
|
id: string;
|
||||||
|
} & Partial<T>) => T;
|
||||||
|
mutate: (this: TLShapeUtil<T, E, M>, shape: T, props: Partial<T>) => Partial<T>;
|
||||||
|
transform: (this: TLShapeUtil<T, E, M>, shape: T, bounds: TLBounds, info: TLTransformInfo<T>) => Partial<T> | void;
|
||||||
|
transformSingle: (this: TLShapeUtil<T, E, M>, shape: T, bounds: TLBounds, info: TLTransformInfo<T>) => Partial<T> | void;
|
||||||
|
updateChildren: <K extends TLShape>(this: TLShapeUtil<T, E, M>, shape: T, children: K[]) => Partial<K>[] | void;
|
||||||
|
onChildrenChange: (this: TLShapeUtil<T, E, M>, shape: T, children: TLShape[]) => Partial<T> | void;
|
||||||
|
onBindingChange: (this: TLShapeUtil<T, E, M>, shape: T, binding: TLBinding, target: TLShape, targetBounds: TLBounds, center: number[]) => Partial<T> | void;
|
||||||
|
onHandleChange: (this: TLShapeUtil<T, E, M>, shape: T, handle: Partial<T['handles']>, info: Partial<TLPointerInfo>) => Partial<T> | void;
|
||||||
|
onRightPointHandle: (this: TLShapeUtil<T, E, M>, shape: T, handle: Partial<T['handles']>, info: Partial<TLPointerInfo>) => Partial<T> | void;
|
||||||
|
onDoubleClickHandle: (this: TLShapeUtil<T, E, M>, shape: T, handle: Partial<T['handles']>, info: Partial<TLPointerInfo>) => Partial<T> | void;
|
||||||
|
onDoubleClickBoundsHandle: (this: TLShapeUtil<T, E, M>, shape: T) => Partial<T> | void;
|
||||||
|
onSessionComplete: (this: TLShapeUtil<T, E, M>, shape: T) => Partial<T> | void;
|
||||||
|
onStyleChange: (this: TLShapeUtil<T, E, M>, shape: T) => Partial<T> | void;
|
||||||
|
_Component: React.ForwardRefExoticComponent<any>;
|
||||||
|
};
|
||||||
export interface IShapeTreeNode<T extends TLShape, M = any> {
|
export interface IShapeTreeNode<T extends TLShape, M = any> {
|
||||||
shape: T
|
shape: T;
|
||||||
children?: IShapeTreeNode<TLShape, M>[]
|
children?: IShapeTreeNode<TLShape, M>[];
|
||||||
isEditing: boolean
|
isEditing: boolean;
|
||||||
isBinding: boolean
|
isBinding: boolean;
|
||||||
isHovered: boolean
|
isHovered: boolean;
|
||||||
isSelected: boolean
|
isSelected: boolean;
|
||||||
isCurrentParent: boolean
|
isCurrentParent: boolean;
|
||||||
meta?: M extends any ? M : never
|
meta?: M extends any ? M : never;
|
||||||
}
|
}
|
||||||
|
export declare type MappedByType<K extends string, T extends {
|
||||||
|
type: K;
|
||||||
|
}> = {
|
||||||
|
[P in T['type']]: T extends any ? (P extends T['type'] ? T : never) : never;
|
||||||
|
};
|
||||||
|
export declare type RequiredKeys<T> = {
|
||||||
|
[K in keyof T]-?: Record<string, unknown> extends Pick<T, K> ? never : K;
|
||||||
|
}[keyof T];
|
||||||
|
export {};
|
||||||
|
//# sourceMappingURL=types.d.ts.map
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,5 @@
|
||||||
|
import { Utils } from './utils';
|
||||||
|
export { Utils } from './utils';
|
||||||
|
export { Svg } from './svg';
|
||||||
|
export default Utils;
|
||||||
|
//# sourceMappingURL=index.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAE3B,eAAe,KAAK,CAAA"}
|
|
@ -0,0 +1 @@
|
||||||
|
//# sourceMappingURL=polyfills.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"polyfills.d.ts","sourceRoot":"","sources":["polyfills.ts"],"names":[],"mappings":""}
|
|
@ -0,0 +1,15 @@
|
||||||
|
export declare class Svg {
|
||||||
|
static ellipse: (A: number[], r: number) => string;
|
||||||
|
static moveTo: (v: number[]) => string;
|
||||||
|
static lineTo: (v: number[]) => string;
|
||||||
|
static line: (a: number[], ...pts: number[][]) => string;
|
||||||
|
static hLineTo: (v: number[]) => string;
|
||||||
|
static vLineTo: (v: number[]) => string;
|
||||||
|
static bezierTo: (A: number[], B: number[], C: number[]) => string;
|
||||||
|
static arcTo: (C: number[], r: number, A: number[], B: number[]) => string;
|
||||||
|
static closePath: () => string;
|
||||||
|
static rectTo: (A: number[]) => string;
|
||||||
|
static getPointAtLength: (path: SVGPathElement, length: number) => number[];
|
||||||
|
}
|
||||||
|
export default Svg;
|
||||||
|
//# sourceMappingURL=svg.d.ts.map
|
|
@ -0,0 +1 @@
|
||||||
|
{"version":3,"file":"svg.d.ts","sourceRoot":"","sources":["svg.ts"],"names":[],"mappings":"AAIA,qBAAa,GAAG;IACd,MAAM,CAAC,OAAO,MAAO,MAAM,EAAE,KAAK,MAAM,KAAG,MAAM,CAIhD;IAED,MAAM,CAAC,MAAM,MAAO,MAAM,EAAE,KAAG,MAAM,CAEpC;IAED,MAAM,CAAC,MAAM,MAAO,MAAM,EAAE,KAAG,MAAM,CAEpC;IAED,MAAM,CAAC,IAAI,MAAO,MAAM,EAAE,UAAU,MAAM,EAAE,EAAE,KAAG,MAAM,CAEtD;IAED,MAAM,CAAC,OAAO,MAAO,MAAM,EAAE,KAAG,MAAM,CAErC;IAED,MAAM,CAAC,OAAO,MAAO,MAAM,EAAE,KAAG,MAAM,CAErC;IAED,MAAM,CAAC,QAAQ,MAAO,MAAM,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,KAAG,MAAM,CAEhE;IAED,MAAM,CAAC,KAAK,MAAO,MAAM,EAAE,KAAK,MAAM,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,KAAG,MAAM,CAYxE;IAED,MAAM,CAAC,SAAS,QAAO,MAAM,CAE5B;IAED,MAAM,CAAC,MAAM,MAAO,MAAM,EAAE,KAAG,MAAM,CAEpC;IAED,MAAM,CAAC,gBAAgB,SAAU,cAAc,UAAU,MAAM,KAAG,MAAM,EAAE,CAGzE;CACF;AAED,eAAe,GAAG,CAAA"}
|
|
@ -0,0 +1,497 @@
|
||||||
|
import type React from 'react';
|
||||||
|
import { TLBezierCurveSegment, TLBounds, TLBoundsCorner, TLBoundsEdge } from '../types';
|
||||||
|
import './polyfills';
|
||||||
|
import type { TLBoundsWithCenter } from '+index';
|
||||||
|
export declare class Utils {
|
||||||
|
static filterObject<T extends object>(obj: T, fn: (entry: Entry<T>, i?: number, arr?: Entry<T>[]) => boolean): Partial<T>;
|
||||||
|
static deepMerge: <T>(target: T, patch: any) => T;
|
||||||
|
/**
|
||||||
|
* Linear interpolation betwen two numbers.
|
||||||
|
* @param y1
|
||||||
|
* @param y2
|
||||||
|
* @param mu
|
||||||
|
*/
|
||||||
|
static lerp(y1: number, y2: number, mu: number): number;
|
||||||
|
/**
|
||||||
|
* Linear interpolation between two colors.
|
||||||
|
*
|
||||||
|
* ### Example
|
||||||
|
*
|
||||||
|
*```ts
|
||||||
|
* lerpColor("#000000", "#0099FF", .25)
|
||||||
|
*```
|
||||||
|
*/
|
||||||
|
static lerpColor(color1: string, color2: string, factor?: number): string;
|
||||||
|
/**
|
||||||
|
* Modulate a value between two ranges.
|
||||||
|
* @param value
|
||||||
|
* @param rangeA from [low, high]
|
||||||
|
* @param rangeB to [low, high]
|
||||||
|
* @param clamp
|
||||||
|
*/
|
||||||
|
static modulate(value: number, rangeA: number[], rangeB: number[], clamp?: boolean): number;
|
||||||
|
/**
|
||||||
|
* Clamp a value into a range.
|
||||||
|
* @param n
|
||||||
|
* @param min
|
||||||
|
*/
|
||||||
|
static clamp(n: number, min: number): number;
|
||||||
|
static clamp(n: number, min: number, max: number): number;
|
||||||
|
static compress(s: string): string;
|
||||||
|
static decompress(s: string): string;
|
||||||
|
/**
|
||||||
|
* Recursively clone an object or array.
|
||||||
|
* @param obj
|
||||||
|
*/
|
||||||
|
static deepClone<T extends unknown>(obj: T): T;
|
||||||
|
/**
|
||||||
|
* Seeded random number generator, using [xorshift](https://en.wikipedia.org/wiki/Xorshift).
|
||||||
|
* The result will always be betweeen -1 and 1.
|
||||||
|
*
|
||||||
|
* Adapted from [seedrandom](https://github.com/davidbau/seedrandom).
|
||||||
|
*/
|
||||||
|
static rng(seed?: string): () => number;
|
||||||
|
static getRectangleSides(point: number[], size: number[], rotation?: number): [string, number[][]][];
|
||||||
|
static getBoundsSides(bounds: TLBounds): [string, number[][]][];
|
||||||
|
static shallowEqual<T extends Record<string, unknown>>(objA: T, objB: T): boolean;
|
||||||
|
/**
|
||||||
|
* Get the outer of between a circle and a point.
|
||||||
|
* @param C The circle's center.
|
||||||
|
* @param r The circle's radius.
|
||||||
|
* @param P The point.
|
||||||
|
* @param side
|
||||||
|
*/
|
||||||
|
static getCircleTangentToPoint(C: number[], r: number, P: number[], side: number): number[] | null;
|
||||||
|
/**
|
||||||
|
* Get outer tangents of two circles.
|
||||||
|
* @param x0
|
||||||
|
* @param y0
|
||||||
|
* @param r0
|
||||||
|
* @param x1
|
||||||
|
* @param y1
|
||||||
|
* @param r1
|
||||||
|
* @returns [lx0, ly0, lx1, ly1, rx0, ry0, rx1, ry1]
|
||||||
|
*/
|
||||||
|
static getOuterTangentsOfCircles(C0: number[], r0: number, C1: number[], r1: number): number[][] | null;
|
||||||
|
/**
|
||||||
|
* Get the closest point on the perimeter of a circle to a given point.
|
||||||
|
* @param C The circle's center.
|
||||||
|
* @param r The circle's radius.
|
||||||
|
* @param P The point.
|
||||||
|
*/
|
||||||
|
static getClosestPointOnCircle(C: number[], r: number, P: number[]): number[];
|
||||||
|
/**
|
||||||
|
* Get a circle from three points.
|
||||||
|
* @param A
|
||||||
|
* @param B
|
||||||
|
* @param C
|
||||||
|
* @returns [x, y, r]
|
||||||
|
*/
|
||||||
|
static circleFromThreePoints(A: number[], B: number[], C: number[]): number[];
|
||||||
|
/**
|
||||||
|
* Find the approximate perimeter of an ellipse.
|
||||||
|
* @param rx
|
||||||
|
* @param ry
|
||||||
|
*/
|
||||||
|
static perimeterOfEllipse(rx: number, ry: number): number;
|
||||||
|
/**
|
||||||
|
* Get the short angle distance between two angles.
|
||||||
|
* @param a0
|
||||||
|
* @param a1
|
||||||
|
*/
|
||||||
|
static shortAngleDist(a0: number, a1: number): number;
|
||||||
|
/**
|
||||||
|
* Get the long angle distance between two angles.
|
||||||
|
* @param a0
|
||||||
|
* @param a1
|
||||||
|
*/
|
||||||
|
static longAngleDist(a0: number, a1: number): number;
|
||||||
|
/**
|
||||||
|
* Interpolate an angle between two angles.
|
||||||
|
* @param a0
|
||||||
|
* @param a1
|
||||||
|
* @param t
|
||||||
|
*/
|
||||||
|
static lerpAngles(a0: number, a1: number, t: number): number;
|
||||||
|
/**
|
||||||
|
* Get the short distance between two angles.
|
||||||
|
* @param a0
|
||||||
|
* @param a1
|
||||||
|
*/
|
||||||
|
static angleDelta(a0: number, a1: number): number;
|
||||||
|
/**
|
||||||
|
* Get the "sweep" or short distance between two points on a circle's perimeter.
|
||||||
|
* @param C
|
||||||
|
* @param A
|
||||||
|
* @param B
|
||||||
|
*/
|
||||||
|
static getSweep(C: number[], A: number[], B: number[]): number;
|
||||||
|
/**
|
||||||
|
* Rotate a point around a center.
|
||||||
|
* @param x The x-axis coordinate of the point.
|
||||||
|
* @param y The y-axis coordinate of the point.
|
||||||
|
* @param cx The x-axis coordinate of the point to rotate round.
|
||||||
|
* @param cy The y-axis coordinate of the point to rotate round.
|
||||||
|
* @param angle The distance (in radians) to rotate.
|
||||||
|
*/
|
||||||
|
static rotatePoint(A: number[], B: number[], angle: number): number[];
|
||||||
|
/**
|
||||||
|
* Clamp radians within 0 and 2PI
|
||||||
|
* @param r
|
||||||
|
*/
|
||||||
|
static clampRadians(r: number): number;
|
||||||
|
/**
|
||||||
|
* Clamp rotation to even segments.
|
||||||
|
* @param r
|
||||||
|
* @param segments
|
||||||
|
*/
|
||||||
|
static snapAngleToSegments(r: number, segments: number): number;
|
||||||
|
/**
|
||||||
|
* Is angle c between angles a and b?
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
* @param c
|
||||||
|
*/
|
||||||
|
static isAngleBetween(a: number, b: number, c: number): boolean;
|
||||||
|
/**
|
||||||
|
* Convert degrees to radians.
|
||||||
|
* @param d
|
||||||
|
*/
|
||||||
|
static degreesToRadians(d: number): number;
|
||||||
|
/**
|
||||||
|
* Convert radians to degrees.
|
||||||
|
* @param r
|
||||||
|
*/
|
||||||
|
static radiansToDegrees(r: number): number;
|
||||||
|
/**
|
||||||
|
* Get the length of an arc between two points on a circle's perimeter.
|
||||||
|
* @param C
|
||||||
|
* @param r
|
||||||
|
* @param A
|
||||||
|
* @param B
|
||||||
|
*/
|
||||||
|
static getArcLength(C: number[], r: number, A: number[], B: number[]): number;
|
||||||
|
/**
|
||||||
|
* Get a dash offset for an arc, based on its length.
|
||||||
|
* @param C
|
||||||
|
* @param r
|
||||||
|
* @param A
|
||||||
|
* @param B
|
||||||
|
* @param step
|
||||||
|
*/
|
||||||
|
static getArcDashOffset(C: number[], r: number, A: number[], B: number[], step: number): number;
|
||||||
|
/**
|
||||||
|
* Get a dash offset for an ellipse, based on its length.
|
||||||
|
* @param A
|
||||||
|
* @param step
|
||||||
|
*/
|
||||||
|
static getEllipseDashOffset(A: number[], step: number): number;
|
||||||
|
/**
|
||||||
|
* Get bezier curve segments that pass through an array of points.
|
||||||
|
* @param points
|
||||||
|
* @param tension
|
||||||
|
*/
|
||||||
|
static getTLBezierCurveSegments(points: number[][], tension?: number): TLBezierCurveSegment[];
|
||||||
|
/**
|
||||||
|
* Find a point along a curve segment, via pomax.
|
||||||
|
* @param t
|
||||||
|
* @param points [cpx1, cpy1, cpx2, cpy2, px, py][]
|
||||||
|
*/
|
||||||
|
static computePointOnCurve(t: number, points: number[][]): number[];
|
||||||
|
/**
|
||||||
|
* Evaluate a 2d cubic bezier at a point t on the x axis.
|
||||||
|
* @param tx
|
||||||
|
* @param x1
|
||||||
|
* @param y1
|
||||||
|
* @param x2
|
||||||
|
* @param y2
|
||||||
|
*/
|
||||||
|
static cubicBezier(tx: number, x1: number, y1: number, x2: number, y2: number): number;
|
||||||
|
/**
|
||||||
|
* Get a bezier curve data for a spline that fits an array of points.
|
||||||
|
* @param points An array of points formatted as [x, y]
|
||||||
|
* @param k Tension
|
||||||
|
*/
|
||||||
|
static getSpline(pts: number[][], k?: number): {
|
||||||
|
cp1x: number;
|
||||||
|
cp1y: number;
|
||||||
|
cp2x: number;
|
||||||
|
cp2y: number;
|
||||||
|
px: number;
|
||||||
|
py: number;
|
||||||
|
}[];
|
||||||
|
/**
|
||||||
|
* Get a bezier curve data for a spline that fits an array of points.
|
||||||
|
* @param pts
|
||||||
|
* @param tension
|
||||||
|
* @param isClosed
|
||||||
|
* @param numOfSegments
|
||||||
|
*/
|
||||||
|
static getCurvePoints(pts: number[][], tension?: number, isClosed?: boolean, numOfSegments?: number): number[][];
|
||||||
|
/**
|
||||||
|
* Simplify a line (using Ramer-Douglas-Peucker algorithm).
|
||||||
|
* @param points An array of points as [x, y, ...][]
|
||||||
|
* @param tolerance The minimum line distance (also called epsilon).
|
||||||
|
* @returns Simplified array as [x, y, ...][]
|
||||||
|
*/
|
||||||
|
static simplify(points: number[][], tolerance?: number): number[][];
|
||||||
|
/**
|
||||||
|
* Get whether a point is inside of a circle.
|
||||||
|
* @param A
|
||||||
|
* @param b
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static pointInCircle(A: number[], C: number[], r: number): boolean;
|
||||||
|
/**
|
||||||
|
* Get whether a point is inside of an ellipse.
|
||||||
|
* @param point
|
||||||
|
* @param center
|
||||||
|
* @param rx
|
||||||
|
* @param ry
|
||||||
|
* @param rotation
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static pointInEllipse(A: number[], C: number[], rx: number, ry: number, rotation?: number): boolean;
|
||||||
|
/**
|
||||||
|
* Get whether a point is inside of a rectangle.
|
||||||
|
* @param point
|
||||||
|
* @param size
|
||||||
|
*/
|
||||||
|
static pointInRect(point: number[], size: number[]): boolean;
|
||||||
|
static pointInPolygon(p: number[], points: number[][]): boolean;
|
||||||
|
/**
|
||||||
|
* Expand a bounding box by a delta.
|
||||||
|
*
|
||||||
|
* ### Example
|
||||||
|
*
|
||||||
|
*```ts
|
||||||
|
* expandBounds(myBounds, [100, 100])
|
||||||
|
*```
|
||||||
|
*/
|
||||||
|
static expandBounds(bounds: TLBounds, delta: number): TLBounds;
|
||||||
|
/**
|
||||||
|
* Get whether a point is inside of a bounds.
|
||||||
|
* @param A
|
||||||
|
* @param b
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static pointInBounds(A: number[], b: TLBounds): boolean;
|
||||||
|
/**
|
||||||
|
* Get whether two bounds collide.
|
||||||
|
* @param a Bounds
|
||||||
|
* @param b Bounds
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static boundsCollide(a: TLBounds, b: TLBounds): boolean;
|
||||||
|
/**
|
||||||
|
* Get whether the bounds of A contain the bounds of B. A perfect match will return true.
|
||||||
|
* @param a Bounds
|
||||||
|
* @param b Bounds
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static boundsContain(a: TLBounds, b: TLBounds): boolean;
|
||||||
|
/**
|
||||||
|
* Get whether the bounds of A are contained by the bounds of B.
|
||||||
|
* @param a Bounds
|
||||||
|
* @param b Bounds
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static boundsContained(a: TLBounds, b: TLBounds): boolean;
|
||||||
|
/**
|
||||||
|
* Get whether two bounds are identical.
|
||||||
|
* @param a Bounds
|
||||||
|
* @param b Bounds
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static boundsAreEqual(a: TLBounds, b: TLBounds): boolean;
|
||||||
|
/**
|
||||||
|
* Find a bounding box from an array of points.
|
||||||
|
* @param points
|
||||||
|
* @param rotation (optional) The bounding box's rotation.
|
||||||
|
*/
|
||||||
|
static getBoundsFromPoints(points: number[][], rotation?: number): TLBounds;
|
||||||
|
/**
|
||||||
|
* Center a bounding box around a given point.
|
||||||
|
* @param bounds
|
||||||
|
* @param center
|
||||||
|
*/
|
||||||
|
static centerBounds(bounds: TLBounds, point: number[]): TLBounds;
|
||||||
|
/**
|
||||||
|
* Move a bounding box without recalculating it.
|
||||||
|
* @param bounds
|
||||||
|
* @param delta
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static translateBounds(bounds: TLBounds, delta: number[]): TLBounds;
|
||||||
|
/**
|
||||||
|
* Rotate a bounding box.
|
||||||
|
* @param bounds
|
||||||
|
* @param center
|
||||||
|
* @param rotation
|
||||||
|
*/
|
||||||
|
static rotateBounds(bounds: TLBounds, center: number[], rotation: number): TLBounds;
|
||||||
|
/**
|
||||||
|
* Get the rotated bounds of an ellipse.
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param rx
|
||||||
|
* @param ry
|
||||||
|
* @param rotation
|
||||||
|
*/
|
||||||
|
static getRotatedEllipseBounds(x: number, y: number, rx: number, ry: number, rotation?: number): TLBounds;
|
||||||
|
/**
|
||||||
|
* Get a bounding box that includes two bounding boxes.
|
||||||
|
* @param a Bounding box
|
||||||
|
* @param b Bounding box
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static getExpandedBounds(a: TLBounds, b: TLBounds): TLBounds;
|
||||||
|
/**
|
||||||
|
* Get the common bounds of a group of bounds.
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
static getCommonBounds(bounds: TLBounds[]): TLBounds;
|
||||||
|
static getRotatedCorners(b: TLBounds, rotation?: number): number[][];
|
||||||
|
static getTransformedBoundingBox(bounds: TLBounds, handle: TLBoundsCorner | TLBoundsEdge | 'center', delta: number[], rotation?: number, isAspectRatioLocked?: boolean): TLBounds & {
|
||||||
|
scaleX: number;
|
||||||
|
scaleY: number;
|
||||||
|
};
|
||||||
|
static getTransformAnchor(type: TLBoundsEdge | TLBoundsCorner, isFlippedX: boolean, isFlippedY: boolean): TLBoundsCorner | TLBoundsEdge;
|
||||||
|
/**
|
||||||
|
* Get the relative bounds (usually a child) within a transformed bounding box.
|
||||||
|
* @param bounds
|
||||||
|
* @param initialBounds
|
||||||
|
* @param initialShapeBounds
|
||||||
|
* @param isFlippedX
|
||||||
|
* @param isFlippedY
|
||||||
|
*/
|
||||||
|
static getRelativeTransformedBoundingBox(bounds: TLBounds, initialBounds: TLBounds, initialShapeBounds: TLBounds, isFlippedX: boolean, isFlippedY: boolean): TLBounds;
|
||||||
|
/**
|
||||||
|
* Get the size of a rotated box.
|
||||||
|
* @param size : ;
|
||||||
|
* @param rotation
|
||||||
|
*/
|
||||||
|
static getRotatedSize(size: number[], rotation: number): number[];
|
||||||
|
/**
|
||||||
|
* Get the center of a bounding box.
|
||||||
|
* @param bounds
|
||||||
|
*/
|
||||||
|
static getBoundsCenter(bounds: TLBounds): number[];
|
||||||
|
/**
|
||||||
|
* Get a bounding box with a midX and midY.
|
||||||
|
* @param bounds
|
||||||
|
*/
|
||||||
|
static getBoundsWithCenter(bounds: TLBounds): TLBounds & {
|
||||||
|
midX: number;
|
||||||
|
midY: number;
|
||||||
|
};
|
||||||
|
static getSnapPoints: (bounds: any, others: TLBoundsWithCenter[], snapDistance: number) => {
|
||||||
|
offset: number[];
|
||||||
|
snapLines: number[][][];
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* ### Example
|
||||||
|
*
|
||||||
|
*```ts
|
||||||
|
* example
|
||||||
|
*```
|
||||||
|
*/
|
||||||
|
static removeDuplicatePoints(points: number[][]): number[][];
|
||||||
|
/**
|
||||||
|
// points =
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a value from a cache (a WeakMap), filling the value if it is not present.
|
||||||
|
*
|
||||||
|
* ### Example
|
||||||
|
*
|
||||||
|
*```ts
|
||||||
|
* getFromCache(boundsCache, shape, (cache) => cache.set(shape, "value"))
|
||||||
|
*```
|
||||||
|
*/
|
||||||
|
static getFromCache<V, I extends object>(cache: WeakMap<I, V>, item: I, getNext: () => V): V;
|
||||||
|
/**
|
||||||
|
* Get a unique string id.
|
||||||
|
*/
|
||||||
|
static uniqueId(a?: string): string;
|
||||||
|
/**
|
||||||
|
* Shuffle the contents of an array.
|
||||||
|
* @param arr
|
||||||
|
* @param offset
|
||||||
|
*/
|
||||||
|
static rotateArray<T>(arr: T[], offset: number): T[];
|
||||||
|
/**
|
||||||
|
* Deep compare two arrays.
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
*/
|
||||||
|
static deepCompareArrays<T>(a: T[], b: T[]): boolean;
|
||||||
|
/**
|
||||||
|
* Deep compare any values.
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
*/
|
||||||
|
static deepCompare<T>(a: T, b: T): boolean;
|
||||||
|
/**
|
||||||
|
* Find whether two arrays intersect.
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
* @param fn An optional function to apply to the items of a; will check if b includes the result.
|
||||||
|
*/
|
||||||
|
static arrsIntersect<T, K>(a: T[], b: K[], fn?: (item: K) => T): boolean;
|
||||||
|
static arrsIntersect<T>(a: T[], b: T[]): boolean;
|
||||||
|
/**
|
||||||
|
* Get the unique values from an array of strings or numbers.
|
||||||
|
* @param items
|
||||||
|
*/
|
||||||
|
static uniqueArray<T extends string | number>(...items: T[]): T[];
|
||||||
|
/**
|
||||||
|
* Convert a set to an array.
|
||||||
|
* @param set
|
||||||
|
*/
|
||||||
|
static setToArray<T>(set: Set<T>): T[];
|
||||||
|
/**
|
||||||
|
* Debounce a function.
|
||||||
|
*/
|
||||||
|
static debounce<T extends (...args: any[]) => void>(fn: T, ms?: number): (...args: Parameters<T>) => void;
|
||||||
|
static TRIM_NUMBERS: RegExp;
|
||||||
|
/**
|
||||||
|
* Turn an array of points into a path of quadradic curves.
|
||||||
|
* @param stroke ;
|
||||||
|
*/
|
||||||
|
static getSvgPathFromStroke(points: number[][], closed?: boolean): string;
|
||||||
|
/**
|
||||||
|
* Get balanced dash-strokearray and dash-strokeoffset properties for a path of a given length.
|
||||||
|
* @param length The length of the path.
|
||||||
|
* @param strokeWidth The shape's stroke-width property.
|
||||||
|
* @param style The stroke's style: "dashed" or "dotted" (default "dashed").
|
||||||
|
* @param snap An interval for dashes (e.g. 4 will produce arrays with 4, 8, 16, etc dashes).
|
||||||
|
*/
|
||||||
|
static getPerfectDashProps(length: number, strokeWidth: number, style: 'dashed' | 'dotted' | string, snap?: number, outset?: boolean): {
|
||||||
|
strokeDasharray: string;
|
||||||
|
strokeDashoffset: string;
|
||||||
|
};
|
||||||
|
static isMobileSize(): boolean;
|
||||||
|
static isMobileSafari(): boolean;
|
||||||
|
static throttle<T extends (...args: any) => any>(func: T, limit: number): (...args: Parameters<T>) => ReturnType<T>;
|
||||||
|
/**
|
||||||
|
* Find whether the current display is a touch display.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Find whether the current device is a Mac / iOS / iPadOS.
|
||||||
|
*/
|
||||||
|
static isDarwin(): boolean;
|
||||||
|
/**
|
||||||
|
* Get whether an event is command (mac) or control (pc).
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
static metaKey(e: KeyboardEvent | React.KeyboardEvent): boolean;
|
||||||
|
}
|
||||||
|
export default Utils;
|
||||||
|
declare type Entry<T> = {
|
||||||
|
[K in keyof T]: [K, T[K]];
|
||||||
|
}[keyof T];
|
||||||
|
//# sourceMappingURL=utils.d.ts.map
|
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import Utils from '~../../core/src/utils'
|
import { Utils } from '@tldraw/core'
|
||||||
import { TLDrawState } from '~state'
|
import { TLDrawState } from '~state'
|
||||||
import { TLDR } from '~state/tldr'
|
import { TLDR } from '~state/tldr'
|
||||||
import { mockDocument } from '~test'
|
import { mockDocument } from '~test'
|
||||||
|
|
|
@ -9,10 +9,10 @@ import {
|
||||||
SessionType,
|
SessionType,
|
||||||
} from '~types'
|
} from '~types'
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
import { Utils } from '@tldraw/core'
|
import { Utils, TLBounds } from '@tldraw/core'
|
||||||
import { TLDR } from '~state/tldr'
|
import { TLDR } from '~state/tldr'
|
||||||
|
|
||||||
export class ArrowSession implements Session {
|
export class ArrowSession extends Session {
|
||||||
static type = SessionType.Arrow
|
static type = SessionType.Arrow
|
||||||
status = TLDrawStatus.TranslatingHandle
|
status = TLDrawStatus.TranslatingHandle
|
||||||
newStartBindingId = Utils.uniqueId()
|
newStartBindingId = Utils.uniqueId()
|
||||||
|
@ -29,7 +29,15 @@ export class ArrowSession implements Session {
|
||||||
startBindingShapeId?: string
|
startBindingShapeId?: string
|
||||||
isCreate: boolean
|
isCreate: boolean
|
||||||
|
|
||||||
constructor(data: Data, point: number[], handleId: 'start' | 'end', isCreate = false) {
|
constructor(
|
||||||
|
data: Data,
|
||||||
|
viewport: TLBounds,
|
||||||
|
point: number[],
|
||||||
|
handleId: 'start' | 'end',
|
||||||
|
isCreate = false
|
||||||
|
) {
|
||||||
|
super(viewport)
|
||||||
|
|
||||||
this.isCreate = isCreate
|
this.isCreate = isCreate
|
||||||
|
|
||||||
const { currentPageId } = data.appState
|
const { currentPageId } = data.appState
|
||||||
|
@ -336,7 +344,7 @@ export class ArrowSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
complete(data: Data) {
|
complete = (data: Data) => {
|
||||||
const { initialShape, initialBinding, newStartBindingId, startBindingShapeId, handleId } = this
|
const { initialShape, initialBinding, newStartBindingId, startBindingShapeId, handleId } = this
|
||||||
|
|
||||||
const page = TLDR.getPage(data, data.appState.currentPageId)
|
const page = TLDR.getPage(data, data.appState.currentPageId)
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
import { Utils } from '@tldraw/core'
|
import { Utils, TLBounds } from '@tldraw/core'
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
import { Data, Session, SessionType, TLDrawPatch, TLDrawStatus } from '~types'
|
import { Data, Session, SessionType, TLDrawPatch, TLDrawStatus } from '~types'
|
||||||
import { TLDR } from '~state/tldr'
|
import { TLDR } from '~state/tldr'
|
||||||
|
|
||||||
export class BrushSession implements Session {
|
export class BrushSession extends Session {
|
||||||
static type = SessionType.Brush
|
static type = SessionType.Brush
|
||||||
status = TLDrawStatus.Brushing
|
status = TLDrawStatus.Brushing
|
||||||
origin: number[]
|
origin: number[]
|
||||||
snapshot: BrushSnapshot
|
snapshot: BrushSnapshot
|
||||||
|
|
||||||
constructor(data: Data, point: number[]) {
|
constructor(data: Data, viewport: TLBounds, point: number[]) {
|
||||||
|
super(viewport)
|
||||||
this.origin = Vec.round(point)
|
this.origin = Vec.round(point)
|
||||||
this.snapshot = getBrushSnapshot(data)
|
this.snapshot = getBrushSnapshot(data)
|
||||||
}
|
}
|
||||||
|
@ -78,7 +79,7 @@ export class BrushSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel(data: Data) {
|
cancel = (data: Data) => {
|
||||||
const { currentPageId } = data.appState
|
const { currentPageId } = data.appState
|
||||||
return {
|
return {
|
||||||
document: {
|
document: {
|
||||||
|
@ -92,7 +93,7 @@ export class BrushSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
complete(data: Data) {
|
complete = (data: Data) => {
|
||||||
const { currentPageId } = data.appState
|
const { currentPageId } = data.appState
|
||||||
const pageState = TLDR.getPageState(data, currentPageId)
|
const pageState = TLDR.getPageState(data, currentPageId)
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Utils } from '@tldraw/core'
|
import { Utils, TLBounds } from '@tldraw/core'
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
import { Data, Session, SessionType, TLDrawStatus } from '~types'
|
import { Data, Session, SessionType, TLDrawStatus } from '~types'
|
||||||
import { TLDR } from '~state/tldr'
|
import { TLDR } from '~state/tldr'
|
||||||
|
|
||||||
export class DrawSession implements Session {
|
export class DrawSession extends Session {
|
||||||
static type = SessionType.Draw
|
static type = SessionType.Draw
|
||||||
status = TLDrawStatus.Creating
|
status = TLDrawStatus.Creating
|
||||||
topLeft: number[]
|
topLeft: number[]
|
||||||
|
@ -16,7 +16,8 @@ export class DrawSession implements Session {
|
||||||
isLocked?: boolean
|
isLocked?: boolean
|
||||||
lockedDirection?: 'horizontal' | 'vertical'
|
lockedDirection?: 'horizontal' | 'vertical'
|
||||||
|
|
||||||
constructor(data: Data, point: number[], id: string) {
|
constructor(data: Data, viewport: TLBounds, point: number[], id: string) {
|
||||||
|
super(viewport)
|
||||||
this.origin = point
|
this.origin = point
|
||||||
this.previous = point
|
this.previous = point
|
||||||
this.last = point
|
this.last = point
|
||||||
|
|
|
@ -16,7 +16,7 @@ import {
|
||||||
import { TLDR } from '~state/tldr'
|
import { TLDR } from '~state/tldr'
|
||||||
import type { Patch } from 'rko'
|
import type { Patch } from 'rko'
|
||||||
|
|
||||||
export class GridSession implements Session {
|
export class GridSession extends Session {
|
||||||
type = SessionType.Grid
|
type = SessionType.Grid
|
||||||
status = TLDrawStatus.Translating
|
status = TLDrawStatus.Translating
|
||||||
origin: number[]
|
origin: number[]
|
||||||
|
@ -29,7 +29,8 @@ export class GridSession implements Session {
|
||||||
rows = 1
|
rows = 1
|
||||||
isCopying = false
|
isCopying = false
|
||||||
|
|
||||||
constructor(data: Data, id: string, pageId: string, point: number[]) {
|
constructor(data: Data, viewport: TLBounds, id: string, pageId: string, point: number[]) {
|
||||||
|
super(viewport)
|
||||||
this.origin = point
|
this.origin = point
|
||||||
this.shape = TLDR.getShape(data, id, pageId)
|
this.shape = TLDR.getShape(data, id, pageId)
|
||||||
this.grid['0_0'] = this.shape.id
|
this.grid['0_0'] = this.shape.id
|
||||||
|
@ -189,7 +190,7 @@ export class GridSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
complete(data: Data) {
|
complete = (data: Data) => {
|
||||||
const pageId = data.appState.currentPageId
|
const pageId = data.appState.currentPageId
|
||||||
|
|
||||||
const beforeShapes: Patch<Record<string, TLDrawShape>> = {}
|
const beforeShapes: Patch<Record<string, TLDrawShape>> = {}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
|
import type { TLBounds } from '@tldraw/core'
|
||||||
import { SessionType, ShapesWithProp, TLDrawStatus } from '~types'
|
import { SessionType, ShapesWithProp, TLDrawStatus } from '~types'
|
||||||
import type { Session } from '~types'
|
import { Session } from '~types'
|
||||||
import type { Data } from '~types'
|
import type { Data } from '~types'
|
||||||
import { TLDR } from '~state/tldr'
|
import { TLDR } from '~state/tldr'
|
||||||
|
|
||||||
export class HandleSession implements Session {
|
export class HandleSession extends Session {
|
||||||
static type = SessionType.Handle
|
static type = SessionType.Handle
|
||||||
status = TLDrawStatus.TranslatingHandle
|
status = TLDrawStatus.TranslatingHandle
|
||||||
commandId: string
|
commandId: string
|
||||||
|
@ -15,7 +16,14 @@ export class HandleSession implements Session {
|
||||||
initialShape: ShapesWithProp<'handles'>
|
initialShape: ShapesWithProp<'handles'>
|
||||||
handleId: string
|
handleId: string
|
||||||
|
|
||||||
constructor(data: Data, point: number[], handleId: string, commandId = 'move_handle') {
|
constructor(
|
||||||
|
data: Data,
|
||||||
|
viewport: TLBounds,
|
||||||
|
point: number[],
|
||||||
|
handleId: string,
|
||||||
|
commandId = 'move_handle'
|
||||||
|
) {
|
||||||
|
super(viewport)
|
||||||
const { currentPageId } = data.appState
|
const { currentPageId } = data.appState
|
||||||
const shapeId = TLDR.getSelectedIds(data, currentPageId)[0]
|
const shapeId = TLDR.getSelectedIds(data, currentPageId)[0]
|
||||||
this.topLeft = point
|
this.topLeft = point
|
||||||
|
@ -86,7 +94,7 @@ export class HandleSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
complete(data: Data) {
|
complete = (data: Data) => {
|
||||||
const { initialShape } = this
|
const { initialShape } = this
|
||||||
const pageId = data.appState.currentPageId
|
const pageId = data.appState.currentPageId
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Utils } from '@tldraw/core'
|
import { Utils, TLBounds } from '@tldraw/core'
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
import { Session, SessionType, TLDrawShape, TLDrawStatus } from '~types'
|
import { Session, SessionType, TLDrawShape, TLDrawStatus } from '~types'
|
||||||
import type { Data } from '~types'
|
import type { Data } from '~types'
|
||||||
|
@ -6,7 +6,7 @@ import { TLDR } from '~state/tldr'
|
||||||
|
|
||||||
const centerCache = new WeakMap<string[], number[]>()
|
const centerCache = new WeakMap<string[], number[]>()
|
||||||
|
|
||||||
export class RotateSession implements Session {
|
export class RotateSession extends Session {
|
||||||
static type = SessionType.Rotate
|
static type = SessionType.Rotate
|
||||||
status = TLDrawStatus.Transforming
|
status = TLDrawStatus.Transforming
|
||||||
delta = [0, 0]
|
delta = [0, 0]
|
||||||
|
@ -15,7 +15,8 @@ export class RotateSession implements Session {
|
||||||
initialAngle: number
|
initialAngle: number
|
||||||
changes: Record<string, Partial<TLDrawShape>> = {}
|
changes: Record<string, Partial<TLDrawShape>> = {}
|
||||||
|
|
||||||
constructor(data: Data, point: number[]) {
|
constructor(data: Data, viewport: TLBounds, point: number[]) {
|
||||||
|
super(viewport)
|
||||||
this.origin = point
|
this.origin = point
|
||||||
this.snapshot = getRotateSnapshot(data)
|
this.snapshot = getRotateSnapshot(data)
|
||||||
this.initialAngle = Vec.angle(this.snapshot.commonBoundsCenter, this.origin)
|
this.initialAngle = Vec.angle(this.snapshot.commonBoundsCenter, this.origin)
|
||||||
|
@ -97,7 +98,7 @@ export class RotateSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
complete(data: Data) {
|
complete = (data: Data) => {
|
||||||
const { initialShapes } = this.snapshot
|
const { initialShapes } = this.snapshot
|
||||||
const pageId = data.appState.currentPageId
|
const pageId = data.appState.currentPageId
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
import { TLBoundsCorner, TLSnapLine, TLBoundsEdge, Utils, TLBoundsWithCenter } from '@tldraw/core'
|
import {
|
||||||
|
TLBounds,
|
||||||
|
TLBoundsCorner,
|
||||||
|
TLSnapLine,
|
||||||
|
TLBoundsEdge,
|
||||||
|
Utils,
|
||||||
|
TLBoundsWithCenter,
|
||||||
|
} from '@tldraw/core'
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
import { SessionType, TLDrawShape, TLDrawStatus } from '~types'
|
import { SessionType, TLDrawShape, TLDrawStatus } from '~types'
|
||||||
import type { Session } from '~types'
|
import { Session } from '~types'
|
||||||
import type { Data } from '~types'
|
import type { Data } from '~types'
|
||||||
import { TLDR } from '~state/tldr'
|
import { TLDR } from '~state/tldr'
|
||||||
import { SLOW_SPEED, SNAP_DISTANCE, VERY_SLOW_SPEED } from '~state/constants'
|
import { SLOW_SPEED, SNAP_DISTANCE } from '~state/constants'
|
||||||
|
|
||||||
type SnapInfo =
|
type SnapInfo =
|
||||||
| {
|
| {
|
||||||
|
@ -15,7 +22,7 @@ type SnapInfo =
|
||||||
bounds: TLBoundsWithCenter[]
|
bounds: TLBoundsWithCenter[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TransformSingleSession implements Session {
|
export class TransformSingleSession extends Session {
|
||||||
type = SessionType.TransformSingle
|
type = SessionType.TransformSingle
|
||||||
status = TLDrawStatus.Transforming
|
status = TLDrawStatus.Transforming
|
||||||
transformType: TLBoundsEdge | TLBoundsCorner
|
transformType: TLBoundsEdge | TLBoundsCorner
|
||||||
|
@ -30,10 +37,12 @@ export class TransformSingleSession implements Session {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
data: Data,
|
data: Data,
|
||||||
|
viewport: TLBounds,
|
||||||
point: number[],
|
point: number[],
|
||||||
transformType: TLBoundsEdge | TLBoundsCorner = TLBoundsCorner.BottomRight,
|
transformType: TLBoundsEdge | TLBoundsCorner = TLBoundsCorner.BottomRight,
|
||||||
isCreate = false
|
isCreate = false
|
||||||
) {
|
) {
|
||||||
|
super(viewport)
|
||||||
this.origin = point
|
this.origin = point
|
||||||
this.transformType = transformType
|
this.transformType = transformType
|
||||||
this.snapshot = getTransformSingleSnapshot(data, transformType)
|
this.snapshot = getTransformSingleSnapshot(data, transformType)
|
||||||
|
@ -88,7 +97,10 @@ export class TransformSingleSession implements Session {
|
||||||
) {
|
) {
|
||||||
const snapResult = Utils.getSnapPoints(
|
const snapResult = Utils.getSnapPoints(
|
||||||
Utils.getBoundsWithCenter(newBounds),
|
Utils.getBoundsWithCenter(newBounds),
|
||||||
this.snapInfo.bounds,
|
this.snapInfo.bounds.filter(
|
||||||
|
(bounds) =>
|
||||||
|
Utils.boundsContain(this.viewport, bounds) || Utils.boundsCollide(this.viewport, bounds)
|
||||||
|
),
|
||||||
SNAP_DISTANCE / zoom
|
SNAP_DISTANCE / zoom
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -161,7 +173,7 @@ export class TransformSingleSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
complete(data: Data) {
|
complete = (data: Data) => {
|
||||||
if (!this.snapshot.hasUnlockedShape) return data
|
if (!this.snapshot.hasUnlockedShape) return data
|
||||||
|
|
||||||
const { initialShape } = this.snapshot
|
const { initialShape } = this.snapshot
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { TLBoundsCorner, TLBoundsEdge, Utils } from '@tldraw/core'
|
import { TLBounds, TLBoundsCorner, TLBoundsEdge, Utils } from '@tldraw/core'
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
import type { TLSnapLine, TLBoundsWithCenter } from '@tldraw/core'
|
import type { TLSnapLine, TLBoundsWithCenter } from '@tldraw/core'
|
||||||
import { Session, SessionType, TLDrawShape, TLDrawStatus } from '~types'
|
import { Session, SessionType, TLDrawShape, TLDrawStatus } from '~types'
|
||||||
import type { Data } from '~types'
|
import type { Data } from '~types'
|
||||||
import { TLDR } from '~state/tldr'
|
import { TLDR } from '~state/tldr'
|
||||||
import type { Command } from 'rko'
|
import type { Command } from 'rko'
|
||||||
import { SLOW_SPEED, SNAP_DISTANCE, VERY_SLOW_SPEED } from '~state/constants'
|
import { SLOW_SPEED, SNAP_DISTANCE } from '~state/constants'
|
||||||
|
|
||||||
type SnapInfo =
|
type SnapInfo =
|
||||||
| {
|
| {
|
||||||
|
@ -16,7 +16,7 @@ type SnapInfo =
|
||||||
bounds: TLBoundsWithCenter[]
|
bounds: TLBoundsWithCenter[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TransformSession implements Session {
|
export class TransformSession extends Session {
|
||||||
static type = SessionType.Transform
|
static type = SessionType.Transform
|
||||||
status = TLDrawStatus.Transforming
|
status = TLDrawStatus.Transforming
|
||||||
scaleX = 1
|
scaleX = 1
|
||||||
|
@ -32,10 +32,12 @@ export class TransformSession implements Session {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
data: Data,
|
data: Data,
|
||||||
|
viewport: TLBounds,
|
||||||
point: number[],
|
point: number[],
|
||||||
transformType: TLBoundsEdge | TLBoundsCorner = TLBoundsCorner.BottomRight,
|
transformType: TLBoundsEdge | TLBoundsCorner = TLBoundsCorner.BottomRight,
|
||||||
isCreate = false
|
isCreate = false
|
||||||
) {
|
) {
|
||||||
|
super(viewport)
|
||||||
this.origin = point
|
this.origin = point
|
||||||
this.transformType = transformType
|
this.transformType = transformType
|
||||||
this.snapshot = getTransformSnapshot(data, transformType)
|
this.snapshot = getTransformSnapshot(data, transformType)
|
||||||
|
@ -92,7 +94,10 @@ export class TransformSession implements Session {
|
||||||
) {
|
) {
|
||||||
const snapResult = Utils.getSnapPoints(
|
const snapResult = Utils.getSnapPoints(
|
||||||
Utils.getBoundsWithCenter(newBounds),
|
Utils.getBoundsWithCenter(newBounds),
|
||||||
this.snapInfo.bounds,
|
this.snapInfo.bounds.filter(
|
||||||
|
(bounds) =>
|
||||||
|
Utils.boundsContain(this.viewport, bounds) || Utils.boundsCollide(this.viewport, bounds)
|
||||||
|
),
|
||||||
SNAP_DISTANCE / zoom
|
SNAP_DISTANCE / zoom
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -180,7 +185,7 @@ export class TransformSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
complete(data: Data): Data | Command<Data> | undefined {
|
complete = (data: Data): Data | Command<Data> | undefined => {
|
||||||
const { hasUnlockedShapes, shapeBounds } = this.snapshot
|
const { hasUnlockedShapes, shapeBounds } = this.snapshot
|
||||||
undefined
|
undefined
|
||||||
if (!hasUnlockedShapes) return
|
if (!hasUnlockedShapes) return
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
/* eslint-disable @typescript-eslint/no-non-null-assertion */
|
||||||
import { TLPageState, Utils, TLBoundsWithCenter, TLSnapLine } from '@tldraw/core'
|
import { TLPageState, Utils, TLBoundsWithCenter, TLSnapLine, TLBounds } from '@tldraw/core'
|
||||||
import { Vec } from '@tldraw/vec'
|
import { Vec } from '@tldraw/vec'
|
||||||
import {
|
import {
|
||||||
TLDrawShape,
|
TLDrawShape,
|
||||||
|
@ -12,9 +12,8 @@ import {
|
||||||
GroupShape,
|
GroupShape,
|
||||||
SessionType,
|
SessionType,
|
||||||
ArrowBinding,
|
ArrowBinding,
|
||||||
TLDrawShapeType,
|
|
||||||
} from '~types'
|
} from '~types'
|
||||||
import { SLOW_SPEED, SNAP_DISTANCE, VERY_SLOW_SPEED } from '~state/constants'
|
import { SLOW_SPEED, SNAP_DISTANCE } from '~state/constants'
|
||||||
import { TLDR } from '~state/tldr'
|
import { TLDR } from '~state/tldr'
|
||||||
import type { Patch } from 'rko'
|
import type { Patch } from 'rko'
|
||||||
|
|
||||||
|
@ -38,7 +37,7 @@ type SnapInfo =
|
||||||
bounds: TLBoundsWithCenter[]
|
bounds: TLBoundsWithCenter[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export class TranslateSession implements Session {
|
export class TranslateSession extends Session {
|
||||||
type = SessionType.Translate
|
type = SessionType.Translate
|
||||||
status = TLDrawStatus.Translating
|
status = TLDrawStatus.Translating
|
||||||
delta = [0, 0]
|
delta = [0, 0]
|
||||||
|
@ -60,10 +59,12 @@ export class TranslateSession implements Session {
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
data: Data,
|
data: Data,
|
||||||
|
viewport: TLBounds,
|
||||||
point: number[],
|
point: number[],
|
||||||
isCreate = false,
|
isCreate = false,
|
||||||
isLinked: 'left' | 'right' | 'center' | false = false
|
isLinked: 'left' | 'right' | 'center' | false = false
|
||||||
) {
|
) {
|
||||||
|
super(viewport)
|
||||||
this.origin = point
|
this.origin = point
|
||||||
this.snapshot = getTranslateSnapshot(data, isLinked)
|
this.snapshot = getTranslateSnapshot(data, isLinked)
|
||||||
this.isCreate = isCreate
|
this.isCreate = isCreate
|
||||||
|
@ -92,7 +93,14 @@ export class TranslateSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update = (data: Data, point: number[], shiftKey = false, altKey = false, metaKey = false) => {
|
update = (
|
||||||
|
data: Data,
|
||||||
|
point: number[],
|
||||||
|
shiftKey = false,
|
||||||
|
altKey = false,
|
||||||
|
metaKey = false,
|
||||||
|
viewPort = {} as TLBounds
|
||||||
|
) => {
|
||||||
const { selectedIds, initialParentChildren, initialShapes, bindingsToDelete } = this.snapshot
|
const { selectedIds, initialParentChildren, initialShapes, bindingsToDelete } = this.snapshot
|
||||||
|
|
||||||
const { currentPageId } = data.appState
|
const { currentPageId } = data.appState
|
||||||
|
@ -158,7 +166,10 @@ export class TranslateSession implements Session {
|
||||||
|
|
||||||
const snapResult = Utils.getSnapPoints(
|
const snapResult = Utils.getSnapPoints(
|
||||||
bounds,
|
bounds,
|
||||||
this.isCloning ? this.snapInfo.bounds : this.snapInfo.others,
|
(this.isCloning ? this.snapInfo.bounds : this.snapInfo.others).filter(
|
||||||
|
(bounds) =>
|
||||||
|
Utils.boundsContain(this.viewport, bounds) || Utils.boundsCollide(this.viewport, bounds)
|
||||||
|
),
|
||||||
SNAP_DISTANCE / zoom
|
SNAP_DISTANCE / zoom
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -370,7 +381,7 @@ export class TranslateSession implements Session {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
complete(data: Data): TLDrawCommand {
|
complete = (data: Data): TLDrawCommand => {
|
||||||
const pageId = data.appState.currentPageId
|
const pageId = data.appState.currentPageId
|
||||||
|
|
||||||
const { initialShapes, initialParentChildren, bindingsToDelete } = this.snapshot
|
const { initialShapes, initialParentChildren, bindingsToDelete } = this.snapshot
|
||||||
|
|
|
@ -36,6 +36,7 @@ import {
|
||||||
TLDrawUser,
|
TLDrawUser,
|
||||||
SessionType,
|
SessionType,
|
||||||
ExceptFirst,
|
ExceptFirst,
|
||||||
|
ExceptFirstTwo,
|
||||||
} from '~types'
|
} from '~types'
|
||||||
import { TLDR } from './tldr'
|
import { TLDR } from './tldr'
|
||||||
import { defaultStyle, tldrawShapeUtils } from '~shape'
|
import { defaultStyle, tldrawShapeUtils } from '~shape'
|
||||||
|
@ -361,6 +362,10 @@ export class TLDrawState extends StateManager<Data> {
|
||||||
*/
|
*/
|
||||||
updateBounds = (bounds: TLBounds) => {
|
updateBounds = (bounds: TLBounds) => {
|
||||||
this.bounds = { ...bounds }
|
this.bounds = { ...bounds }
|
||||||
|
if (this.session) {
|
||||||
|
this.session.updateViewport(this.viewport)
|
||||||
|
this.session.update(this.state, this.pointerPoint, false, false, false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1329,7 +1334,7 @@ export class TLDrawState extends StateManager<Data> {
|
||||||
* @param reason Why did the camera change?
|
* @param reason Why did the camera change?
|
||||||
*/
|
*/
|
||||||
setCamera = (point: number[], zoom: number, reason: string): this => {
|
setCamera = (point: number[], zoom: number, reason: string): this => {
|
||||||
return this.patchState(
|
this.patchState(
|
||||||
{
|
{
|
||||||
document: {
|
document: {
|
||||||
pageStates: {
|
pageStates: {
|
||||||
|
@ -1339,6 +1344,12 @@ export class TLDrawState extends StateManager<Data> {
|
||||||
},
|
},
|
||||||
reason
|
reason
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (this.session) {
|
||||||
|
this.session.updateViewport(this.viewport)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1640,7 +1651,7 @@ export class TLDrawState extends StateManager<Data> {
|
||||||
* @param session The new session
|
* @param session The new session
|
||||||
* @param args arguments of the session's start method.
|
* @param args arguments of the session's start method.
|
||||||
*/
|
*/
|
||||||
startSession = <T extends SessionType>(type: T, ...args: ExceptFirst<ArgsOfType<T>>): this => {
|
startSession = <T extends SessionType>(type: T, ...args: ExceptFirstTwo<ArgsOfType<T>>): this => {
|
||||||
if (this.session) {
|
if (this.session) {
|
||||||
throw Error(`Already in a session! (${this.session.constructor.name})`)
|
throw Error(`Already in a session! (${this.session.constructor.name})`)
|
||||||
}
|
}
|
||||||
|
@ -1648,7 +1659,7 @@ export class TLDrawState extends StateManager<Data> {
|
||||||
const Session = getSession(type)
|
const Session = getSession(type)
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
this.session = new Session(this.state, ...args)
|
this.session = new Session(this.state, this.viewport, ...args)
|
||||||
|
|
||||||
const result = this.session.start(this.state)
|
const result = this.session.start(this.state)
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import Vec from '@tldraw/vec'
|
import Vec from '@tldraw/vec'
|
||||||
import type {
|
import {
|
||||||
TLBoundsEventHandler,
|
TLBoundsEventHandler,
|
||||||
TLBoundsHandleEventHandler,
|
TLBoundsHandleEventHandler,
|
||||||
TLCanvasEventHandler,
|
TLCanvasEventHandler,
|
||||||
|
@ -9,8 +9,8 @@ import type {
|
||||||
TLShapeBlurHandler,
|
TLShapeBlurHandler,
|
||||||
TLShapeCloneHandler,
|
TLShapeCloneHandler,
|
||||||
TLWheelEventHandler,
|
TLWheelEventHandler,
|
||||||
} from '~../../core/src/types'
|
Utils,
|
||||||
import Utils from '~../../core/src/utils'
|
} from '@tldraw/core'
|
||||||
import type { TLDrawState } from '~state'
|
import type { TLDrawState } from '~state'
|
||||||
import type { TLDrawShapeType } from '~types'
|
import type { TLDrawShapeType } from '~types'
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import Vec from '@tldraw/vec'
|
import Vec from '@tldraw/vec'
|
||||||
import type { TLPointerEventHandler } from '~../../core/src/types'
|
import { Utils, TLPointerEventHandler } from '@tldraw/core'
|
||||||
import Utils from '~../../core/src/utils'
|
|
||||||
import { Draw } from '~shape/shapes'
|
import { Draw } from '~shape/shapes'
|
||||||
import { SessionType, TLDrawShapeType } from '~types'
|
import { SessionType, TLDrawShapeType } from '~types'
|
||||||
import { BaseTool, Status } from '../BaseTool'
|
import { BaseTool, Status } from '../BaseTool'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
/* eslint-disable @typescript-eslint/ban-types */
|
/* eslint-disable @typescript-eslint/ban-types */
|
||||||
import type { TLBinding, TLShapeProps, TLSnapLine, TLBoundsWithCenter } from '@tldraw/core'
|
import type { TLBinding, TLShapeProps, TLBounds, TLSnapLine } from '@tldraw/core'
|
||||||
import type { TLShape, TLShapeUtil, TLHandle } from '@tldraw/core'
|
import type { TLShape, TLShapeUtil, TLHandle } from '@tldraw/core'
|
||||||
import type { TLPage, TLUser, TLPageState } from '@tldraw/core'
|
import type { TLPage, TLUser, TLPageState } from '@tldraw/core'
|
||||||
import type { StoreApi } from 'zustand'
|
import type { StoreApi } from 'zustand'
|
||||||
|
@ -116,6 +116,16 @@ export abstract class Session {
|
||||||
) => TLDrawPatch | undefined
|
) => TLDrawPatch | undefined
|
||||||
abstract complete: (data: Readonly<Data>) => TLDrawPatch | TLDrawCommand | undefined
|
abstract complete: (data: Readonly<Data>) => TLDrawPatch | TLDrawCommand | undefined
|
||||||
abstract cancel: (data: Readonly<Data>) => TLDrawPatch | undefined
|
abstract cancel: (data: Readonly<Data>) => TLDrawPatch | undefined
|
||||||
|
|
||||||
|
viewport: TLBounds
|
||||||
|
|
||||||
|
constructor(viewport: TLBounds) {
|
||||||
|
this.viewport = viewport
|
||||||
|
}
|
||||||
|
|
||||||
|
updateViewport = (viewport: TLBounds) => {
|
||||||
|
this.viewport = viewport
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum TLDrawStatus {
|
export enum TLDrawStatus {
|
||||||
|
@ -138,6 +148,8 @@ export type ParametersExceptFirst<F> = F extends (arg0: any, ...rest: infer R) =
|
||||||
|
|
||||||
export type ExceptFirst<T extends unknown[]> = T extends [any, ...infer U] ? U : never
|
export type ExceptFirst<T extends unknown[]> = T extends [any, ...infer U] ? U : never
|
||||||
|
|
||||||
|
export type ExceptFirstTwo<T extends unknown[]> = T extends [any, any, ...infer U] ? U : never
|
||||||
|
|
||||||
export enum MoveType {
|
export enum MoveType {
|
||||||
Backward = 'backward',
|
Backward = 'backward',
|
||||||
Forward = 'forward',
|
Forward = 'forward',
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Ładowanie…
Reference in New Issue