react-moveable
Version:
A React Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable, Groupable.
137 lines (117 loc) • 4.31 kB
text/typescript
import { Able, MoveableGroupInterface, MoveableManagerInterface, MoveableManagerState } from "./types";
import CustomGesto, { setCustomDrag } from "./gesto/CustomGesto";
import { getAbsolutePosesByState } from "./utils";
import { calculate, createRotateMatrix } from "@scena/matrix";
import { getPosByDirection } from "./gesto/GestoUtils";
export function fillChildEvents(
moveable: MoveableGroupInterface<any, any>,
name: string,
e: any,
): any[] {
const datas = e.originalDatas;
datas.groupable = datas.groupable || {};
const groupableDatas = datas.groupable;
groupableDatas.childDatas = groupableDatas.childDatas || [];
const childDatas = groupableDatas.childDatas;
return moveable.moveables.map((_, i) => {
childDatas[i] = childDatas[i] || {};
childDatas[i][name] = childDatas[i][name] || {};
return {
...e,
isRequestChild: true,
datas: childDatas[i][name],
originalDatas: childDatas[i],
};
});
}
export function triggerChildGesto(
moveable: MoveableGroupInterface<any, any>,
able: Able,
type: string,
delta: number[],
e: any,
isConvert: boolean,
ableName: string,
) {
const isStart = !!type.match(/Start$/g);
const isEnd = !!type.match(/End$/g);
const isPinch = e.isPinch;
const datas = e.datas;
const events = fillChildEvents(moveable, able.name, e);
const moveables = moveable.moveables;
const childEvents: any[] = [];
const eventParams = events.map((ev, i) => {
const childMoveable = moveables[i];
const state = childMoveable.state as MoveableManagerState<any>;
const gestos = state.gestos;
let childEvent: any = ev;
if (isStart) {
childEvent = new CustomGesto(ableName).dragStart(delta, ev);
childEvents.push(childEvent);
} else {
if (!gestos[ableName]) {
gestos[ableName] = datas.childGestos[i];
}
if (!gestos[ableName]) {
return;
}
childEvent = setCustomDrag(ev, state, delta, isPinch, isConvert, ableName);
childEvents.push(childEvent);
}
const result = (able as any)[type]!(childMoveable, { ...childEvent, parentFlag: true });
if (isEnd) {
gestos[ableName] = null;
}
return result;
});
if (isStart) {
datas.childGestos = moveables.map(child => child.state.gestos[ableName]);
}
return {
eventParams,
childEvents,
};
}
export function triggerChildAbles<T extends Able>(
moveable: MoveableGroupInterface<any, any>,
able: T,
type: keyof T & string,
e: any,
eachEvent: (movebale: MoveableManagerInterface<any, any>, ev: any) => any = (_, ev) => ev,
callback?: (moveable: MoveableManagerInterface<any, any>, ev: any, result: any, index: number) => any,
) {
const isEnd = !!type.match(/End$/g);
const events = fillChildEvents(moveable, able.name, e);
const moveables = moveable.moveables;
const childs = events.map((ev, i) => {
const childMoveable = moveables[i];
let childEvent = ev;
childEvent = eachEvent(childMoveable, ev);
const result = (able as any)[type]!(childMoveable, { ...childEvent, parentFlag: true });
result && callback && callback(childMoveable, ev, result, i);
if (isEnd) {
childMoveable.state.gestos = {};
}
return result;
});
return childs;
}
export function startChildDist(
moveable: MoveableGroupInterface,
child: MoveableManagerInterface,
parentDatas: any,
childEvent: any,
) {
const fixedDirection = parentDatas.fixedDirection;
const fixedPosition = parentDatas.fixedPosition;
const startPositions = childEvent.datas.startPositions || getAbsolutePosesByState(child.state);
const pos = getPosByDirection(startPositions, fixedDirection);
const [originalX, originalY] = calculate(
createRotateMatrix(-moveable.rotation / 180 * Math.PI, 3),
[pos[0] - fixedPosition[0], pos[1] - fixedPosition[1], 1],
3,
);
childEvent.datas.originalX = originalX;
childEvent.datas.originalY = originalY;
return childEvent;
}