feat: Add PDF viewer and preview components with styling and functionality
- Implemented DeesPdfViewer for full-featured PDF viewing with toolbar and sidebar navigation. - Created DeesPdfPreview for lightweight PDF previews. - Introduced PdfManager for managing PDF document loading and caching. - Added CanvasPool for efficient canvas management. - Developed utility functions for performance monitoring and file size formatting. - Established styles for viewer and preview components to enhance UI/UX. - Included demo examples for showcasing PDF viewer capabilities.
This commit is contained in:
98
ts_web/elements/dees-pdf-shared/utils.ts
Normal file
98
ts_web/elements/dees-pdf-shared/utils.ts
Normal file
@@ -0,0 +1,98 @@
|
||||
export function debounce<T extends (...args: any[]) => any>(
|
||||
func: T,
|
||||
wait: number
|
||||
): (...args: Parameters<T>) => void {
|
||||
let timeout: number | undefined;
|
||||
|
||||
return function executedFunction(...args: Parameters<T>) {
|
||||
const later = () => {
|
||||
clearTimeout(timeout);
|
||||
func(...args);
|
||||
};
|
||||
|
||||
clearTimeout(timeout);
|
||||
timeout = window.setTimeout(later, wait);
|
||||
};
|
||||
}
|
||||
|
||||
export function throttle<T extends (...args: any[]) => any>(
|
||||
func: T,
|
||||
limit: number
|
||||
): (...args: Parameters<T>) => void {
|
||||
let inThrottle: boolean;
|
||||
|
||||
return function executedFunction(...args: Parameters<T>) {
|
||||
if (!inThrottle) {
|
||||
func.apply(this, args);
|
||||
inThrottle = true;
|
||||
setTimeout(() => inThrottle = false, limit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function formatFileSize(bytes: number): string {
|
||||
if (bytes === 0) return '0 Bytes';
|
||||
|
||||
const k = 1024;
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
|
||||
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];
|
||||
}
|
||||
|
||||
export function isInViewport(element: Element, margin = 0): boolean {
|
||||
const rect = element.getBoundingClientRect();
|
||||
return (
|
||||
rect.top >= -margin &&
|
||||
rect.left >= -margin &&
|
||||
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) + margin &&
|
||||
rect.right <= (window.innerWidth || document.documentElement.clientWidth) + margin
|
||||
);
|
||||
}
|
||||
|
||||
export class PerformanceMonitor {
|
||||
private static marks = new Map<string, number>();
|
||||
private static measures: Array<{ name: string; duration: number }> = [];
|
||||
|
||||
public static mark(name: string) {
|
||||
this.marks.set(name, performance.now());
|
||||
}
|
||||
|
||||
public static measure(name: string, startMark: string) {
|
||||
const start = this.marks.get(startMark);
|
||||
if (start) {
|
||||
const duration = performance.now() - start;
|
||||
this.measures.push({ name, duration });
|
||||
this.marks.delete(startMark);
|
||||
return duration;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static getReport() {
|
||||
const report = {
|
||||
measures: [...this.measures],
|
||||
averages: {} as Record<string, number>,
|
||||
};
|
||||
|
||||
// Calculate averages for repeated measures
|
||||
const grouped = new Map<string, number[]>();
|
||||
for (const measure of this.measures) {
|
||||
if (!grouped.has(measure.name)) {
|
||||
grouped.set(measure.name, []);
|
||||
}
|
||||
grouped.get(measure.name)!.push(measure.duration);
|
||||
}
|
||||
|
||||
for (const [name, durations] of grouped) {
|
||||
report.averages[name] = durations.reduce((a, b) => a + b, 0) / durations.length;
|
||||
}
|
||||
|
||||
return report;
|
||||
}
|
||||
|
||||
public static clear() {
|
||||
this.marks.clear();
|
||||
this.measures = [];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user