I am having trouble getting a smooth scroll service to work in angular 2. Are there any services for smooth scrolling, or plain anchor scrolling, that might work until the
Thanks to the accepted answer I was able to implement a smooth "scroll to top". Scrolling to the top is actually even easier than scrolling to a particular target element since we are scrolling to the 0-position always. Here is the code:
scrollTo(yPoint: number, duration: number) {
setTimeout(() => {
window.scrollTo(0, yPoint)
}, duration);
return;
}
smoothScrollToTop() {
let startY = this.currentYPosition();
let stopY = 0; // window top
let distance = stopY > startY ? stopY - startY : startY - stopY;
if (distance < 100) {
window.scrollTo(0, stopY);
return;
}
let speed = Math.round(distance / 100);
let step = speed;
speed = Math.max(9, speed); //min 9 otherwise it won't look smooth
let leapY = stopY > startY ? startY + step : startY - step;
let timer = 0;
if (stopY > startY) {
for (let i = startY; i < stopY; i += step) {
// since setTimeout is asynchronous, the for-loop will will fire all scrolls
// nearly simoultaniously. Therefore, we need to multiply the speed with
// a counter which lets the scrolls start with a growing offset which lets the
// setTimeout wait for a growing time till it scrolls there
// that way, we prevent the window to scroll instantly to the target Yposition
this.scrollTo(leapY, timer * speed);
leapY += step; if (leapY > stopY) leapY = stopY; timer++;
}
return;
} else {
for (let i = startY; i > stopY; i -= step) {
this.scrollTo(leapY, timer * speed);
leapY -= step; if (leapY < stopY) leapY = stopY; timer++;
}
}
}
currentYPosition() {
// Firefox, Chrome, Opera, Safari
if (self.pageYOffset) return self.pageYOffset;
// Internet Explorer 6 - standards mode
if (document.documentElement && document.documentElement.scrollTop)
return document.documentElement.scrollTop;
// Internet Explorer 6, 7 and 8
if (document.body.scrollTop) return document.body.scrollTop;
return 0;
}
If you want, you can let your "Scroll-To-Top" button appear dynamically when user scrolls:
@HostListener('window:scroll', ['$event'])
onWindowScroll(event) {
this.onScrollFadeInOutScrollToTopButton();
}
shouldShowScrollToTop: boolean = false;
onScrollFadeInOutScrollToTopButton() {
this.shouldShowScrollToTop = (window.pageYOffset >= window.screen.height/2);
}
And the HTML for the Scroll-to-top Button:
As you can see, that button also has an animation trigger. You can think about using an icon for the button and ideally, your button should have a position:fixed; style.