improve hover performance
All checks were successful
publish.yml / publish (push) Successful in 1m6s
All checks were successful
publish.yml / publish (push) Successful in 1m6s
This commit is contained in:
@@ -30,7 +30,6 @@
|
|||||||
border: 1px solid #30363d;
|
border: 1px solid #30363d;
|
||||||
border-radius: 18px;
|
border-radius: 18px;
|
||||||
background: rgba(22, 27, 34, 0.75);
|
background: rgba(22, 27, 34, 0.75);
|
||||||
backdrop-filter: blur(9px);
|
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
transition:
|
transition:
|
||||||
top 260ms ease,
|
top 260ms ease,
|
||||||
|
|||||||
@@ -37,35 +37,9 @@ h2 {
|
|||||||
|
|
||||||
.stack-carousel-column {
|
.stack-carousel-column {
|
||||||
position: relative;
|
position: relative;
|
||||||
--left-fade-size: 0px;
|
|
||||||
--right-fade-size: 0px;
|
|
||||||
width: calc(100% - (var(--carousel-nav-space) * 2));
|
width: calc(100% - (var(--carousel-nav-space) * 2));
|
||||||
margin-inline: auto;
|
margin-inline: auto;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
-webkit-mask-image: linear-gradient(
|
|
||||||
to right,
|
|
||||||
transparent 0,
|
|
||||||
#000 var(--left-fade-size),
|
|
||||||
#000 calc(100% - var(--right-fade-size)),
|
|
||||||
transparent 100%
|
|
||||||
);
|
|
||||||
mask-image: linear-gradient(
|
|
||||||
to right,
|
|
||||||
transparent 0,
|
|
||||||
#000 var(--left-fade-size),
|
|
||||||
#000 calc(100% - var(--right-fade-size)),
|
|
||||||
transparent 100%
|
|
||||||
);
|
|
||||||
-webkit-mask-repeat: no-repeat;
|
|
||||||
mask-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stack-carousel-column.has-left-fade {
|
|
||||||
--left-fade-size: var(--carousel-edge-fade-size);
|
|
||||||
}
|
|
||||||
|
|
||||||
.stack-carousel-column.has-right-fade {
|
|
||||||
--right-fade-size: var(--carousel-edge-fade-size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.stack-carousel {
|
.stack-carousel {
|
||||||
@@ -118,8 +92,7 @@ h2 {
|
|||||||
height: 1.2rem;
|
height: 1.2rem;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
opacity: 0.92;
|
opacity: 0.92;
|
||||||
filter: grayscale(1) brightness(1.25) contrast(0.92);
|
transition: transform 140ms ease, opacity 140ms ease;
|
||||||
transition: transform 140ms ease, opacity 140ms ease, filter 140ms ease;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.skill-fallback {
|
.skill-fallback {
|
||||||
@@ -159,7 +132,6 @@ h2 {
|
|||||||
.stack-slide:focus-within .skill-logo {
|
.stack-slide:focus-within .skill-logo {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scale(1.04);
|
transform: scale(1.04);
|
||||||
filter: grayscale(1) brightness(1.4) contrast(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-btn {
|
.carousel-btn {
|
||||||
|
|||||||
@@ -30,11 +30,13 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
|||||||
private isPausePendingStop = false;
|
private isPausePendingStop = false;
|
||||||
private isTouchInteracting = false;
|
private isTouchInteracting = false;
|
||||||
private isProgrammaticScrollUpdate = false;
|
private isProgrammaticScrollUpdate = false;
|
||||||
private readonly autoScrollSpeedPxPerSecond = 72;
|
private lastFadeStateUpdateTime = 0;
|
||||||
|
private readonly autoScrollSpeedPxPerSecond = 48;
|
||||||
private readonly speedRampDurationMs = 420;
|
private readonly speedRampDurationMs = 420;
|
||||||
private readonly speedStopThresholdPxPerSecond = 0.5;
|
private readonly speedStopThresholdPxPerSecond = 0.5;
|
||||||
private readonly touchScrollResumeDelayMs = 1200;
|
private readonly touchScrollResumeDelayMs = 1200;
|
||||||
private readonly hoverPauseDelayMs = 300;
|
private readonly hoverPauseDelayMs = 300;
|
||||||
|
private readonly fadeUpdateIntervalMs = 96;
|
||||||
isAutoScrolling = false;
|
isAutoScrolling = false;
|
||||||
showLeftFade = false;
|
showLeftFade = false;
|
||||||
showRightFade = false;
|
showRightFade = false;
|
||||||
@@ -71,6 +73,8 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
|||||||
this.updateFadeState();
|
this.updateFadeState();
|
||||||
this.resumeAutoScroll();
|
this.resumeAutoScroll();
|
||||||
}, 0);
|
}, 0);
|
||||||
|
|
||||||
|
document.addEventListener('visibilitychange', this.onVisibilityChange);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
@@ -82,6 +86,7 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
|||||||
this.clearScheduledResume();
|
this.clearScheduledResume();
|
||||||
this.clearScheduledHoverPause();
|
this.clearScheduledHoverPause();
|
||||||
this.pauseAutoScroll();
|
this.pauseAutoScroll();
|
||||||
|
document.removeEventListener('visibilitychange', this.onVisibilityChange);
|
||||||
this.isAutoScrolling = false;
|
this.isAutoScrolling = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,6 +173,10 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
resumeAutoScroll(): void {
|
resumeAutoScroll(): void {
|
||||||
|
if (document.hidden) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.isTouchInteracting) {
|
if (this.isTouchInteracting) {
|
||||||
this.scheduleResume(this.touchScrollResumeDelayMs);
|
this.scheduleResume(this.touchScrollResumeDelayMs);
|
||||||
return;
|
return;
|
||||||
@@ -208,7 +217,11 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
|||||||
this.autoAdvanceStack(carousel, deltaMs, this.currentAutoScrollSpeedPxPerSecond);
|
this.autoAdvanceStack(carousel, deltaMs, this.currentAutoScrollSpeedPxPerSecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (timestamp - this.lastFadeStateUpdateTime >= this.fadeUpdateIntervalMs) {
|
||||||
this.updateFadeState(carousel);
|
this.updateFadeState(carousel);
|
||||||
|
this.lastFadeStateUpdateTime = timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
this.syncAutoScrollState();
|
this.syncAutoScrollState();
|
||||||
|
|
||||||
if (this.isPausePendingStop && this.currentAutoScrollSpeedPxPerSecond <= this.speedStopThresholdPxPerSecond) {
|
if (this.isPausePendingStop && this.currentAutoScrollSpeedPxPerSecond <= this.speedStopThresholdPxPerSecond) {
|
||||||
@@ -353,7 +366,17 @@ export class TechStackCarousel implements AfterViewInit, OnDestroy {
|
|||||||
this.currentAutoScrollSpeedPxPerSecond = 0;
|
this.currentAutoScrollSpeedPxPerSecond = 0;
|
||||||
this.targetAutoScrollSpeedPxPerSecond = 0;
|
this.targetAutoScrollSpeedPxPerSecond = 0;
|
||||||
this.lastAutoScrollTime = 0;
|
this.lastAutoScrollTime = 0;
|
||||||
|
this.lastFadeStateUpdateTime = 0;
|
||||||
this.syncAutoScrollState();
|
this.syncAutoScrollState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly onVisibilityChange = (): void => {
|
||||||
|
if (document.hidden) {
|
||||||
|
this.pauseAutoScrollImmediately();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.scheduleResume(320);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user