feat(dees-pdf-viewer): improve scrolling behavior and styles for better user experience
This commit is contained in:
@@ -528,10 +528,16 @@ export class DeesPdfViewer extends DeesElement {
|
||||
const isBelow = thumbnailRect.bottom > sidebarRect.bottom;
|
||||
|
||||
if (isAbove || isBelow) {
|
||||
// Scroll the thumbnail into view, centering it if possible
|
||||
thumbnail.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
block: 'center'
|
||||
// Calculate the scroll position to center the thumbnail
|
||||
const thumbnailOffset = thumbnail.offsetTop;
|
||||
const thumbnailHeight = thumbnail.offsetHeight;
|
||||
const sidebarHeight = sidebarContent.clientHeight;
|
||||
const targetScrollTop = thumbnailOffset - (sidebarHeight / 2) + (thumbnailHeight / 2);
|
||||
|
||||
// Scroll the sidebar to center the thumbnail
|
||||
sidebarContent.scrollTo({
|
||||
top: Math.max(0, targetScrollTop),
|
||||
behavior: 'smooth'
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -541,10 +547,23 @@ export class DeesPdfViewer extends DeesElement {
|
||||
await this.updateComplete;
|
||||
const pageWrapper = this.shadowRoot?.querySelector(`.page-wrapper[data-page="${pageNum}"]`) as HTMLElement;
|
||||
if (pageWrapper && this.viewerMain) {
|
||||
pageWrapper.scrollIntoView({
|
||||
behavior: smooth ? 'smooth' : 'auto',
|
||||
block: 'start'
|
||||
// Calculate the offset of the page wrapper relative to the viewer
|
||||
const pageRect = pageWrapper.getBoundingClientRect();
|
||||
const viewerRect = this.viewerMain.getBoundingClientRect();
|
||||
const currentScrollTop = this.viewerMain.scrollTop;
|
||||
|
||||
// Calculate the target scroll position
|
||||
const targetScrollTop = currentScrollTop + (pageRect.top - viewerRect.top) - this.viewerMain.clientTop;
|
||||
|
||||
// Scroll to the calculated position
|
||||
if (smooth) {
|
||||
this.viewerMain.scrollTo({
|
||||
top: targetScrollTop,
|
||||
behavior: 'smooth'
|
||||
});
|
||||
} else {
|
||||
this.viewerMain.scrollTop = targetScrollTop;
|
||||
}
|
||||
|
||||
// Update current page
|
||||
this.currentPage = pageNum;
|
||||
@@ -661,11 +680,6 @@ export class DeesPdfViewer extends DeesElement {
|
||||
}
|
||||
}
|
||||
|
||||
private async goToPage(pageNum: number) {
|
||||
if (pageNum >= 1 && pageNum <= this.totalPages) {
|
||||
await this.scrollToPage(pageNum);
|
||||
}
|
||||
}
|
||||
|
||||
private handleThumbnailClick(e: Event) {
|
||||
const target = e.currentTarget as HTMLElement;
|
||||
@@ -809,6 +823,28 @@ export class DeesPdfViewer extends DeesElement {
|
||||
});
|
||||
this.resizeObserver.observe(this.viewerMain);
|
||||
this.measureViewportDimensions();
|
||||
|
||||
// Prevent scroll propagation to parent when scrolling inside viewer
|
||||
this.viewerMain.addEventListener('wheel', (e) => {
|
||||
const element = e.currentTarget as HTMLElement;
|
||||
const scrollTop = element.scrollTop;
|
||||
const scrollHeight = element.scrollHeight;
|
||||
const clientHeight = element.clientHeight;
|
||||
const deltaY = e.deltaY;
|
||||
|
||||
// Check if we're at the boundaries
|
||||
const isAtTop = scrollTop === 0;
|
||||
const isAtBottom = Math.abs(scrollTop + clientHeight - scrollHeight) < 1;
|
||||
|
||||
// Prevent propagation if we're scrolling within bounds
|
||||
if ((deltaY < 0 && !isAtTop) || (deltaY > 0 && !isAtBottom)) {
|
||||
e.stopPropagation();
|
||||
} else if ((deltaY < 0 && isAtTop) || (deltaY > 0 && isAtBottom)) {
|
||||
// Prevent default and propagation when at boundaries
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}, { passive: false });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ export const viewerStyles = [
|
||||
height: 600px;
|
||||
position: relative;
|
||||
font-family: 'Geist Sans', sans-serif;
|
||||
contain: layout style;
|
||||
}
|
||||
|
||||
.pdf-viewer {
|
||||
@@ -17,6 +18,8 @@ export const viewerStyles = [
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 97%)', 'hsl(215 20% 10%)')};
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
@@ -109,6 +112,7 @@ export const viewerStyles = [
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
@@ -160,6 +164,8 @@ export const viewerStyles = [
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
overscroll-behavior: contain;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.thumbnail {
|
||||
@@ -210,6 +216,9 @@ export const viewerStyles = [
|
||||
overflow-x: hidden;
|
||||
padding: 20px;
|
||||
scroll-behavior: smooth;
|
||||
overscroll-behavior: contain;
|
||||
min-height: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.loading-container {
|
||||
|
||||
Reference in New Issue
Block a user