@learn-hunger/visual-gestures
Version:
VisualGestures.js is a package that empowers users to effortlessly control the cursor, including actions such as hover, click, drag, and drop, through precise finger movements in the air.
202 lines (201 loc) • 12.3 kB
TypeScript
import { IGestureCustomProps } from "../utilities/vg-types";
import { INormalizedLandmark } from "../utilities/vg-types-handlandmarks";
import { VgHandLandmarksDTO } from "./DTO/vg-handlandmark";
import { AVgPointerEvents } from "./abstracts/vg-pointer-events";
/**
* Central Class to store states of the hand landmarks
* handles triggering events
* Core logic for hand gestures is maintained here
*/
export declare class VgPointer extends AVgPointerEvents {
distance2D: number;
distance3D: number;
relativeDist2D: number;
mouseInit: MouseEventInit;
props: IGestureCustomProps;
structuredLandmarks: VgHandLandmarksDTO;
mouseDown: boolean;
upElement: HTMLElement;
palmHeight?: number;
fingerHeight?: number;
fingerKinkRatio: number;
/***
* stateID: Flagging variable indicates the current event being performed
* If stateID==0 then move event
* else if stateID==1 then down event
* else if stateID==2 then up event
* else if stateID==3 then drag event
* else if stateID==4 them drag+up= drop event
*/
stateID?: number;
decaWindowPointer?: number;
/**
* decaWindow: Window contains history 'fingerKinkRatio'
* initialized with array of null values
* length is set to five to achieve optimal results
*/
decaWindow: [
number | null,
number | null,
number | null,
number | null,
number | null
];
/**
* tipWindow: Window contains history 'INormalizedLandmark' of TIP of INDEX finger
* initialized with array of null values
* length is set to five to achieve optimal results
*/
tipWindow: [
INormalizedLandmark | null,
INormalizedLandmark | null,
INormalizedLandmark | null,
INormalizedLandmark | null,
INormalizedLandmark | null
];
/**
* motionWindow: Window contains 'INormalizedLandmark' of MCP of INDEX finger
* initialized with array of null values
* 0th index contains the significant past 'INormalizedLandmark'
* 1th index contains the current 'INormalizedLandmark'
*/
motionWindow: [INormalizedLandmark | null, INormalizedLandmark | null];
constructor();
set setElement(element: Element);
private get getProps();
updateProps(mouseProp: MouseEventInit, customProps: IGestureCustomProps): void;
trigger(): void;
private kinkLogic;
/**
* Signature : pseudoDown()
* Description : Used to check whether the mouse(cursor) is in 'down' state at current instance of time
* _____________________________________________________________________________________
* ALGORITHM
* _____________________________________________________________________________________
* If 'structuredLandmarks' are correctly detected, 'fingerKinkRatio' is calculated, and current 'stateID == 0' (onmousemove event)
* * If 'decaWindow[0]' (fingerKinkRatio of previous frame) is calculated and significant decrement (magnitude= 200) in 'fingerKinkRatio' is observed
* * * Store current 'fingerKinkRatio' at 'decaWindow[1]' [ decaWindow[0], decaWindow[1] attains hibernation ]
* * * Nullify decaWindow after 1th-index [ decaWIndow[2], decaWindow[3], decaWindow[4] are set to implement sliding window ]
* * * Store current TIP of INDEX finger at 'tipWindow[1]' [ tipWindow[0], tipWindow[1] attains hibernation ]
* * * Nullify tipWindow after 1th-index [ tipWindow[2], tipWindow[3], tipWindow[4] are set to implement sliding window ]
* * * Set the 'decaWindowPointer' to '1' indicating the index where 'onmousedown' event is triggered
* * * Set stateID to '1' representing 'onmousedown' operation is triggered
* * * Set 'motionWindow[0]' with INormalizedLandmark of INDEX.MCP at instance where down operation is triggered
* * * Call 'triggerMouseDown' event at 'tipWindow[0]' which contains INormalizedLandmark which corresponds to the starting(initial) coordinates from where 'onmousedown' event is started
* * * Nullify 'motionWindow[0]' to hold the successive INormalizedLandmarks of INDEX.MCP
* * * 'true' is returned indicating mouse is down at the current instance of time
* * Else
* * * If 'decaWindow' is not completely filled
* * * * Increment decaWindowPointer by 1
* * * * Append current 'fingerKinkRatio' to 'decaWindow'
* * * * Append current INDEX.TIP to 'tipWindow'
* * * Else
* * * * Shift-left all values of 'decaWindow' to immediate preceeding index [ Sliding Operation ]
* * * * Update 'decaWindow[4]' with current 'fingerKinkRatio'
* * * * Shift-left all values of 'tipWindow' to immediate preceeding index [ Sliding Operation ]
* * * * Update 'tipWindow[4]' with current INDEX.TIP
* * * Set 'motionWindow[0]' with current 'INormalizedLandmark' of INDEX.MCP
* * * Nullify 'motionWindow[1]' as current event being performed is 'onmousedown'
* * * 'false' is returned indicating mouse is not down at the current instance of time
* Else
* * 'false' is returned indicating mouse is not down at the current instance of time
*/
private pseudoDown;
/**
* Signature : pseudoUp()
* Description : Used to check whether the mouse(cursor) is in 'up' state at current instance of time
* _____________________________________________________________________________________
* ALGORITHM
* _____________________________________________________________________________________
* If current state of cusor is 'onmousedown'(stateID == 1) or 'onmousedrag'(stateID == 3)
* * Update the motionWindow[1] with current INDEX.MCP to track movement of hand from initial position (position at which 'pseudoDown()' is triggered)
* * If significant increment (>=200) in 'fingerKinkRatio' is observed
* * * If previous operation is 'drag'(stateID=3)
* * * * Set 'stateID = 4' representing 'onmousedrop' event
* * * Else (if previous operation is 'down'[stateID=1])
* * * * Set 'stateID = 2' representing 'onmouseup' event
* * Else
* * * If 'decaWindow' is completely filled using 'decaWindowPointer'
* * * * Increment 'decaWindowPointer' by 1
* * * * Append current 'fingerKinkRatio' to 'decaWindow'
* * * * Append current INDEX.TIP to 'tipWindow'
* * * * Update the motionWindow[1] with current INDEX.MCP to track movement of hand from initial position (position at which 'pseudoDown()' is triggered)
* * * Else if 'decaWindow' is completely filled
* * * * Take copy of values of 'decaWindow' into variables
* * * * Update the 'decaWindow' shifting one-index left
* * * * Update 'decaWindow[4]' with current 'fingerKinkRatio'
* * * * Take copy of values of 'tipWindow' into variables
* * * * Update the 'tipWindow' shifting one-index left
* * * * Update 'tipWindow[4]' with current INDEX.TIP
* * * If current event is 'onmousedrag' ('stateID == 3')
* * * * Call 'triggerMouseMove' event (corresponds to onmousemove in traditional mouse-based controls)
* 'false' is returned indicating mouse is not up at the current instance of time
*/
private pseudoUp;
/**
* Signature : pseudoClick()
* Description : Used to check whether the mouse(cursor) is in 'click' state at current instance of time
* _____________________________________________________________________________________
* ALGORITHM
* _____________________________________________________________________________________
* If ( (current state of cursor is 'onmouseup' ('stateID == 2') and significant hand movement is not observed) or
* (current state of cursor is 'onmousedrop' ('stateID == 4') and significant hand movement is not observed) )
* * Call 'triggerMouseUp' event (corresponds to 'onmouseup' in traditional mouse-based controls)
* * Call 'triggerMouseClick' event (corresponds to 'onmouseclick' in traditional mouse-based controls)
* * Update 'decaWindow[0]' with current 'fingerKinkRatio' at the instance where 'pseudoClick()' ('onmouseclick') operation is triggered
* * Nullify entire 'decaWindow' after 0th- index
* * Update 'tipWindow[0]' with current INDEX.TIP at the instance where 'pseudoClick()' ('onmouseclick') operation is triggered
* * Nullify entire 'tipWindow' after 0th-index
* * Set 'decaWindowPointer' pointing to '0'th-index
* * Update 'motionWindow[0]' with 'INormalizedLandmark' of current INDEX.MCP
* * Nullify 'motionWindow[1]' to hold the successive 'INormalizedLandmarks' of INDEX.MCP
* * Update stateID to '0' denoting 'onmousemove' as the current event as 'pseudoClick()' ('onmouseclick') operation is completed
* * 'true' is returned indicating mouse is clicked at the current instance of time
* 'false' is returned indicating mouse is not clicked at the current instance of time
*/
private pseudoClick;
/**
* Signature : pseudoDrag()
* Description : Used to check whether the mouse(cursor) is in 'drag' state at current instance of time
* _____________________________________________________________________________________
* ALGORITHM
* _____________________________________________________________________________________
* If ( current event is 'pseudoDown()' ('stateID == 1') and
* significant hand movement is observed ('weightedEuclideanDistance' between 'motionWindow[0]' and 'motionWindow[1]' is greater than '0.08') )
* * Set 'stateID' to '3' indicating 'onmousedrag' ('pseudoDrag') operation is triggered at the current instance of time
* * 'true' is returned indicating mouse is dragged at the current instance of time
* 'false' is returned indicating mouse is not dragged at the current instance of time
*/
private pseudoDrag;
/**
* Signature : pseudoDrop()
* Description : Used to check whether the mouse(cursor) is in 'drop' state at current instance of time
* _____________________________________________________________________________________
* ALGORITHM
* _____________________________________________________________________________________
* If
* ( current event is 'pseudoDrop()' ('stateID == 4') and significant hand movement is observed ('weightedEuclideanDistance' between 'motionWindow[0]' and 'motionWindow[1]' is greater than '0.08') ) or
* ( current event is 'pseudoUp()' ('stateID == 2') and significant hand movement is observed ('weightedEuclideanDistance' between 'motionWindow[0]' and 'motionWindow[1]' is greater than '0.08') )
* * Call 'triggerMouseDrop' event (corresponds to 'onmousedrop' in traditional mouse-based controls)
* * Update 'decaWindow[0]' with current 'fingerKinkRatio' at the instance where 'pseudoDrop()' operation is triggered
* * Nullify entire 'decaWindow' after 0th- index
* * Update 'tipWindow[0]' with INDEX.TIP at the instance where 'pseudoDrop()' operation is triggered
* * Nullify entire 'tipWindow' after 0th- index
* * Set 'decaWindowPointer' to '0' indicating current state is 'onmousemove' as 'onmousedrop' ('pseudoDrop()') event has completed at the current instance of time
* * Set 'motionWindow[0]' with current 'INormalizedLandmark' of INDEX.MCP
* * Nullify 'motionWindow[1]' as current event being performed is 'onmousedrop' and to hold the successive 'INormalizedLandmarks' of INDEX.MCP
* * Set 'stateID' to '0' representing 'onmousemove' operation is triggered as 'onmousedrop' event is completed at the current instance of time
* * 'true' is returned indicating mouse is dropped at the current instance of time
* 'false' is returned indicating mouse is not dropped at the current instance of time
*/
private pseudoDrop;
private staticEventsInitialiser;
/**
* Reset all sliding windows (decaWindow, tipWindow, motionWindow),
* pointer (decaWindowPointer), and
* flag (stateID)
* if hand landmarks are not detected
*/
resetStatesOnNoLandmarks(): void;
private getElement;
}