react-moveable
Version:
A React Component that create Moveable, Draggable, Resizable, Scalable, Rotatable, Warpable, Pinchable, Groupable.
146 lines (128 loc) • 4.81 kB
text/typescript
import { Client } from "@daybrush/drag";
import { triggerEvent, fillParams } from "../utils";
import MoveableManager from "../MoveableManager";
import { PinchableProps, Able, SnappableState, OnPinchStart, OnPinch, OnPinchEnd } from "../types";
import MoveableGroup from "../MoveableGroup";
import { getRad } from "@moveable/matrix";
function getRotatiion(touches: Client[]) {
return getRad([
touches[0].clientX,
touches[0].clientY,
], [
touches[1].clientX,
touches[1].clientY,
]) / Math.PI * 180;
}
export default {
name: "pinchable",
updateRect: true,
pinchStart(
moveable: MoveableManager<PinchableProps, SnappableState>,
e: any,
) {
const { datas, clientX, clientY, touches, inputEvent, targets } = e;
const { pinchable, ables } = moveable.props;
if (!pinchable) {
return false;
}
const eventName = `onPinch${targets ? "Group" : ""}Start` as "onPinchStart";
const controlEventName = `drag${targets ? "Group" : ""}ControlStart` as "dragControlStart";
const pinchAbles = (pinchable === true ? moveable.controlAbles : ables!.filter(able => {
return pinchable.indexOf(able.name as any) > -1;
})).filter(able => able.canPinch && able[controlEventName]);
const params = fillParams<OnPinchStart>(moveable, e, {}) as any;
if (targets) {
params.targets = targets;
}
const result = triggerEvent(moveable, eventName, params);
datas.isPinch = result !== false;
datas.ables = pinchAbles;
const isPinch = datas.isPinch;
if (!isPinch) {
return false;
}
const parentRotate = getRotatiion(touches);
pinchAbles.forEach(able => {
datas[able.name + "Datas"] = {};
const ableEvent: any = {
datas: datas[able.name + "Datas"],
clientX,
clientY,
inputEvent,
parentRotate,
pinchFlag: true,
};
able[controlEventName]!(moveable, ableEvent);
});
moveable.state.snapDirection = [0, 0];
return isPinch;
},
pinch(
moveable: MoveableManager<PinchableProps>,
e: any,
) {
const { datas, clientX, clientY, scale: pinchScale, distance, touches, inputEvent, targets } = e;
if (!datas.isPinch) {
return;
}
const parentRotate = getRotatiion(touches);
const parentDistance = distance * (1 - 1 / pinchScale);
const params = fillParams<OnPinch>(moveable, e, {}) as any;
if (targets) {
params.targets = targets;
}
const eventName = `onPinch${targets ? "Group" : ""}` as "onPinch";
triggerEvent(moveable, eventName, params);
const ables: Able[] = datas.ables;
const controlEventName = `drag${targets ? "Group" : ""}Control` as "dragControl";
ables.forEach(able => {
able[controlEventName]!(moveable, {
clientX,
clientY,
datas: datas[able.name + "Datas"],
inputEvent,
parentDistance,
parentRotate,
pinchFlag: true,
} as any);
});
return params;
},
pinchEnd(
moveable: MoveableManager<PinchableProps>,
e: any,
) {
const { datas, clientX, clientY, isPinch, inputEvent, targets } = e;
if (!datas.isPinch) {
return;
}
const eventName = `onPinch${targets ? "Group" : ""}End` as "onPinchEnd";
const params = fillParams<OnPinchEnd>(moveable, e, { isDrag: isPinch }) as any;
if (targets) {
params.targets = targets;
}
triggerEvent(moveable, eventName, params);
const ables: Able[] = datas.ables;
const controlEventName = `drag${targets ? "Group" : ""}ControlEnd` as "dragControlEnd";
ables.forEach(able => {
able[controlEventName]!(moveable, {
clientX,
clientY,
isDrag: isPinch,
datas: datas[able.name + "Datas"],
inputEvent,
pinchFlag: true,
} as any);
});
return isPinch;
},
pinchGroupStart(moveable: MoveableGroup, e: any) {
return this.pinchStart(moveable, { ...e, targets: moveable.props.targets });
},
pinchGroup(moveable: MoveableGroup, e: any) {
return this.pinch(moveable, { ...e, targets: moveable.props.targets });
},
pinchGroupEnd(moveable: MoveableGroup, e: any) {
return this.pinchEnd(moveable, { ...e, targets: moveable.props.targets });
},
};