@aurigma/design-atoms
Version:
Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.
330 lines • 14.8 kB
JavaScript
import { InputType, NativeEventType, Button, InputState, isNativeMouseEvent } from "./IInputManager";
import { EventObject } from "@aurigma/design-atoms-model/EventObject";
import { PointF, RectangleF } from "@aurigma/design-atoms-model/Math";
import { FrontEndLogger, LogSource, LogClr } from "../../Services/FrontEndLogger";
import { PointerInputHelper } from "./PointerInputHelper";
export class InputManager {
constructor(_convertor = null, settings = null) {
this._convertor = _convertor;
this._touchEndCancel = false;
this._keyMap = new Map();
this._onMouseDown = (event) => {
if (this._currentAction != null)
return;
this._pointerInputHelper.onButtonDown(event.coordinates);
this._pointerEventNotify(event, InputType.PointerDown);
};
this._onMouseMove = (event) => {
this._pointerEventNotify(event, InputType.Hover);
if ((event.button !== Button.Primary) && (event.button !== Button.Tertiary))
return;
if (this._currentAction === InputType.Move)
return this._dragEventNotify(event, this._currentAction == null ? InputState.Started : InputState.InProgress);
if (this._currentAction == null && this._pointerInputHelper.isButtonDown() == false || this._pointerInputHelper.isInDownUpThresholdArea(event.coordinates, false))
return;
this._dragEventNotify(event, this._currentAction == null ? InputState.Started : InputState.InProgress);
};
this._onMouseUp = (event) => {
if (this._pointerInputHelper.isButtonDown() == false)
return;
const clickCount = this._pointerInputHelper.onButtonUp(event.coordinates, false, event.button);
if (this._currentAction !== InputType.Move) {
if (clickCount > 0)
this._pointerEventNotify(event, InputType.Click, clickCount);
}
else {
if (event.button !== Button.Primary && event.button !== Button.Secondary && event.button !== Button.Tertiary)
return;
this._dragEventNotify(event, InputState.Finished);
}
this._resetState();
};
this._onTouchStart = (event) => {
this._touchEndCancel = false;
this._pointerInputHelper.onButtonDown(event.touches[0]);
this._clearLongTapTimeout();
if (event.touches.length === 2) {
this._transformPoints = event.touches;
}
else {
this._longTapTimeout = window.setTimeout(this._onLongTap, this._settings.longTapTime, event);
this._pointerEventNotify(event, InputType.PointerDown);
}
};
this._onTouchMove = (event) => {
if (this._pointerInputHelper.isButtonDown() == false)
return;
if (event.touches.length === 2 && this._currentAction !== InputType.Move) {
let state;
if (this._currentAction == null) {
state = InputState.Started;
this._currentAction = InputType.Transform;
}
else {
state = InputState.InProgress;
}
this._transformEventNotify(event, state);
this._transformPoints = event.touches;
}
else {
if (this._currentAction !== InputType.Move && this._pointerInputHelper.isInDownUpThresholdArea(event.touches[0], true))
return;
this._clearLongTapTimeout();
this._dragEventNotify(event, this._currentAction == null ? InputState.Started : InputState.InProgress);
}
};
this._onTouchEnd = (event) => {
if (this._pointerInputHelper.isButtonDown() == false || this._touchEndCancel)
return;
const time = Date.now();
const clickCount = this._pointerInputHelper.onButtonUp(event.changedTouches[0], true, Button.Primary);
if (this._currentAction === InputType.Transform) {
this._transformEventNotify(event, InputState.Finished);
}
else if (this._currentAction !== InputType.Move) {
if (clickCount > 0)
this._pointerEventNotify(event, InputType.Click, clickCount);
}
else {
if (event.touches.length > 0)
return;
this._dragEventNotify(event, InputState.Finished);
}
this._resetState();
};
this._resetState = () => {
this._currentAction = null;
this._transformPoints = null;
this._clearLongTapTimeout();
};
this._clearLongTapTimeout = () => {
if (this._longTapTimeout != null)
clearTimeout(this._longTapTimeout);
};
this._onLongTap = (e) => {
this._pointerEventNotify(e, InputType.LongTap);
this._clearLongTapTimeout();
this._touchEndCancel = true;
};
this._pointerEventNotify = (e, type, clickCount = 0) => {
const data = this._getPointerArgs(e, type, clickCount);
this._emitEvent(data);
};
this._transformEventNotify = (e, state) => {
try {
const args = {
preventDefault: e.preventDefault,
scale: this._calculateScale(this._transformPoints[0], this._transformPoints[1], e.touches[0], e.touches[1]),
translate: this._calculateTransform(this._transformPoints[0], this._transformPoints[1], e.touches[0], e.touches[1]),
type: InputType.Transform,
state: state,
altKey: e.altKey,
ctrlKey: e.ctrlKey,
shiftKey: e.shiftKey,
metaKey: e.metaKey
};
this._emitEvent(args);
this._transformPoints = e.touches;
if (state !== InputState.Finished)
this._currentAction = InputType.Transform;
}
catch (ex) {
console.error(ex);
}
};
this._calculateScale = (oldPoint1, oldPoint2, newPoint1, newPoint2) => {
if (oldPoint1 == null || oldPoint2 == null || newPoint1 == null || newPoint2 == null)
return 1;
const oldDistance = oldPoint1.distance(oldPoint2);
const newDistance = newPoint1.distance(newPoint2);
if (newDistance <= this._settings.minimalScaleDistance)
return 1;
const scale = newDistance / oldDistance;
return isNaN(scale) ? 1 : scale;
};
this._calculateTransform = (oldPoint1, oldPoint2, newPoint1, newPoint2) => {
if (oldPoint1 == null || oldPoint2 == null || newPoint1 == null || newPoint2 == null)
return new PointF();
const oldRect = RectangleF.fromPoints(oldPoint1, oldPoint2);
const newRect = RectangleF.fromPoints(newPoint1, newPoint2);
const oldCenter = oldRect.center;
const newCenter = newRect.center;
return new PointF(newCenter.x - oldCenter.x, newCenter.y - oldCenter.y);
};
this._getPointerArgs = (e, type, clickCount = 0) => {
const firstPoint = this._getFirstCoordinate(e);
const workspaceCoords = this._convertor.pageToWorkspacePoint(firstPoint);
const buttonType = isNativeMouseEvent(e) ? e.button : Button.Primary;
const data = {
page: firstPoint,
workspace: workspaceCoords,
preventDefault: e.preventDefault,
type: type,
button: buttonType,
isMobile: !isNativeMouseEvent(e),
altKey: e.altKey,
ctrlKey: e.ctrlKey,
shiftKey: e.shiftKey,
metaKey: e.metaKey,
clickCount: clickCount
};
return data;
};
this._getFirstCoordinate = (e) => {
var _a;
return isNativeMouseEvent(e) ? e.coordinates : ((_a = e.touches[0]) !== null && _a !== void 0 ? _a : e.changedTouches[0]);
};
this._dragEventNotify = (e, state) => {
var _a, _b;
const data = this._getPointerArgs(e, InputType.Move);
const downPoint = new PointF((_a = this._pointerInputHelper.lastDownPoint) === null || _a === void 0 ? void 0 : _a.x, (_b = this._pointerInputHelper.lastDownPoint) === null || _b === void 0 ? void 0 : _b.y);
data.startPage = downPoint.clone();
data.startWorkspace = this._convertor.pageToWorkspacePoint(downPoint);
data.state = state;
this._emitEvent(data);
if (state !== InputState.Finished)
this._currentAction = InputType.Move;
};
this._onKeyDown = (e) => {
const state = this._keyMap.get(e.code);
if (this._pointerInputHelper.isButtonDown())
return;
if (state == null || state === InputState.Finished) {
this._keyMap.set(e.code, InputState.Started);
}
else {
this._keyMap.set(e.code, InputState.InProgress);
}
this._emitKeyEvent(e);
};
this._onKeyUp = (e) => {
this._keyMap.set(e.code, InputState.Finished);
this._emitKeyEvent(e);
};
this._emitKeyEvent = (e) => {
const params = {
altKey: e.altKey,
ctrlKey: e.ctrlKey,
code: e.code,
key: e.key,
preventDefault: e.preventDefault,
type: InputType.Key,
shiftKey: e.shiftKey,
metaKey: e.metaKey,
state: this._keyMap.get(e.code)
};
this._emitEvent(params);
};
this._onWheel = (e) => {
const args = {
altKey: e.altKey,
ctrlKey: e.ctrlKey,
delta: e.delta,
preventDefault: e.preventDefault,
shiftKey: e.shiftKey,
type: InputType.Wheel,
metaKey: e.metaKey
};
this._emitEvent(args);
};
this._emitEvent = (data) => {
InputManagerLogger.log(data);
this._inputEvent.notify(data);
};
this._inputEvent = new EventObject();
if (this._convertor == null)
this._convertor = { pageToWorkspacePoint: x => x };
const defaultSettings = {
clickThreshold: 4,
tapThreshold: 10,
doubleTapThreshold: 20,
doubleTapTime: 500,
longTapTime: 500,
minimalScaleDistance: 120
};
this._settings = Object.assign(Object.assign({}, defaultSettings), (settings || {}));
this._pointerInputHelper = new PointerInputHelper(this._settings);
}
raiseNativeEvent(event) {
switch (event.eventType) {
case NativeEventType.MouseDown:
this._onMouseDown(event);
break;
case NativeEventType.MouseMove:
this._onMouseMove(event);
break;
case NativeEventType.MouseUp:
this._onMouseUp(event);
break;
case NativeEventType.TouchStart:
const touchEvent = event;
this._onTouchStart(touchEvent);
break;
case NativeEventType.TouchMove:
this._onTouchMove(event);
break;
case NativeEventType.TouchEnd:
this._onTouchEnd(event);
break;
case NativeEventType.KeyDown:
this._onKeyDown(event);
break;
case NativeEventType.KeyUp:
this._onKeyUp(event);
break;
case NativeEventType.Wheel:
this._onWheel(event);
break;
}
}
addOnInput(handler) {
this._inputEvent.add(handler);
}
removeOnInput(handler) {
this._inputEvent.remove(handler);
}
dispose() { }
}
class InputManagerLogger {
static log(data) {
let message = `${LogClr.green(data.type.toString())} was performed!`;
switch (data.type) {
case InputType.Hover:
return;
case InputType.Click:
case InputType.LongTap:
case InputType.PointerDown:
let clickData = data;
message += ` ${LogClr.cyan(clickData.workspace.toString())}`;
message += ` with ${LogClr.green(clickData.button.toString())} button`;
message += ` clickCount: ${LogClr.cyan(clickData.clickCount.toString())}`;
break;
case InputType.Move:
let dragData = data;
message += ` From ${LogClr.cyan(dragData.startWorkspace.toString())}`;
message += ` to ${LogClr.cyan(dragData.workspace.toString())}.`;
message += ` State is ${dragData.state}.`;
break;
case InputType.Key:
let keyData = data;
message += ` Key code was ${keyData.code}`;
if (keyData.altKey)
message += ` with alt`;
if (keyData.ctrlKey)
message += ` with ctrl`;
message += `. State is ${keyData.state}.`;
break;
case InputType.Transform:
let transformParams = data;
message += ` Scale: ${LogClr.cyan(transformParams.scale.toFixed(2))}, translate: ${LogClr.cyan(transformParams.translate.toString())}`;
message += ` State is ${transformParams.state}.`;
break;
case InputType.Wheel:
let wheelParams = data;
message += ` Delta: ${wheelParams.delta.toString()}`;
break;
}
FrontEndLogger.debugLog(message, LogSource.InputManager);
}
}
//# sourceMappingURL=InputManager.js.map