react-moveable
Version:
A React Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable, Groupable.
460 lines (459 loc) • 14.9 kB
TypeScript
import { IObject } from "@daybrush/utils";
import Dragger, * as DraggerTypes from "@daybrush/drag";
import CustomDragger from "./CustomDragger";
import { Position } from "@daybrush/drag";
export interface MoveableClientRect {
left: number;
top: number;
right: number;
bottom: number;
width: number;
height: number;
}
export declare type MoveableManagerProps<T = {}> = {
target?: SVGElement | HTMLElement | null;
container?: SVGElement | HTMLElement | null;
dragArea?: boolean;
parentMoveable?: any;
parentPosition?: {
left: number;
top: number;
} | null;
origin?: boolean;
transformOrigin?: Array<string | number> | "";
edge?: boolean;
keepRatio?: boolean;
pinchThreshold?: number;
ables?: Array<Able<T>>;
className?: string;
} & T;
export declare type MoveableManagerState<T = {}> = {
container: SVGElement | HTMLElement | null | undefined;
target: SVGElement | HTMLElement | null | undefined;
left: number;
top: number;
right: number;
bottom: number;
width: number;
height: number;
beforeMatrix: number[];
matrix: number[];
targetTransform: string;
targetMatrix: number[];
offsetMatrix: number[];
is3d: boolean;
transformOrigin: number[];
beforeOrigin: number[];
origin: number[];
beforeDirection: 1 | -1;
direction: 1 | -1;
pos1: number[];
pos2: number[];
pos3: number[];
pos4: number[];
dragger: Dragger | CustomDragger | null;
clientRect: MoveableClientRect;
containerRect: MoveableClientRect;
} & T;
export interface Renderer {
createElement(type: any, props?: any, ...children: any[]): any;
}
export interface Guideline {
type: "horizontal" | "vertical";
element?: Element | null;
center?: boolean;
pos: number[];
size: number;
}
export interface BoundInfo {
isBound: boolean;
offset: number;
pos: number;
}
export interface SnapInfo {
isSnap: boolean;
dist: number;
offset: number;
guidelines: Guideline[];
snapPoses: number[];
}
export interface MoveableProps extends MoveableManagerProps<any>, DraggableProps, RotatableProps, ResizableProps, ScalableProps, WarpableProps, PinchableProps, GroupableProps, SnappableProps, ScrollableProps, RenderProps {
target?: SVGElement | HTMLElement | Array<SVGElement | HTMLElement> | null;
container?: SVGElement | HTMLElement | null;
origin?: boolean;
keepRatio?: boolean;
edge?: boolean;
pinchThreshold?: number;
ables?: Able[];
}
export declare type MoveableState = MoveableManagerState;
export interface Able<T = any> {
name: string & keyof MoveableManagerProps<T>;
ableGroup?: string;
updateRect?: boolean;
canPinch?: boolean;
unset?: (moveable: MoveableManagerProps<any>) => any;
render?: (moveable: MoveableManagerProps<any>, renderer: Renderer) => any;
dragStart?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDragStart) => any;
drag?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDrag) => any;
dragEnd?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDragEnd) => any;
pinchStart?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnPinchStart) => any;
pinch?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnPinch) => any;
pinchEnd?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnPinchEnd) => any;
dragControlCondition?: (target: SVGElement | HTMLElement) => boolean;
dragControlStart?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDragStart) => any;
dragControl?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDrag) => any;
dragControlEnd?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDragEnd) => any;
dragGroupCondition?: (target: SVGElement | HTMLElement) => boolean;
dragGroupStart?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDragStart) => any;
dragGroup?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDrag) => any;
dragGroupEnd?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDragEnd) => any;
pinchGroupStart?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnPinchStart) => any;
pinchGroup?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnPinch) => any;
pinchGroupEnd?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnPinchEnd) => any;
dragGroupControlCondition?: (target: SVGElement | HTMLElement) => boolean;
dragGroupControlStart?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDragStart) => any;
dragGroupControl?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDragStart) => any;
dragGroupControlEnd?: (moveable: MoveableManagerProps<any>, e: DraggerTypes.OnDragEnd) => any;
}
export interface OnEvent {
currentTarget: MoveableInterface;
target: HTMLElement | SVGElement;
clientX: number;
clientY: number;
datas: IObject<any>;
inputEvent: any;
}
export interface OnPinchStart extends OnEvent {
}
export interface OnPinch extends OnEvent {
}
export interface OnPinchEnd extends OnEvent {
isDrag: boolean;
}
export interface OnDragStart extends OnEvent {
set: (translate: number[]) => void;
}
export interface OnDrag extends OnEvent {
beforeDelta: number[];
beforeDist: number[];
beforeTranslate: number[];
delta: number[];
dist: number[];
translate: number[];
transform: string;
left: number;
top: number;
bottom: number;
right: number;
isPinch: boolean;
}
export interface OnDragEnd extends OnEvent {
isDrag: boolean;
}
export interface OnScaleStart extends OnEvent {
direction: number[];
dragStart: OnDragStart | false;
set: (scale: number[]) => void;
}
export interface OnScale extends OnEvent {
direction: number[];
scale: number[];
dist: number[];
delta: number[];
transform: string;
isPinch: boolean;
drag: OnDrag;
}
export interface OnScaleEnd extends OnEvent {
isDrag: boolean;
}
export interface OnResizeStart extends OnEvent {
direction: number[];
dragStart: OnDragStart | false;
set: (sizes: number[]) => any;
setOrigin: (origin: Array<string | number>) => any;
}
export interface OnResize extends OnEvent {
direction: number[];
width: number;
height: number;
offsetWidth: number;
offsetHeight: number;
dist: number[];
delta: number[];
isPinch: boolean;
drag: OnDrag;
}
export interface OnResizeEnd extends OnEvent {
isDrag: boolean;
}
export interface OnRotateStart extends OnEvent {
set: (rotate: number) => void;
}
export interface OnRotate extends OnEvent {
beforeDist: number;
beforeDelta: number;
beforeRotate: number;
dist: number;
delta: number;
rotate: number;
transform: string;
isPinch: boolean;
}
export interface OnRotateEnd extends OnEvent {
isDrag: boolean;
}
export interface OnWarpStart extends OnEvent {
set: (matrix: number[]) => any;
}
export interface OnWarp extends OnEvent {
transform: string;
delta: number[];
dist: number[];
matrix: number[];
multiply: (matrix1: number[], matrix2: number[], n?: number) => number[];
}
export interface OnWarpEnd extends OnEvent {
isDrag: boolean;
}
export interface OnDragGroupStart extends OnDragStart {
targets: Array<HTMLElement | SVGElement>;
events: OnDragStart[];
}
export interface OnDragGroup extends OnDrag {
targets: Array<HTMLElement | SVGElement>;
events: OnDrag[];
}
export interface OnDragGroupEnd extends OnDragEnd {
targets: Array<HTMLElement | SVGElement>;
isDrag: boolean;
}
export interface OnRotateGroupStart extends OnRotateStart {
targets: Array<HTMLElement | SVGElement>;
events: Array<OnRotateStart & {
dragStart: OnDragStart | false;
}>;
}
export interface OnRotateGroup extends OnRotate {
targets: Array<HTMLElement | SVGElement>;
events: Array<OnRotate & {
drag: OnDrag;
}>;
}
export interface OnRotateGroupEnd extends OnRotateEnd {
targets: Array<HTMLElement | SVGElement>;
isDrag: boolean;
}
export interface OnResizeGroupStart extends OnResizeStart {
targets: Array<HTMLElement | SVGElement>;
events: OnResizeStart[];
}
export interface OnResizeGroup extends OnResize {
targets: Array<HTMLElement | SVGElement>;
events: Array<OnResize & {
drag: OnDrag;
}>;
}
export interface OnResizeGroupEnd extends OnResizeEnd {
targets: Array<HTMLElement | SVGElement>;
isDrag: boolean;
}
export interface OnScaleGroupStart extends OnScaleStart {
targets: Array<HTMLElement | SVGElement>;
events: OnScaleStart[];
}
export interface OnScaleGroup extends OnScale {
targets: Array<HTMLElement | SVGElement>;
events: Array<OnScale & {
drag: OnDrag;
}>;
}
export interface OnScaleGroupEnd extends OnScaleEnd {
targets: Array<HTMLElement | SVGElement>;
isDrag: boolean;
}
export interface OnPinchGroupStart extends OnPinchStart {
targets: Array<HTMLElement | SVGElement>;
}
export interface OnPinchGroup extends OnPinch {
targets: Array<HTMLElement | SVGElement>;
}
export interface OnPinchGroupEnd extends OnPinchEnd {
targets: Array<HTMLElement | SVGElement>;
}
export interface OnClick extends OnEvent {
inputTarget: HTMLElement | SVGElement;
isTarget: boolean;
containsTarget: boolean;
}
export interface OnClickGroup extends OnEvent {
targets: Array<HTMLElement | SVGElement>;
inputTarget: HTMLElement | SVGElement;
isTarget: boolean;
containsTarget: boolean;
targetIndex: number;
}
export interface OnRenderStart extends OnEvent {
isPinch: boolean;
}
export interface OnRender extends OnEvent {
isPinch: boolean;
}
export interface OnRenderEnd extends OnEvent {
isPinch: boolean;
isDrag: boolean;
}
export interface OnScroll extends OnEvent {
scrollContainer: HTMLElement;
direction: number[];
}
export interface OnScrollGroup extends OnScroll {
targets: Array<HTMLElement | SVGElement>;
}
export interface OnRenderGroupStart extends OnRenderStart {
targets: Array<HTMLElement | SVGElement>;
}
export interface OnRenderGroup extends OnRender {
targets: Array<HTMLElement | SVGElement>;
}
export interface OnRenderGroupEnd extends OnRenderEnd {
targets: Array<HTMLElement | SVGElement>;
}
export interface OriginProps {
origin: boolean;
}
export interface DraggableProps {
draggable?: boolean;
throttleDrag?: number;
onDragStart?: (e: OnDragStart) => any;
onDrag?: (e: OnDrag) => any;
onDragEnd?: (e: OnDragEnd) => any;
onDragGroupStart?: (e: OnDragGroupStart) => any;
onDragGroup?: (e: OnDragGroup) => any;
onDragGroupEnd?: (e: OnDragGroupEnd) => any;
}
export interface ResizableProps {
resizable?: boolean;
throttleResize?: number;
renderDirections?: string[];
onResizeStart?: (e: OnResizeStart) => any;
onResize?: (e: OnResize) => any;
onResizeEnd?: (e: OnResizeEnd) => any;
onResizeGroupStart?: (e: OnResizeGroupStart) => any;
onResizeGroup?: (e: OnResizeGroup) => any;
onResizeGroupEnd?: (e: OnResizeGroupEnd) => any;
}
export interface ScalableProps {
scalable?: boolean;
throttleScale?: number;
renderDirections?: string[];
onScaleStart?: (e: OnScaleStart) => any;
onScale?: (e: OnScale) => any;
onScaleEnd?: (e: OnScaleEnd) => any;
onScaleGroupStart?: (e: OnScaleGroupStart) => any;
onScaleGroup?: (e: OnScaleGroup) => any;
onScaleGroupEnd?: (e: OnScaleGroupEnd) => any;
}
export interface RotatableProps {
rotatable?: boolean;
rotationPosition?: "top" | "bottom" | "left" | "right";
throttleRotate?: number;
onRotateStart?: (e: OnRotateStart) => any;
onRotate?: (e: OnRotate) => any;
onRotateEnd?: (e: OnRotateEnd) => any;
onRotateGroupStart?: (e: OnRotateGroupStart) => any;
onRotateGroup?: (e: OnRotateGroup) => any;
onRotateGroupEnd?: (e: OnRotateGroupEnd) => any;
}
export interface WarpableProps {
warpable?: boolean;
renderDirections?: string[];
onWarpStart?: (e: OnWarpStart) => any;
onWarp?: (e: OnWarp) => any;
onWarpEnd?: (e: OnWarpEnd) => any;
}
export interface PinchableProps extends ResizableProps, ScalableProps, RotatableProps {
pinchable?: boolean | Array<"rotatable" | "resizable" | "scalable">;
onPinchStart?: (e: OnPinchStart) => any;
onPinch?: (e: OnPinch) => any;
onPinchEnd?: (e: OnPinchEnd) => any;
onPinchGroupStart?: (e: OnPinchGroupStart) => any;
onPinchGroup?: (e: OnPinchGroup) => any;
onPinchGroupEnd?: (e: OnPinchGroupEnd) => any;
}
export interface GroupableProps extends PinchableProps, DraggableProps, RotatableProps, ResizableProps, ScalableProps, SnappableProps, RenderProps, DragAreaProps, ScrollableProps {
groupable?: boolean;
targets?: Array<HTMLElement | SVGElement>;
updateGroup?: boolean;
}
export interface SnappableProps {
snappable?: boolean | string[];
snapCenter?: boolean;
snapThreshold?: number;
horizontalGuidelines?: number[];
verticalGuidelines?: number[];
elementGuidelines?: Element[];
bounds?: {
left?: number;
top?: number;
right?: number;
bottom?: number;
};
}
export interface SnappableState {
guidelines: any[];
snapDirection: number[] | true | null;
enableSnap: boolean;
}
export interface ScrollableProps {
scrollable?: boolean;
scrollContainer?: HTMLElement;
scrollThreshold?: number;
getScrollPosition?: (e: {
scrollContainer: HTMLElement;
direction: number[];
}) => number[];
onScroll?: (e: OnScroll) => any;
onScrollGroup?: (e: OnScrollGroup) => any;
}
export interface DragAreaProps {
dragArea?: boolean;
onClick?: (e: OnClick) => any;
onClickGroup?: (e: OnClickGroup) => any;
}
export interface RenderProps {
onRenderStart?: (e: OnRenderStart) => any;
onRender?: (e: OnRender) => any;
onRenderEnd?: (e: OnRenderEnd) => any;
onRenderGroupStart?: (e: OnRenderGroupStart) => any;
onRenderGroup?: (e: OnRenderGroup) => any;
onRenderGroupEnd?: (e: OnRenderGroupEnd) => any;
}
export interface OnCustomDrag extends Position {
inputEvent: any;
isDrag: boolean;
datas: IObject<any>;
parentEvent: boolean;
parentDragger: CustomDragger;
}
export interface RectInfo {
pos1: number[];
pos2: number[];
pos3: number[];
pos4: number[];
left: number;
top: number;
width: number;
height: number;
}
export interface MoveableInterface {
getRect(): RectInfo;
isMoveableElement(target: HTMLElement | SVGElement): boolean;
updateRect(isNotSetState?: boolean): void;
updateTarget(): void;
destroy(): void;
dragStart(e: MouseEvent | TouchEvent): void;
isInside(clientX: number, clientY: number): boolean;
setState(state: any, callback?: () => any): any;
}