| export function nextTypeDelay(target: string, currentLength: number, streamRate: number) { |
| const nextChar = target[currentLength] ?? '' |
| const backlog = target.length - currentLength |
| const targetCharsPerSecond = resolveTypingCharsPerSecond(backlog, streamRate) |
| if (!nextChar) { |
| return 18 |
| } |
|
|
| if (nextChar === '\n') { |
| return 1000 / Math.max(targetCharsPerSecond * 1.4, 1) |
| } |
|
|
| if (/[,。!?;:,.!?;:]/.test(nextChar)) { |
| return Math.max(24, 1000 / Math.max(targetCharsPerSecond * 0.55, 1)) |
| } |
|
|
| if (/\s/.test(nextChar)) { |
| return Math.max(10, 1000 / Math.max(targetCharsPerSecond * 1.25, 1)) |
| } |
|
|
| return Math.max(12, 1000 / Math.max(targetCharsPerSecond, 1)) |
| } |
|
|
| export function nextTypeStep(backlog: number) { |
| if (backlog >= 28) { |
| return 3 |
| } |
|
|
| if (backlog >= 16) { |
| return 2 |
| } |
|
|
| return 1 |
| } |
|
|
| function resolveTypingCharsPerSecond(backlog: number, streamRate: number) { |
| const minCharsPerSecond = 10 |
| const maxCharsPerSecond = 26 |
| const adaptiveBase = streamRate > 0 ? streamRate * 0.55 + 6 : minCharsPerSecond |
|
|
| if (backlog >= 10) { |
| return clamp(adaptiveBase, 12, maxCharsPerSecond) |
| } |
|
|
| return clamp(adaptiveBase, minCharsPerSecond, 18) |
| } |
|
|
| function clamp(value: number, min: number, max: number) { |
| return Math.min(max, Math.max(min, value)) |
| } |
|
|
| export function shouldRedirectKeyToInput(event: KeyboardEvent): boolean { |
| return event.key.length === 1 || event.key === 'Backspace' |
| } |
|
|