fix(feedback): Screenshot scharf + ohne Feedback-UI
- Auflösung: scale = window.devicePixelRatio (statt min:2 cap) — Retina-scharf
- Vor dem html2canvas-Capture werden v2-feedback-{modal,overlay,btn} auf
display:none gesetzt; finally-Block stellt UI zurueck. Damit ist die
ausgegraute Modal-Schicht nicht im Bild
- Capture nur des sichtbaren Viewports (width/height/x/y/windowWidth/Height
explizit), spart Bandbreite + zeigt was der User wirklich sieht
- MAX_W 800 -> 1600, JPEG 0.7 -> 0.85, imageSmoothingQuality high
- requestAnimationFrame x2 vor capture, damit Browser den Reflow vor dem Snap fertig hat
- app_version 1.0.1 -> 1.0.2 (Cache-Buster)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
07bb832c35
commit
4b03448e29
@ -4,7 +4,7 @@ from pathlib import Path
|
|||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
app_name: str = "GWÖ-Antragsprüfer"
|
app_name: str = "GWÖ-Antragsprüfer"
|
||||||
app_version: str = "1.0.1"
|
app_version: str = "1.0.2"
|
||||||
prompt_version: str = "v4.1"
|
prompt_version: str = "v4.1"
|
||||||
|
|
||||||
# Paths
|
# Paths
|
||||||
|
|||||||
@ -298,15 +298,39 @@
|
|||||||
// Screenshot (optional, via html2canvas)
|
// Screenshot (optional, via html2canvas)
|
||||||
if (screenshot && window.html2canvas) {
|
if (screenshot && window.html2canvas) {
|
||||||
submitBtn.textContent = 'Screenshot wird erstellt…';
|
submitBtn.textContent = 'Screenshot wird erstellt…';
|
||||||
|
// Modal + Overlay verstecken, damit der Screenshot die Seite ohne
|
||||||
|
// Feedback-UI zeigt. Nach dem Capture wieder einblenden.
|
||||||
|
var modal = document.getElementById('v2-feedback-modal');
|
||||||
|
var overlay = document.getElementById('v2-feedback-overlay');
|
||||||
|
var fbBtn = document.getElementById('v2-feedback-btn');
|
||||||
|
var prev = {
|
||||||
|
modalDisp: modal ? modal.style.display : null,
|
||||||
|
overlayDisp: overlay ? overlay.style.display : null,
|
||||||
|
btnDisp: fbBtn ? fbBtn.style.display : null,
|
||||||
|
};
|
||||||
|
if (modal) modal.style.display = 'none';
|
||||||
|
if (overlay) overlay.style.display = 'none';
|
||||||
|
if (fbBtn) fbBtn.style.display = 'none';
|
||||||
|
// ein Frame warten, damit die Browser den Reflow rendert
|
||||||
|
await new Promise(function (r) { requestAnimationFrame(function(){ requestAnimationFrame(r); }); });
|
||||||
try {
|
try {
|
||||||
var canvas = await window.html2canvas(document.body, {
|
var canvas = await window.html2canvas(document.body, {
|
||||||
scale: Math.min(window.devicePixelRatio || 1, 2),
|
scale: window.devicePixelRatio || 2, // Hi-DPI: scharfes Bild
|
||||||
useCORS: true,
|
useCORS: true,
|
||||||
allowTaint: false,
|
allowTaint: false,
|
||||||
logging: false,
|
logging: false,
|
||||||
|
backgroundColor: getComputedStyle(document.body).backgroundColor || '#fff',
|
||||||
|
// Sichtbares Viewport, nicht das ganze Dokument
|
||||||
|
width: document.documentElement.clientWidth,
|
||||||
|
height: document.documentElement.clientHeight,
|
||||||
|
x: window.scrollX,
|
||||||
|
y: window.scrollY,
|
||||||
|
windowWidth: document.documentElement.clientWidth,
|
||||||
|
windowHeight: document.documentElement.clientHeight,
|
||||||
});
|
});
|
||||||
// Breite auf max 800 px beschränken
|
// Breite begrenzen — bei Hi-DPI Display kann canvas.width 4000+ sein.
|
||||||
var MAX_W = 800;
|
// Cap bei 1600 logischen px (à la Retina-friendly), JPEG quality 0.85.
|
||||||
|
var MAX_W = 1600;
|
||||||
var finalCanvas = canvas;
|
var finalCanvas = canvas;
|
||||||
if (canvas.width > MAX_W) {
|
if (canvas.width > MAX_W) {
|
||||||
var ratio = MAX_W / canvas.width;
|
var ratio = MAX_W / canvas.width;
|
||||||
@ -314,14 +338,20 @@
|
|||||||
sc.width = MAX_W;
|
sc.width = MAX_W;
|
||||||
sc.height = Math.round(canvas.height * ratio);
|
sc.height = Math.round(canvas.height * ratio);
|
||||||
var ctx = sc.getContext('2d');
|
var ctx = sc.getContext('2d');
|
||||||
|
ctx.imageSmoothingEnabled = true;
|
||||||
|
ctx.imageSmoothingQuality = 'high';
|
||||||
ctx.drawImage(canvas, 0, 0, sc.width, sc.height);
|
ctx.drawImage(canvas, 0, 0, sc.width, sc.height);
|
||||||
finalCanvas = sc;
|
finalCanvas = sc;
|
||||||
}
|
}
|
||||||
var dataUrl = finalCanvas.toDataURL('image/jpeg', 0.7);
|
var dataUrl = finalCanvas.toDataURL('image/jpeg', 0.85);
|
||||||
fd.append('screenshot', dataUrl);
|
fd.append('screenshot', dataUrl);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Screenshot fehlgeschlagen → trotzdem absenden
|
|
||||||
fd.append('screenshot_error', String(err));
|
fd.append('screenshot_error', String(err));
|
||||||
|
} finally {
|
||||||
|
// UI zurückbringen
|
||||||
|
if (modal) modal.style.display = prev.modalDisp || '';
|
||||||
|
if (overlay) overlay.style.display = prev.overlayDisp || '';
|
||||||
|
if (fbBtn) fbBtn.style.display = prev.btnDisp || '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user