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;
|
const isBelow = thumbnailRect.bottom > sidebarRect.bottom;
|
||||||
|
|
||||||
if (isAbove || isBelow) {
|
if (isAbove || isBelow) {
|
||||||
// Scroll the thumbnail into view, centering it if possible
|
// Calculate the scroll position to center the thumbnail
|
||||||
thumbnail.scrollIntoView({
|
const thumbnailOffset = thumbnail.offsetTop;
|
||||||
behavior: 'smooth',
|
const thumbnailHeight = thumbnail.offsetHeight;
|
||||||
block: 'center'
|
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;
|
await this.updateComplete;
|
||||||
const pageWrapper = this.shadowRoot?.querySelector(`.page-wrapper[data-page="${pageNum}"]`) as HTMLElement;
|
const pageWrapper = this.shadowRoot?.querySelector(`.page-wrapper[data-page="${pageNum}"]`) as HTMLElement;
|
||||||
if (pageWrapper && this.viewerMain) {
|
if (pageWrapper && this.viewerMain) {
|
||||||
pageWrapper.scrollIntoView({
|
// Calculate the offset of the page wrapper relative to the viewer
|
||||||
behavior: smooth ? 'smooth' : 'auto',
|
const pageRect = pageWrapper.getBoundingClientRect();
|
||||||
block: 'start'
|
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
|
// Update current page
|
||||||
this.currentPage = pageNum;
|
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) {
|
private handleThumbnailClick(e: Event) {
|
||||||
const target = e.currentTarget as HTMLElement;
|
const target = e.currentTarget as HTMLElement;
|
||||||
@@ -809,6 +823,28 @@ export class DeesPdfViewer extends DeesElement {
|
|||||||
});
|
});
|
||||||
this.resizeObserver.observe(this.viewerMain);
|
this.resizeObserver.observe(this.viewerMain);
|
||||||
this.measureViewportDimensions();
|
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;
|
height: 600px;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-family: 'Geist Sans', sans-serif;
|
font-family: 'Geist Sans', sans-serif;
|
||||||
|
contain: layout style;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pdf-viewer {
|
.pdf-viewer {
|
||||||
@@ -17,6 +18,8 @@ export const viewerStyles = [
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background: ${cssManager.bdTheme('hsl(0 0% 97%)', 'hsl(215 20% 10%)')};
|
background: ${cssManager.bdTheme('hsl(0 0% 97%)', 'hsl(215 20% 10%)')};
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar {
|
.toolbar {
|
||||||
@@ -109,6 +112,7 @@ export const viewerStyles = [
|
|||||||
display: flex;
|
display: flex;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
@@ -160,6 +164,8 @@ export const viewerStyles = [
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.thumbnail {
|
.thumbnail {
|
||||||
@@ -210,6 +216,9 @@ export const viewerStyles = [
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
|
overscroll-behavior: contain;
|
||||||
|
min-height: 0;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.loading-container {
|
.loading-container {
|
||||||
|
|||||||
Reference in New Issue
Block a user