improve touchscreen scrolling on carousel
All checks were successful
publish.yml / publish (push) Successful in 1m5s
All checks were successful
publish.yml / publish (push) Successful in 1m5s
This commit is contained in:
@@ -26,9 +26,12 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
||||
private currentAutoScrollSpeedPxPerSecond = 0;
|
||||
private targetAutoScrollSpeedPxPerSecond = 0;
|
||||
private isPausePendingStop = false;
|
||||
private isTouchInteracting = false;
|
||||
private isProgrammaticScrollUpdate = false;
|
||||
private readonly autoScrollSpeedPxPerSecond = 72;
|
||||
private readonly speedRampDurationMs = 420;
|
||||
private readonly speedStopThresholdPxPerSecond = 0.5;
|
||||
private readonly touchScrollResumeDelayMs = 1200;
|
||||
isAutoScrolling = false;
|
||||
showLeftFade = false;
|
||||
showRightFade = false;
|
||||
@@ -89,9 +92,34 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
onCarouselScroll(): void {
|
||||
if (this.isProgrammaticScrollUpdate) {
|
||||
this.isProgrammaticScrollUpdate = false;
|
||||
this.updateFadeState();
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep autoscroll from fighting touch/momentum scrolling on mobile.
|
||||
this.pauseAutoScrollImmediately();
|
||||
this.scheduleResume(this.touchScrollResumeDelayMs);
|
||||
this.updateFadeState();
|
||||
}
|
||||
|
||||
onTouchStart(): void {
|
||||
this.isTouchInteracting = true;
|
||||
this.clearScheduledResume();
|
||||
this.pauseAutoScrollImmediately();
|
||||
}
|
||||
|
||||
onTouchEnd(): void {
|
||||
this.isTouchInteracting = false;
|
||||
this.scheduleResume(this.touchScrollResumeDelayMs);
|
||||
}
|
||||
|
||||
onTouchCancel(): void {
|
||||
this.isTouchInteracting = false;
|
||||
this.scheduleResume(this.touchScrollResumeDelayMs);
|
||||
}
|
||||
|
||||
onHoverStart(): void {
|
||||
this.pauseAutoScroll();
|
||||
this.clearScheduledResume();
|
||||
@@ -118,6 +146,11 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
||||
}
|
||||
|
||||
resumeAutoScroll(): void {
|
||||
if (this.isTouchInteracting) {
|
||||
this.scheduleResume(this.touchScrollResumeDelayMs);
|
||||
return;
|
||||
}
|
||||
|
||||
this.isPausePendingStop = false;
|
||||
this.targetAutoScrollSpeedPxPerSecond = this.autoScrollSpeedPxPerSecond;
|
||||
this.syncAutoScrollState();
|
||||
@@ -242,6 +275,7 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
||||
// Normalize only when moving past the duplicated track boundary to avoid abrupt remaps on quick re-entry.
|
||||
this.virtualScrollLeft = nextVirtualScrollLeft >= loopWidth ? nextVirtualScrollLeft - loopWidth : nextVirtualScrollLeft;
|
||||
|
||||
this.isProgrammaticScrollUpdate = true;
|
||||
carousel.scrollLeft = this.virtualScrollLeft;
|
||||
}
|
||||
|
||||
@@ -277,5 +311,20 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
||||
this.targetAutoScrollSpeedPxPerSecond > this.speedStopThresholdPxPerSecond ||
|
||||
this.currentAutoScrollSpeedPxPerSecond > this.speedStopThresholdPxPerSecond;
|
||||
}
|
||||
|
||||
private pauseAutoScrollImmediately(): void {
|
||||
this.clearScheduledResume();
|
||||
|
||||
if (this.autoScrollFrameId !== null) {
|
||||
cancelAnimationFrame(this.autoScrollFrameId);
|
||||
this.autoScrollFrameId = null;
|
||||
}
|
||||
|
||||
this.isPausePendingStop = false;
|
||||
this.currentAutoScrollSpeedPxPerSecond = 0;
|
||||
this.targetAutoScrollSpeedPxPerSecond = 0;
|
||||
this.lastAutoScrollTime = 0;
|
||||
this.syncAutoScrollState();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user