Created
December 4, 2021 03:29
-
-
Save dimitropoulos/227c0cfd502d5e537675ae329644519e to your computer and use it in GitHub Desktop.
typing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const enum Finger { | |
LeftPinky = 1, | |
LeftRing = 2, | |
LeftMiddle = 3, | |
LeftIndex = 4, | |
Thumb = 5, | |
RightIndex = 6, | |
RightMiddle = 7, | |
RightRing = 8, | |
RightPinky = 9, | |
} | |
const isolatedKeystroke: Record<string, Finger> = { | |
'`': Finger.LeftPinky, | |
'1': Finger.LeftPinky, | |
// eslint-disable-next-line no-tabs -- it boggles my mind that this rule doesn't allow this... | |
' ': Finger.LeftPinky, | |
q: Finger.LeftPinky, | |
a: Finger.LeftPinky, | |
z: Finger.LeftPinky, | |
'2': Finger.LeftRing, | |
w: Finger.LeftRing, | |
s: Finger.LeftRing, | |
x: Finger.LeftRing, | |
'3': Finger.LeftMiddle, | |
e: Finger.LeftMiddle, | |
d: Finger.LeftMiddle, | |
c: Finger.LeftMiddle, | |
'4': Finger.LeftIndex, | |
r: Finger.LeftIndex, | |
f: Finger.LeftIndex, | |
v: Finger.LeftIndex, | |
'5': Finger.LeftIndex, | |
t: Finger.LeftIndex, | |
g: Finger.LeftIndex, | |
b: Finger.LeftIndex, | |
' ': Finger.Thumb, | |
'6': Finger.RightIndex, | |
y: Finger.RightIndex, | |
h: Finger.RightIndex, | |
n: Finger.RightIndex, | |
'7': Finger.RightIndex, | |
u: Finger.RightIndex, | |
j: Finger.RightIndex, | |
m: Finger.RightIndex, | |
'8': Finger.RightMiddle, | |
i: Finger.RightMiddle, | |
k: Finger.RightMiddle, | |
',': Finger.RightMiddle, | |
'9': Finger.RightRing, | |
o: Finger.RightRing, | |
l: Finger.RightRing, | |
'.': Finger.RightRing, | |
'0': Finger.RightPinky, | |
p: Finger.RightPinky, | |
';': Finger.RightPinky, | |
'/': Finger.RightPinky, | |
'-': Finger.RightPinky, | |
'[': Finger.RightPinky, | |
"'": Finger.RightPinky, | |
'=': Finger.RightPinky, | |
']': Finger.RightPinky, | |
'\\': Finger.RightPinky, | |
'\n': Finger.RightPinky, // Enter | |
}; | |
const requiresShiftKey = (character: string) => isolatedKeystroke[character] === undefined; | |
/** | |
* If the previous character had to be typed by the same hand there's a bit of an added time tax to pay because it takes time to physically | |
*/ | |
const sequentialKeysSameFinger = (character: string, previousCharacter: string) => ( | |
isolatedKeystroke[character] === isolatedKeystroke[previousCharacter] | |
); | |
/** | |
* If the previous character matches, we want to go faster. | |
* | |
* Consider the situation of multiple spaces for indenting, multiple sequential line returns, or words with repeated characters (e.g. "llama"). In these situations it's natural that someone would type the repeated character much faster. | |
*/ | |
const isDoubleKeypress = (character: string, previousCharacter: string) => ( | |
character === previousCharacter | |
); | |
const hardcodedDelays: Record<string, number | undefined> = { | |
' ': 4, | |
'\n': 8, | |
';': 5, | |
'=': 2, | |
'>': 3, | |
'(': 3, | |
')': 2, | |
'{': 2, | |
'}': 3, | |
'.': 6, | |
}; | |
/** give an extra little randomness to the typing */ | |
const getJitter = () => { | |
const min = 100; | |
const max = 150; // so, up to 50% randomness | |
const result = Math.floor(min + (Math.random() * (max + 1 - min))); | |
return result / 100; | |
}; | |
export const getDelayMultiplier = (character: string, previousCharacter: string) => { | |
if (isDoubleKeypress(character, previousCharacter)) { | |
return 2; | |
} | |
const hardcodedDelayMultiplier = hardcodedDelays[character]; | |
if (hardcodedDelayMultiplier !== undefined) { | |
return hardcodedDelayMultiplier; | |
} | |
if (requiresShiftKey(character)) { | |
return 3; | |
} | |
if (sequentialKeysSameFinger(character, previousCharacter)) { | |
return 3; | |
} | |
return 1; | |
}; | |
export const getWaitTime = (milliseconds: number) => (character: string, previousCharacter: string) => { | |
const jitter = getJitter(); | |
const delayMultiplier = getDelayMultiplier(character, previousCharacter); | |
return milliseconds * delayMultiplier * jitter; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment