From 9384f5399da39e53855beb8e7f8ded1aa56bf72e Mon Sep 17 00:00:00 2001 From: syuilo Date: Tue, 27 Dec 2022 14:36:33 +0900 Subject: rename: client -> frontend --- packages/frontend/src/scripts/sticky-sidebar.ts | 50 +++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 packages/frontend/src/scripts/sticky-sidebar.ts (limited to 'packages/frontend/src/scripts/sticky-sidebar.ts') diff --git a/packages/frontend/src/scripts/sticky-sidebar.ts b/packages/frontend/src/scripts/sticky-sidebar.ts new file mode 100644 index 0000000000..c67b8f37ac --- /dev/null +++ b/packages/frontend/src/scripts/sticky-sidebar.ts @@ -0,0 +1,50 @@ +export class StickySidebar { + private lastScrollTop = 0; + private container: HTMLElement; + private el: HTMLElement; + private spacer: HTMLElement; + private marginTop: number; + private isTop = false; + private isBottom = false; + private offsetTop: number; + private globalHeaderHeight: number = 59; + + constructor(container: StickySidebar['container'], marginTop = 0, globalHeaderHeight = 0) { + this.container = container; + this.el = this.container.children[0] as HTMLElement; + this.el.style.position = 'sticky'; + this.spacer = document.createElement('div'); + this.container.prepend(this.spacer); + this.marginTop = marginTop; + this.offsetTop = this.container.getBoundingClientRect().top; + this.globalHeaderHeight = globalHeaderHeight; + } + + public calc(scrollTop: number) { + if (scrollTop > this.lastScrollTop) { // downscroll + const overflow = Math.max(0, this.globalHeaderHeight + (this.el.clientHeight + this.marginTop) - window.innerHeight); + this.el.style.bottom = null; + this.el.style.top = `${-overflow + this.marginTop + this.globalHeaderHeight}px`; + + this.isBottom = (scrollTop + window.innerHeight) >= (this.el.offsetTop + this.el.clientHeight); + + if (this.isTop) { + this.isTop = false; + this.spacer.style.marginTop = `${Math.max(0, this.globalHeaderHeight + this.lastScrollTop + this.marginTop - this.offsetTop)}px`; + } + } else { // upscroll + const overflow = this.globalHeaderHeight + (this.el.clientHeight + this.marginTop) - window.innerHeight; + this.el.style.top = null; + this.el.style.bottom = `${-overflow}px`; + + this.isTop = scrollTop + this.marginTop + this.globalHeaderHeight <= this.el.offsetTop; + + if (this.isBottom) { + this.isBottom = false; + this.spacer.style.marginTop = `${this.globalHeaderHeight + this.lastScrollTop + this.marginTop - this.offsetTop - overflow}px`; + } + } + + this.lastScrollTop = scrollTop <= 0 ? 0 : scrollTop; + } +} -- cgit v1.2.3-freya