From 01a5eebe17440e62f57b59a296cf5be151af2a91 Mon Sep 17 00:00:00 2001 From: Reece Date: Thu, 15 Jan 2026 14:12:22 +0000 Subject: [PATCH] Better screenshot --- frontend/package-lock.json | 57 +++---------------- frontend/package.json | 2 +- .../fileEditor/FileEditorThumbnail.tsx | 1 + .../viewer/ViewerZoomTransition.tsx | 4 +- frontend/src/core/utils/screenshot.ts | 17 ++---- 5 files changed, 17 insertions(+), 64 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index d819f2332c..a9f9ee1b6c 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -53,11 +53,11 @@ "autoprefixer": "^10.4.21", "axios": "^1.12.2", "globals": "^16.4.0", - "html2canvas": "^1.4.1", "i18next": "^25.5.2", "i18next-browser-languagedetector": "^8.2.0", "jszip": "^3.10.1", "license-report": "^6.8.0", + "modern-screenshot": "^4.4.39", "pdf-lib": "^1.17.1", "pdfjs-dist": "^5.4.149", "peerjs": "^1.5.5", @@ -5841,15 +5841,6 @@ "bare-path": "^3.0.0" } }, - "node_modules/base64-arraybuffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz", - "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/base64-js": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", @@ -6527,15 +6518,6 @@ "node": ">= 8" } }, - "node_modules/css-line-break": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz", - "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==", - "license": "MIT", - "dependencies": { - "utrie": "^1.0.2" - } - }, "node_modules/css-tree": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", @@ -8872,19 +8854,6 @@ "void-elements": "3.1.0" } }, - "node_modules/html2canvas": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz", - "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==", - "license": "MIT", - "dependencies": { - "css-line-break": "^2.1.0", - "text-segmentation": "^1.0.3" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/http-cache-semantics": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", @@ -10684,6 +10653,12 @@ "pathe": "^2.0.1" } }, + "node_modules/modern-screenshot": { + "version": "4.6.7", + "resolved": "https://registry.npmjs.org/modern-screenshot/-/modern-screenshot-4.6.7.tgz", + "integrity": "sha512-0GhgI6i6le4AhKzCvLYjwEmsP47kTsX45iT5yuAzsLTi/7i3Rjxe8fbH2VjGJLuyOThwsa0CdQAPd4auoEtsZg==", + "license": "MIT" + }, "node_modules/module-definition": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-6.0.1.tgz", @@ -13860,15 +13835,6 @@ "b4a": "^1.6.4" } }, - "node_modules/text-segmentation": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz", - "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==", - "license": "MIT", - "dependencies": { - "utrie": "^1.0.2" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -14503,15 +14469,6 @@ "dev": true, "license": "MIT" }, - "node_modules/utrie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz", - "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==", - "license": "MIT", - "dependencies": { - "base64-arraybuffer": "^1.0.2" - } - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", diff --git a/frontend/package.json b/frontend/package.json index b3f443dbfa..f350ef08d6 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -49,7 +49,7 @@ "autoprefixer": "^10.4.21", "axios": "^1.12.2", "globals": "^16.4.0", - "html2canvas": "^1.4.1", + "modern-screenshot": "^4.4.39", "i18next": "^25.5.2", "i18next-browser-languagedetector": "^8.2.0", "jszip": "^3.10.1", diff --git a/frontend/src/core/components/fileEditor/FileEditorThumbnail.tsx b/frontend/src/core/components/fileEditor/FileEditorThumbnail.tsx index 8af5d14d7a..d469064dd6 100644 --- a/frontend/src/core/components/fileEditor/FileEditorThumbnail.tsx +++ b/frontend/src/core/components/fileEditor/FileEditorThumbnail.tsx @@ -414,6 +414,7 @@ const FileEditorThumbnail = ({ display: 'block', marginLeft: 'auto', marginRight: 'auto', + justifySelf: 'center', alignSelf: 'start' }} /> diff --git a/frontend/src/core/components/viewer/ViewerZoomTransition.tsx b/frontend/src/core/components/viewer/ViewerZoomTransition.tsx index 4311908e73..77dc8d4436 100644 --- a/frontend/src/core/components/viewer/ViewerZoomTransition.tsx +++ b/frontend/src/core/components/viewer/ViewerZoomTransition.tsx @@ -182,8 +182,8 @@ export const ViewerZoomTransition: React.FC = () => { ? (viewerTransition.exitTargetRect || viewerTransition.sourceRect || getFallbackRect()) : (viewerTransition.sourceRect || getFallbackRect()); - const initialRadius = isExitTransition ? '0' : '8px'; - const targetRadius = isExitTransition ? '8px' : '0'; + const initialRadius = '0'; + const targetRadius = '0'; const initialWidth = Math.max(initialRect.width, 1); const initialHeight = Math.max(initialRect.height, 1); diff --git a/frontend/src/core/utils/screenshot.ts b/frontend/src/core/utils/screenshot.ts index 97a47065fb..94f61e7d42 100644 --- a/frontend/src/core/utils/screenshot.ts +++ b/frontend/src/core/utils/screenshot.ts @@ -1,4 +1,4 @@ -import html2canvas from 'html2canvas'; +import { domToPng } from 'modern-screenshot'; /** * Capture a screenshot of a DOM element as a data URL @@ -8,20 +8,15 @@ import html2canvas from 'html2canvas'; */ export async function captureElementScreenshot(element: HTMLElement): Promise { try { - const canvas = await html2canvas(element, { - backgroundColor: null, - scale: 1, - logging: false, - useCORS: true, + const dataUrl = await domToPng(element, { width: window.innerWidth, height: window.innerHeight, - windowWidth: window.innerWidth, - windowHeight: window.innerHeight, - x: 0, - y: 0, + style: { + transform: 'none', + }, }); - return canvas.toDataURL('image/png'); + return dataUrl; } catch (error) { console.warn('Failed to capture screenshot:', error); return null;