filter snappable shapes, give viewport information to sessions

pull/190/head
Steve Ruiz 2021-10-21 19:28:33 +01:00
rodzic f8a7e3a681
commit 91b4184162
27 zmienionych plików z 929 dodań i 371 usunięć

Wyświetl plik

@ -1,357 +1,322 @@
import type React from 'react'
import { MutableRefObject } from 'react-router/node_modules/@types/react'
import type React from 'react';
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> {
id: string
name?: string
childIndex?: number
shapes: Record<string, T>
bindings: Record<string, B>
id: string;
name?: string;
childIndex?: number;
shapes: Record<string, T>;
bindings: Record<string, B>;
}
export interface TLPageState {
id: string
selectedIds: string[]
camera: {
point: number[]
zoom: number
}
brush?: TLBounds
pointedId?: string | null
hoveredId?: string | null
editingId?: string | null
bindingId?: string | null
boundsRotation?: number
currentParentId?: string | null
id: string;
selectedIds: string[];
camera: {
point: number[];
zoom: number;
};
brush?: TLBounds | null;
pointedId?: string | null;
hoveredId?: string | null;
editingId?: string | null;
bindingId?: string | null;
boundsRotation?: number;
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 {
id: string
index: number
point: number[]
canBind?: boolean
bindingId?: string
id: string;
index: number;
point: number[];
canBind?: boolean;
bindingId?: string;
}
export interface TLShape {
id: string
type: string
parentId: string
childIndex: number
name: string
point: number[]
rotation?: number
children?: string[]
handles?: Record<string, TLHandle>
isLocked?: boolean
isHidden?: boolean
isEditing?: boolean
isGenerated?: boolean
isAspectRatioLocked?: boolean
id: string;
type: string;
parentId: string;
childIndex: number;
name: string;
point: number[];
rotation?: number;
children?: string[];
handles?: Record<string, TLHandle>;
isLocked?: boolean;
isHidden?: boolean;
isEditing?: boolean;
isGenerated?: boolean;
isAspectRatioLocked?: boolean;
}
export declare type TLShapeUtils<
T extends TLShape = any,
E extends Element = any,
M = any,
K = any
> = Record<string, TLShapeUtil<T, E, M, K>>
export declare type TLShapeUtils<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> {
shape: T
isEditing: boolean
isBinding: boolean
isHovered: boolean
isSelected: boolean
isCurrentParent: boolean
meta: M extends any ? M : never
onShapeChange?: TLCallbacks<T>['onShapeChange']
onShapeBlur?: TLCallbacks<T>['onShapeBlur']
events: {
onPointerDown: (e: React.PointerEvent<E>) => void
onPointerUp: (e: React.PointerEvent<E>) => void
onPointerEnter: (e: React.PointerEvent<E>) => void
onPointerMove: (e: React.PointerEvent<E>) => void
onPointerLeave: (e: React.PointerEvent<E>) => void
}
shape: T;
isEditing: boolean;
isBinding: boolean;
isHovered: boolean;
isSelected: boolean;
isCurrentParent: boolean;
meta: M extends any ? M : never;
onShapeChange?: TLCallbacks<T>['onShapeChange'];
onShapeBlur?: TLCallbacks<T>['onShapeBlur'];
events: {
onPointerDown: (e: React.PointerEvent<E>) => void;
onPointerUp: (e: React.PointerEvent<E>) => void;
onPointerEnter: (e: React.PointerEvent<E>) => void;
onPointerMove: (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> {
ref: MutableRefObject<E>
shape: T
ref: ForwardedRef<E>;
shape: T;
}
export interface TLTool {
id: string
name: string
id: string;
name: string;
}
export interface TLBinding<M = any> {
id: string
type: string
toId: string
fromId: string
meta: M
id: string;
type: string;
toId: string;
fromId: string;
meta: M;
}
export interface TLTheme {
brushFill?: string
brushStroke?: string
selectFill?: string
selectStroke?: string
background?: string
foreground?: string
accent?: string;
brushFill?: string;
brushStroke?: string;
selectFill?: string;
selectStroke?: string;
background?: string;
foreground?: string;
}
export declare type TLWheelEventHandler = (
info: TLPointerInfo<string>,
e: React.WheelEvent<Element> | WheelEvent
) => void
export declare type TLPinchEventHandler = (
info: TLPointerInfo<string>,
e:
| React.WheelEvent<Element>
| WheelEvent
| React.TouchEvent<Element>
| TouchEvent
| React.PointerEvent<Element>
| PointerEventInit
) => 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 declare type TLWheelEventHandler = (info: TLPointerInfo<string>, e: React.WheelEvent<Element> | WheelEvent) => void;
export declare type TLPinchEventHandler = (info: TLPointerInfo<string>, e: React.WheelEvent<Element> | WheelEvent | React.TouchEvent<Element> | TouchEvent | React.PointerEvent<Element> | PointerEventInit) => void;
export declare type TLShapeChangeHandler<T, K = any> = (shape: {
id: string;
} & Partial<T>, info?: K) => void;
export declare type TLShapeBlurHandler<K = any> = (info?: K) => void;
export declare type TLKeyboardEventHandler = (key: string, info: TLKeyboardInfo, e: KeyboardEvent) => void;
export declare type TLPointerEventHandler = (info: TLPointerInfo<string>, e: React.PointerEvent) => void;
export declare type TLShapeCloneHandler = (info: TLPointerInfo<'top' | 'right' | 'bottom' | 'left' | 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'>, e: React.PointerEvent) => void;
export declare type TLShapeLinkHandler = (info: TLPointerInfo<'link'>, 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' | 'center' | 'left' | 'right'>, e: React.PointerEvent) => void;
export interface TLCallbacks<T extends TLShape> {
onPinchStart: TLPinchEventHandler
onPinchEnd: TLPinchEventHandler
onPinch: TLPinchEventHandler
onPan: TLWheelEventHandler
onZoom: TLWheelEventHandler
onPointerMove: TLPointerEventHandler
onPointerUp: TLPointerEventHandler
onPointerDown: TLPointerEventHandler
onPointCanvas: TLCanvasEventHandler
onDoubleClickCanvas: TLCanvasEventHandler
onRightPointCanvas: TLCanvasEventHandler
onDragCanvas: TLCanvasEventHandler
onReleaseCanvas: TLCanvasEventHandler
onPointShape: TLPointerEventHandler
onDoubleClickShape: TLPointerEventHandler
onRightPointShape: TLPointerEventHandler
onDragShape: TLPointerEventHandler
onHoverShape: TLPointerEventHandler
onUnhoverShape: TLPointerEventHandler
onReleaseShape: TLPointerEventHandler
onPointBounds: TLBoundsEventHandler
onDoubleClickBounds: TLBoundsEventHandler
onRightPointBounds: TLBoundsEventHandler
onDragBounds: TLBoundsEventHandler
onHoverBounds: TLBoundsEventHandler
onUnhoverBounds: TLBoundsEventHandler
onReleaseBounds: TLBoundsEventHandler
onPointBoundsHandle: TLBoundsHandleEventHandler
onDoubleClickBoundsHandle: TLBoundsHandleEventHandler
onRightPointBoundsHandle: TLBoundsHandleEventHandler
onDragBoundsHandle: TLBoundsHandleEventHandler
onHoverBoundsHandle: TLBoundsHandleEventHandler
onUnhoverBoundsHandle: TLBoundsHandleEventHandler
onReleaseBoundsHandle: TLBoundsHandleEventHandler
onPointHandle: TLPointerEventHandler
onDoubleClickHandle: TLPointerEventHandler
onRightPointHandle: TLPointerEventHandler
onDragHandle: TLPointerEventHandler
onHoverHandle: TLPointerEventHandler
onUnhoverHandle: TLPointerEventHandler
onReleaseHandle: TLPointerEventHandler
onRenderCountChange: (ids: string[]) => void
onShapeChange: (
shape: {
id: string
} & Partial<T>
) => void
onShapeBlur: () => void
onError: (error: Error) => void
onPinchStart: TLPinchEventHandler;
onPinchEnd: TLPinchEventHandler;
onPinch: TLPinchEventHandler;
onPan: TLWheelEventHandler;
onZoom: TLWheelEventHandler;
onPointerMove: TLPointerEventHandler;
onPointerUp: TLPointerEventHandler;
onPointerDown: TLPointerEventHandler;
onPointCanvas: TLCanvasEventHandler;
onDoubleClickCanvas: TLCanvasEventHandler;
onRightPointCanvas: TLCanvasEventHandler;
onDragCanvas: TLCanvasEventHandler;
onReleaseCanvas: TLCanvasEventHandler;
onPointShape: TLPointerEventHandler;
onDoubleClickShape: TLPointerEventHandler;
onRightPointShape: TLPointerEventHandler;
onDragShape: TLPointerEventHandler;
onHoverShape: TLPointerEventHandler;
onUnhoverShape: TLPointerEventHandler;
onReleaseShape: TLPointerEventHandler;
onPointBounds: TLBoundsEventHandler;
onDoubleClickBounds: TLBoundsEventHandler;
onRightPointBounds: TLBoundsEventHandler;
onDragBounds: TLBoundsEventHandler;
onHoverBounds: TLBoundsEventHandler;
onUnhoverBounds: TLBoundsEventHandler;
onReleaseBounds: TLBoundsEventHandler;
onPointBoundsHandle: TLBoundsHandleEventHandler;
onDoubleClickBoundsHandle: TLBoundsHandleEventHandler;
onRightPointBoundsHandle: TLBoundsHandleEventHandler;
onDragBoundsHandle: TLBoundsHandleEventHandler;
onHoverBoundsHandle: TLBoundsHandleEventHandler;
onUnhoverBoundsHandle: TLBoundsHandleEventHandler;
onReleaseBoundsHandle: TLBoundsHandleEventHandler;
onPointHandle: TLPointerEventHandler;
onDoubleClickHandle: TLPointerEventHandler;
onRightPointHandle: TLPointerEventHandler;
onDragHandle: TLPointerEventHandler;
onHoverHandle: TLPointerEventHandler;
onUnhoverHandle: TLPointerEventHandler;
onReleaseHandle: TLPointerEventHandler;
onShapeChange: TLShapeChangeHandler<T, any>;
onShapeBlur: TLShapeBlurHandler<any>;
onShapeClone: TLShapeCloneHandler;
onRenderCountChange: (ids: string[]) => void;
onError: (error: Error) => void;
onBoundsChange: (bounds: TLBounds) => void;
onKeyDown: TLKeyboardEventHandler;
onKeyUp: TLKeyboardEventHandler;
}
export interface TLBounds {
minX: number
minY: number
maxX: number
maxY: number
width: number
height: number
rotation?: number
minX: number;
minY: number;
maxX: number;
maxY: number;
width: number;
height: number;
rotation?: number;
}
export interface TLBoundsWithCenter extends TLBounds {
midX: number;
midY: number;
}
export declare type TLIntersection = {
didIntersect: boolean
message: string
points: number[][]
}
didIntersect: boolean;
message: string;
points: number[][];
};
export declare enum TLBoundsEdge {
Top = 'top_edge',
Right = 'right_edge',
Bottom = 'bottom_edge',
Left = 'left_edge',
Top = "top_edge",
Right = "right_edge",
Bottom = "bottom_edge",
Left = "left_edge"
}
export declare enum TLBoundsCorner {
TopLeft = 'top_left_corner',
TopRight = 'top_right_corner',
BottomRight = 'bottom_right_corner',
BottomLeft = 'bottom_left_corner',
TopLeft = "top_left_corner",
TopRight = "top_right_corner",
BottomRight = "bottom_right_corner",
BottomLeft = "bottom_left_corner"
}
export interface TLPointerInfo<T extends string = string> {
target: T
pointerId: number
origin: number[]
point: number[]
delta: number[]
pressure: number
shiftKey: boolean
ctrlKey: boolean
metaKey: boolean
altKey: boolean
target: T;
pointerId: number;
origin: number[];
point: number[];
delta: number[];
pressure: number;
shiftKey: boolean;
ctrlKey: boolean;
metaKey: boolean;
altKey: boolean;
spaceKey: boolean;
}
export interface TLKeyboardInfo {
origin: number[]
point: number[]
key: string
keys: string[]
shiftKey: boolean
ctrlKey: boolean
metaKey: boolean
altKey: boolean
origin: number[];
point: number[];
key: string;
keys: string[];
shiftKey: boolean;
ctrlKey: boolean;
metaKey: boolean;
altKey: boolean;
}
export interface TLTransformInfo<T extends TLShape> {
type: TLBoundsEdge | TLBoundsCorner
initialShape: T
scaleX: number
scaleY: number
transformOrigin: number[]
type: TLBoundsEdge | TLBoundsCorner;
initialShape: T;
scaleX: number;
scaleY: number;
transformOrigin: number[];
}
export interface TLBezierCurveSegment {
start: number[]
tangentStart: number[]
normalStart: number[]
pressureStart: number
end: number[]
tangentEnd: number[]
normalEnd: number[]
pressureEnd: number
start: number[];
tangentStart: number[];
normalStart: number[];
pressureStart: number;
end: number[];
tangentEnd: number[];
normalEnd: number[];
pressureEnd: 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: 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 enum SnapPoints {
minX = "minX",
midX = "midX",
maxX = "maxX",
minY = "minY",
midY = "midY",
maxY = "maxY"
}
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> {
shape: T
children?: IShapeTreeNode<TLShape, M>[]
isEditing: boolean
isBinding: boolean
isHovered: boolean
isSelected: boolean
isCurrentParent: boolean
meta?: M extends any ? M : never
shape: T;
children?: IShapeTreeNode<TLShape, M>[];
isEditing: boolean;
isBinding: boolean;
isHovered: boolean;
isSelected: boolean;
isCurrentParent: boolean;
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

Wyświetl plik

@ -0,0 +1,5 @@
import { Utils } from './utils';
export { Utils } from './utils';
export { Svg } from './svg';
export default Utils;
//# sourceMappingURL=index.d.ts.map

Wyświetl plik

@ -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"}

Wyświetl plik

@ -0,0 +1 @@
//# sourceMappingURL=polyfills.d.ts.map

Wyświetl plik

@ -0,0 +1 @@
{"version":3,"file":"polyfills.d.ts","sourceRoot":"","sources":["polyfills.ts"],"names":[],"mappings":""}

Wyświetl plik

@ -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

Wyświetl plik

@ -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"}

Wyświetl plik

@ -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

Wyświetl plik

@ -1,5 +1,5 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import Utils from '~../../core/src/utils'
import { Utils } from '@tldraw/core'
import { TLDrawState } from '~state'
import { TLDR } from '~state/tldr'
import { mockDocument } from '~test'

Wyświetl plik

@ -9,10 +9,10 @@ import {
SessionType,
} from '~types'
import { Vec } from '@tldraw/vec'
import { Utils } from '@tldraw/core'
import { Utils, TLBounds } from '@tldraw/core'
import { TLDR } from '~state/tldr'
export class ArrowSession implements Session {
export class ArrowSession extends Session {
static type = SessionType.Arrow
status = TLDrawStatus.TranslatingHandle
newStartBindingId = Utils.uniqueId()
@ -29,7 +29,15 @@ export class ArrowSession implements Session {
startBindingShapeId?: string
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
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 page = TLDR.getPage(data, data.appState.currentPageId)

Wyświetl plik

@ -1,15 +1,16 @@
import { Utils } from '@tldraw/core'
import { Utils, TLBounds } from '@tldraw/core'
import { Vec } from '@tldraw/vec'
import { Data, Session, SessionType, TLDrawPatch, TLDrawStatus } from '~types'
import { TLDR } from '~state/tldr'
export class BrushSession implements Session {
export class BrushSession extends Session {
static type = SessionType.Brush
status = TLDrawStatus.Brushing
origin: number[]
snapshot: BrushSnapshot
constructor(data: Data, point: number[]) {
constructor(data: Data, viewport: TLBounds, point: number[]) {
super(viewport)
this.origin = Vec.round(point)
this.snapshot = getBrushSnapshot(data)
}
@ -78,7 +79,7 @@ export class BrushSession implements Session {
}
}
cancel(data: Data) {
cancel = (data: Data) => {
const { currentPageId } = data.appState
return {
document: {
@ -92,7 +93,7 @@ export class BrushSession implements Session {
}
}
complete(data: Data) {
complete = (data: Data) => {
const { currentPageId } = data.appState
const pageState = TLDR.getPageState(data, currentPageId)

Wyświetl plik

@ -1,9 +1,9 @@
import { Utils } from '@tldraw/core'
import { Utils, TLBounds } from '@tldraw/core'
import { Vec } from '@tldraw/vec'
import { Data, Session, SessionType, TLDrawStatus } from '~types'
import { TLDR } from '~state/tldr'
export class DrawSession implements Session {
export class DrawSession extends Session {
static type = SessionType.Draw
status = TLDrawStatus.Creating
topLeft: number[]
@ -16,7 +16,8 @@ export class DrawSession implements Session {
isLocked?: boolean
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.previous = point
this.last = point

Wyświetl plik

@ -16,7 +16,7 @@ import {
import { TLDR } from '~state/tldr'
import type { Patch } from 'rko'
export class GridSession implements Session {
export class GridSession extends Session {
type = SessionType.Grid
status = TLDrawStatus.Translating
origin: number[]
@ -29,7 +29,8 @@ export class GridSession implements Session {
rows = 1
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.shape = TLDR.getShape(data, id, pageId)
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 beforeShapes: Patch<Record<string, TLDrawShape>> = {}

Wyświetl plik

@ -1,10 +1,11 @@
import { Vec } from '@tldraw/vec'
import type { TLBounds } from '@tldraw/core'
import { SessionType, ShapesWithProp, TLDrawStatus } from '~types'
import type { Session } from '~types'
import { Session } from '~types'
import type { Data } from '~types'
import { TLDR } from '~state/tldr'
export class HandleSession implements Session {
export class HandleSession extends Session {
static type = SessionType.Handle
status = TLDrawStatus.TranslatingHandle
commandId: string
@ -15,7 +16,14 @@ export class HandleSession implements Session {
initialShape: ShapesWithProp<'handles'>
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 shapeId = TLDR.getSelectedIds(data, currentPageId)[0]
this.topLeft = point
@ -86,7 +94,7 @@ export class HandleSession implements Session {
}
}
complete(data: Data) {
complete = (data: Data) => {
const { initialShape } = this
const pageId = data.appState.currentPageId

Wyświetl plik

@ -1,4 +1,4 @@
import { Utils } from '@tldraw/core'
import { Utils, TLBounds } from '@tldraw/core'
import { Vec } from '@tldraw/vec'
import { Session, SessionType, TLDrawShape, TLDrawStatus } from '~types'
import type { Data } from '~types'
@ -6,7 +6,7 @@ import { TLDR } from '~state/tldr'
const centerCache = new WeakMap<string[], number[]>()
export class RotateSession implements Session {
export class RotateSession extends Session {
static type = SessionType.Rotate
status = TLDrawStatus.Transforming
delta = [0, 0]
@ -15,7 +15,8 @@ export class RotateSession implements Session {
initialAngle: number
changes: Record<string, Partial<TLDrawShape>> = {}
constructor(data: Data, point: number[]) {
constructor(data: Data, viewport: TLBounds, point: number[]) {
super(viewport)
this.origin = point
this.snapshot = getRotateSnapshot(data)
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 pageId = data.appState.currentPageId

Wyświetl plik

@ -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 { SessionType, TLDrawShape, TLDrawStatus } from '~types'
import type { Session } from '~types'
import { Session } from '~types'
import type { Data } from '~types'
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 =
| {
@ -15,7 +22,7 @@ type SnapInfo =
bounds: TLBoundsWithCenter[]
}
export class TransformSingleSession implements Session {
export class TransformSingleSession extends Session {
type = SessionType.TransformSingle
status = TLDrawStatus.Transforming
transformType: TLBoundsEdge | TLBoundsCorner
@ -30,10 +37,12 @@ export class TransformSingleSession implements Session {
constructor(
data: Data,
viewport: TLBounds,
point: number[],
transformType: TLBoundsEdge | TLBoundsCorner = TLBoundsCorner.BottomRight,
isCreate = false
) {
super(viewport)
this.origin = point
this.transformType = transformType
this.snapshot = getTransformSingleSnapshot(data, transformType)
@ -88,7 +97,10 @@ export class TransformSingleSession implements Session {
) {
const snapResult = Utils.getSnapPoints(
Utils.getBoundsWithCenter(newBounds),
this.snapInfo.bounds,
this.snapInfo.bounds.filter(
(bounds) =>
Utils.boundsContain(this.viewport, bounds) || Utils.boundsCollide(this.viewport, bounds)
),
SNAP_DISTANCE / zoom
)
@ -161,7 +173,7 @@ export class TransformSingleSession implements Session {
}
}
complete(data: Data) {
complete = (data: Data) => {
if (!this.snapshot.hasUnlockedShape) return data
const { initialShape } = this.snapshot

Wyświetl plik

@ -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 type { TLSnapLine, TLBoundsWithCenter } from '@tldraw/core'
import { Session, SessionType, TLDrawShape, TLDrawStatus } from '~types'
import type { Data } from '~types'
import { TLDR } from '~state/tldr'
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 =
| {
@ -16,7 +16,7 @@ type SnapInfo =
bounds: TLBoundsWithCenter[]
}
export class TransformSession implements Session {
export class TransformSession extends Session {
static type = SessionType.Transform
status = TLDrawStatus.Transforming
scaleX = 1
@ -32,10 +32,12 @@ export class TransformSession implements Session {
constructor(
data: Data,
viewport: TLBounds,
point: number[],
transformType: TLBoundsEdge | TLBoundsCorner = TLBoundsCorner.BottomRight,
isCreate = false
) {
super(viewport)
this.origin = point
this.transformType = transformType
this.snapshot = getTransformSnapshot(data, transformType)
@ -92,7 +94,10 @@ export class TransformSession implements Session {
) {
const snapResult = Utils.getSnapPoints(
Utils.getBoundsWithCenter(newBounds),
this.snapInfo.bounds,
this.snapInfo.bounds.filter(
(bounds) =>
Utils.boundsContain(this.viewport, bounds) || Utils.boundsCollide(this.viewport, bounds)
),
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
undefined
if (!hasUnlockedShapes) return

Wyświetl plik

@ -1,5 +1,5 @@
/* 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 {
TLDrawShape,
@ -12,9 +12,8 @@ import {
GroupShape,
SessionType,
ArrowBinding,
TLDrawShapeType,
} 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 type { Patch } from 'rko'
@ -38,7 +37,7 @@ type SnapInfo =
bounds: TLBoundsWithCenter[]
}
export class TranslateSession implements Session {
export class TranslateSession extends Session {
type = SessionType.Translate
status = TLDrawStatus.Translating
delta = [0, 0]
@ -60,10 +59,12 @@ export class TranslateSession implements Session {
constructor(
data: Data,
viewport: TLBounds,
point: number[],
isCreate = false,
isLinked: 'left' | 'right' | 'center' | false = false
) {
super(viewport)
this.origin = point
this.snapshot = getTranslateSnapshot(data, isLinked)
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 { currentPageId } = data.appState
@ -158,7 +166,10 @@ export class TranslateSession implements Session {
const snapResult = Utils.getSnapPoints(
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
)
@ -370,7 +381,7 @@ export class TranslateSession implements Session {
}
}
complete(data: Data): TLDrawCommand {
complete = (data: Data): TLDrawCommand => {
const pageId = data.appState.currentPageId
const { initialShapes, initialParentChildren, bindingsToDelete } = this.snapshot

Wyświetl plik

@ -36,6 +36,7 @@ import {
TLDrawUser,
SessionType,
ExceptFirst,
ExceptFirstTwo,
} from '~types'
import { TLDR } from './tldr'
import { defaultStyle, tldrawShapeUtils } from '~shape'
@ -361,6 +362,10 @@ export class TLDrawState extends StateManager<Data> {
*/
updateBounds = (bounds: TLBounds) => {
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?
*/
setCamera = (point: number[], zoom: number, reason: string): this => {
return this.patchState(
this.patchState(
{
document: {
pageStates: {
@ -1339,6 +1344,12 @@ export class TLDrawState extends StateManager<Data> {
},
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 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) {
throw Error(`Already in a session! (${this.session.constructor.name})`)
}
@ -1648,7 +1659,7 @@ export class TLDrawState extends StateManager<Data> {
const Session = getSession(type)
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @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)

Wyświetl plik

@ -1,5 +1,5 @@
import Vec from '@tldraw/vec'
import type {
import {
TLBoundsEventHandler,
TLBoundsHandleEventHandler,
TLCanvasEventHandler,
@ -9,8 +9,8 @@ import type {
TLShapeBlurHandler,
TLShapeCloneHandler,
TLWheelEventHandler,
} from '~../../core/src/types'
import Utils from '~../../core/src/utils'
Utils,
} from '@tldraw/core'
import type { TLDrawState } from '~state'
import type { TLDrawShapeType } from '~types'

Wyświetl plik

@ -1,6 +1,5 @@
import Vec from '@tldraw/vec'
import type { TLPointerEventHandler } from '~../../core/src/types'
import Utils from '~../../core/src/utils'
import { Utils, TLPointerEventHandler } from '@tldraw/core'
import { Draw } from '~shape/shapes'
import { SessionType, TLDrawShapeType } from '~types'
import { BaseTool, Status } from '../BaseTool'

Wyświetl plik

@ -1,6 +1,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* 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 { TLPage, TLUser, TLPageState } from '@tldraw/core'
import type { StoreApi } from 'zustand'
@ -116,6 +116,16 @@ export abstract class Session {
) => TLDrawPatch | undefined
abstract complete: (data: Readonly<Data>) => TLDrawPatch | TLDrawCommand | 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 {
@ -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 ExceptFirstTwo<T extends unknown[]> = T extends [any, any, ...infer U] ? U : never
export enum MoveType {
Backward = 'backward',
Forward = 'forward',

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long