Skip to content

Instantly share code, notes, and snippets.

@hatsumatsu
Last active May 18, 2024 19:24
Show Gist options
  • Save hatsumatsu/39f5d91d282f607fea6159bf5d6795e6 to your computer and use it in GitHub Desktop.
Save hatsumatsu/39f5d91d282f607fea6159bf5d6795e6 to your computer and use it in GitHub Desktop.
function easeOutQuart(x) {
return 1 - Math.pow(1 - x, 4);
}
function easeInQuart(x) {
return x * x * x * x;
}
function easeInOutQuart(x) {
return x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2;
}
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
class AutoScroll {
constructor() {
this.frame = null;
this.speed = 1;
this.isActive = false;
this.isNatural = false;
this.showNotice();
window.addEventListener('keyup', (event) => {
if (event.key === '0') this.speed = 0.5;
if (event.key === '1') this.speed = 1;
if (event.key === '2') this.speed = 2;
if (event.key === '3') this.speed = 4;
if (event.key === '4') this.speed = 8;
if (event.key === '5') this.speed = 12;
if (event.key === '6') this.speed = 16;
if (event.key === '7') this.speed = 20;
if (event.key === '8') this.speed = 24;
if (event.key === '9') this.speed = 28;
if (event.key === 'n') this.isNatural = !this.isNatural;
if (event.key === '#') {
if (this.isActive) {
this.stop();
} else {
this.start();
}
}
});
}
// (((Math.sin(time * 0.002) + 1) / 2 + 0.1) / 1.1) * this.speed * 4
onFrame(time) {
let offset = this.speed;
if (this.isNatural) {
const cycleProgress = (time % 2500) / 2500;
const threshold = 0.1;
offset =
0 +
(cycleProgress < threshold
? easeInOutQuart(cycleProgress / threshold) * this.speed * 2
: (1 -
easeInOutQuart((cycleProgress - threshold) / (1 - threshold))) *
this.speed *
2);
}
document.scrollingElement.scrollTo({
top: document.scrollingElement.scrollTop + offset,
behavior: 'instant'
});
this.frame = requestAnimationFrame((time) => {
this.onFrame(time);
});
}
start() {
this.isActive = true;
this.frame = requestAnimationFrame((time) => {
this.onFrame(time);
});
}
stop() {
cancelAnimationFrame(this.frame);
this.isActive = false;
}
showNotice() {
const notice = document.createElement('div');
notice.textContent = 'AutoScroll is ready. Toggle with #';
notice.style.position = 'fixed';
notice.style.right = '10px';
notice.style.top = '10px';
notice.style.zIndex = '9000';
notice.style.margin = '10px';
notice.style.padding = '2px 8px';
notice.style.fontFamily = 'sans-serif';
notice.style.fontSize = '14px';
notice.style.lineHeight = '1.1';
notice.style.background = '#222';
notice.style.borderRadius = '2px';
notice.style.color = '#fff';
document.body.appendChild(notice);
setTimeout(() => {
notice.remove();
}, 4000);
}
}
if (!window.AutoScroll) window.AutoScroll = new AutoScroll();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment