Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix floating point scrollLeft bug #55

Merged
merged 2 commits into from
Jul 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions client/components/RepeatingList/RepeatingList.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ class RepeatingList extends HTMLElement {
* @type {number}
*/
#lastKnownMouseX = -1;
/**
* scrollLeft cannot take fractional values in some browsers, so we store the next scrollLeft value here and
* attempt to add it's non-fractional value to the actual scrollLeft value every frame. E.g., if this value
* is 4.25, then on the next frame, 4 will be added to scrollLeft and this will be set back to 0.25.
* @type {number}
*/
#nextScrollLeft = 0;

constructor() {
super();
Expand All @@ -45,10 +52,6 @@ class RepeatingList extends HTMLElement {
requestAnimationFrame(this.render.bind(this));
}

attributeChangedCallback() {
this.setup();
}

/**
* Get the speed attribute, or the default if one wasn't provided.
* @returns {number} The parsed float value of the data-speed attribute, or the default of 1 if one wasn't provided.
Expand Down Expand Up @@ -120,7 +123,7 @@ class RepeatingList extends HTMLElement {
!this.matches(":active") &&
this.#lastRenderTimestamp !== null
) {
this.scrollLeft += normalScrollSpeed;
this.#nextScrollLeft += normalScrollSpeed;
} else {
// Scroll manually if the user is hovering
const leftPos = this.getBoundingClientRect().left;
Expand Down Expand Up @@ -148,12 +151,18 @@ class RepeatingList extends HTMLElement {
)) *
3;
if (this.#lastKnownMouseX < centerPos) {
this.scrollLeft -= adjustedScrollSpeed;
this.#nextScrollLeft -= adjustedScrollSpeed;
} else {
this.scrollLeft += adjustedScrollSpeed;
this.#nextScrollLeft += adjustedScrollSpeed;
}
}

// Once we've reached at least one full pixel, scroll by that pixel(s) and then remove it from the next scroll.
if (Math.abs(this.#nextScrollLeft) >= 1) {
this.scrollLeft += Math.trunc(this.#nextScrollLeft);
this.#nextScrollLeft = this.#nextScrollLeft % 1;
}

// If we've made a full loop by reaching the second instance of the first element,
// go back to the front of the list.
if (this.scrollLeft >= this.#firstElementInstances[1]?.offsetLeft) {
Expand Down
12 changes: 6 additions & 6 deletions client/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.