feat(dees-pdf-viewer): optimize thumbnail rendering and styles for improved layout and responsiveness

This commit is contained in:
2025-09-20 22:07:41 +00:00
parent 352fe79791
commit 53b5cbed07
2 changed files with 34 additions and 16 deletions

View File

@@ -604,41 +604,56 @@ export class DeesPdfViewer extends DeesElement {
try { try {
await this.updateComplete; await this.updateComplete;
const thumbnails = this.shadowRoot?.querySelectorAll('.thumbnail-canvas') as NodeListOf<HTMLCanvasElement>; const thumbnails = this.shadowRoot?.querySelectorAll('.thumbnail') as NodeListOf<HTMLElement>;
const thumbnailWidth = 176; // Fixed width for thumbnails (200px container - 24px padding) const thumbnailCanvases = this.shadowRoot?.querySelectorAll('.thumbnail-canvas') as NodeListOf<HTMLCanvasElement>;
const sidebarContent = this.shadowRoot?.querySelector('.sidebar-content') as HTMLElement;
// Get the actual available width for thumbnails (sidebar width minus padding)
const sidebarStyles = window.getComputedStyle(sidebarContent);
const sidebarPadding = parseFloat(sidebarStyles.paddingLeft) + parseFloat(sidebarStyles.paddingRight);
const maxThumbnailWidth = 200 - sidebarPadding - 4; // Account for border
// Clear all canvases first to prevent conflicts // Clear all canvases first to prevent conflicts
for (const canvas of Array.from(thumbnails)) { for (const canvas of Array.from(thumbnailCanvases)) {
const context = canvas.getContext('2d'); const context = canvas.getContext('2d');
if (context) { if (context) {
context.clearRect(0, 0, canvas.width, canvas.height); context.clearRect(0, 0, canvas.width, canvas.height);
} }
} }
for (const canvas of Array.from(thumbnails)) { for (let i = 0; i < thumbnailCanvases.length; i++) {
if (signal?.aborted) return; if (signal?.aborted) return;
const canvas = thumbnailCanvases[i];
const thumbnail = thumbnails[i];
const pageNum = parseInt(canvas.dataset.page || '1'); const pageNum = parseInt(canvas.dataset.page || '1');
const page = await this.pdfDocument.getPage(pageNum); const page = await this.pdfDocument.getPage(pageNum);
// Calculate scale to fit thumbnail width while maintaining aspect ratio // Get the page's natural dimensions
const initialViewport = page.getViewport({ scale: 1 }); const initialViewport = page.getViewport({ scale: 1 });
const scale = thumbnailWidth / initialViewport.width;
// Calculate scale to fit within the max thumbnail width
const scale = maxThumbnailWidth / initialViewport.width;
const viewport = page.getViewport({ scale }); const viewport = page.getViewport({ scale });
// Set canvas dimensions to actual render size // Set canvas dimensions to actual render size
canvas.width = viewport.width; canvas.width = viewport.width;
canvas.height = viewport.height; canvas.height = viewport.height;
// Also set the display size via style to ensure proper display // Set the display size via style to ensure proper display
canvas.style.width = `${viewport.width}px`; canvas.style.width = `${viewport.width}px`;
canvas.style.height = `${viewport.height}px`; canvas.style.height = `${viewport.height}px`;
// Set the actual thumbnail container height
thumbnail.style.height = `${viewport.height}px`;
thumbnail.style.minHeight = `${viewport.height}px`;
const context = canvas.getContext('2d'); const context = canvas.getContext('2d');
if (!context) { if (!context) {
page.cleanup?.(); page.cleanup?.();
continue; continue;
} }
const renderContext = { const renderContext = {
canvasContext: context, canvasContext: context,
viewport: viewport, viewport: viewport,

View File

@@ -161,9 +161,7 @@ export const viewerStyles = [
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;
padding: 12px; padding: 12px;
display: flex; display: block;
flex-direction: column;
gap: 12px;
overscroll-behavior: contain; overscroll-behavior: contain;
min-height: 0; min-height: 0;
} }
@@ -175,11 +173,16 @@ export const viewerStyles = [
cursor: pointer; cursor: pointer;
border: 2px solid transparent; border: 2px solid transparent;
transition: border-color 0.15s ease; transition: border-color 0.15s ease;
background: ${cssManager.bdTheme('hsl(0 0% 100%)', 'hsl(215 20% 18%)')}; background: ${cssManager.bdTheme('hsl(0 0% 95%)', 'hsl(215 20% 18%)')};
display: flex; display: block;
align-items: center; width: 100%;
justify-content: center; margin-bottom: 12px;
min-height: 100px; /* Default A4 aspect ratio (297mm / 210mm ≈ 1.414) */
min-height: calc(176px * 1.414);
}
.thumbnail:last-child {
margin-bottom: 0;
} }
.thumbnail:hover { .thumbnail:hover {
@@ -192,7 +195,7 @@ export const viewerStyles = [
.thumbnail-canvas { .thumbnail-canvas {
display: block; display: block;
max-width: 100%; width: 100%;
height: auto; height: auto;
image-rendering: -webkit-optimize-contrast; image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges; image-rendering: crisp-edges;