mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2026-01-11 09:55:13 +08:00
fix(caret): caret not resetting position on quick restart (@nadalaba) (#7038)
- quick restarting immediately after some input makes the caret fail to reset its position sometimes. https://github.com/user-attachments/assets/d9e1def5-d8f6-4af2-845c-778c89279849 this happens because the reset of caret's position that should happen on the callback inside `requestAnimationFrame` in `caret.goTo()` (triggered in `TestUI.updateWordsWrapperClasses()`) is cancelled by a later call to `caret.goTo()` (triggered by `TestUI.focusWords()`). However the second call sets the position directly without stopping previous animation `$('#caret').stop().animate()`. As a result, the earlier animation (caused by last input) continues after the reset, if the restart was done fast enough. - update some previous comments.
This commit is contained in:
parent
42227666a8
commit
a0c9decc3f
2 changed files with 11 additions and 5 deletions
|
|
@ -286,6 +286,7 @@ export function restart(options = {} as RestartOptions): void {
|
|||
TimerProgress.hide();
|
||||
Replay.pauseReplay();
|
||||
TestState.setBailedOut(false);
|
||||
Caret.resetPosition();
|
||||
PaceCaret.reset();
|
||||
Monkey.hide();
|
||||
TestInput.input.setKoreanStatus(false);
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ export class Caret {
|
|||
top: number;
|
||||
width?: number;
|
||||
}): void {
|
||||
$(this.element).stop("pos", true, false);
|
||||
this.element.style.left = `${options.left}px`;
|
||||
this.element.style.top = `${options.top}px`;
|
||||
if (options.width !== undefined) {
|
||||
|
|
@ -143,6 +144,8 @@ export class Caret {
|
|||
}
|
||||
|
||||
public handleTapeWordsRemoved(widthRemoved: number): void {
|
||||
// Removing tape words reduces the absolute value of options.newValue passed to handleTapeScroll().
|
||||
// To keep the target marginLeft accurate, we reduce the absolute value of cumulative correction by the same amount.
|
||||
this.cumulativeTapeMarginCorrection += widthRemoved;
|
||||
}
|
||||
|
||||
|
|
@ -154,12 +157,14 @@ export class Caret {
|
|||
this.readyToResetMarginLeft = false;
|
||||
|
||||
/**
|
||||
* If we didn't reset marginLeft, then options.newValue gives the correct caret
|
||||
* position by adding up the widths of all typed characters. But since we reset
|
||||
* caret.style.marginLeft during the test, the caret ends up too far left.
|
||||
* options.newValue is the total width of all previously typed characters, and assuming we didn't
|
||||
* reset marginLeft or remove any tape words, then it would be the correct marginLeft to go to.
|
||||
*
|
||||
* To fix this, we track how much marginLeft we've reset so far (cumulativeTapeMarginCorrection),
|
||||
* and subtract it from options.newValue to get the correct newMarginLeft.
|
||||
* Each time marginLeft is reset, the distance between options.newValue and the current
|
||||
* marginLeft-after-reset increases, making the caret shift too much left (in LTR).
|
||||
*
|
||||
* To correct this, we decrease the new target marginLeft by how much we've
|
||||
* reset the margin so far (cumulativeTapeMarginCorrection).
|
||||
*/
|
||||
const newMarginLeft =
|
||||
options.newValue - this.cumulativeTapeMarginCorrection;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue