feat: Toolbar-Einstellungen merken (localStorage) + Tooltips überall
All checks were successful
Deploy bericht / deploy (push) Successful in 1s
All checks were successful
Deploy bericht / deploy (push) Successful in 1s
- Farbe, Strichstärke, Schriftart, Schriftgröße, Bold/Italic und Zoom werden in localStorage unter bericht.editor.settings.v1 gespeichert - Beim nächsten Öffnen werden alle Werte wiederhergestellt - Alle Toolbar-Buttons und Inputs haben jetzt deutsche Tooltips (Farbe, Strichstärke, Schriftart, Größe, Fett, Kursiv, Zoom -/+/Reset, Rotation links/rechts) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> [deploy]
This commit is contained in:
parent
a6cb8ade44
commit
a7a533f3b8
2 changed files with 58 additions and 14 deletions
|
|
@ -272,8 +272,8 @@ if (!$bericht) {
|
||||||
print '<button type="button" class="tool-btn" data-tool="arrow" title="'.$langs->trans("BerichtToolArrow").'">↗</button>';
|
print '<button type="button" class="tool-btn" data-tool="arrow" title="'.$langs->trans("BerichtToolArrow").'">↗</button>';
|
||||||
print '<button type="button" class="tool-btn" data-tool="text" title="'.$langs->trans("BerichtToolText").'">T</button>';
|
print '<button type="button" class="tool-btn" data-tool="text" title="'.$langs->trans("BerichtToolText").'">T</button>';
|
||||||
print '<span class="sep"></span>';
|
print '<span class="sep"></span>';
|
||||||
print '<label>'.$langs->trans("BerichtColor").': <input type="color" id="tool-color" value="#ff0000"></label>';
|
print '<label title="Linien-/Textfarbe">'.$langs->trans("BerichtColor").': <input type="color" id="tool-color" value="#ff0000" title="Farbe wählen"></label>';
|
||||||
print '<label>'.$langs->trans("BerichtStrokeWidth").': <input type="range" id="tool-stroke" min="1" max="20" value="3"></label>';
|
print '<label title="Linien-/Strichstärke in Pixel">'.$langs->trans("BerichtStrokeWidth").': <input type="range" id="tool-stroke" min="1" max="20" value="3" title="Strichstärke"></label>';
|
||||||
print '<span class="sep"></span>';
|
print '<span class="sep"></span>';
|
||||||
print '<button type="button" id="btn-undo" title="'.$langs->trans("BerichtUndo").'">↶</button>';
|
print '<button type="button" id="btn-undo" title="'.$langs->trans("BerichtUndo").'">↶</button>';
|
||||||
print '<button type="button" id="btn-redo" title="'.$langs->trans("BerichtRedo").'">↷</button>';
|
print '<button type="button" id="btn-redo" title="'.$langs->trans("BerichtRedo").'">↷</button>';
|
||||||
|
|
@ -283,7 +283,7 @@ if (!$bericht) {
|
||||||
print '<div class="row-break"></div>';
|
print '<div class="row-break"></div>';
|
||||||
|
|
||||||
// Text-Optionen
|
// Text-Optionen
|
||||||
print '<label class="text-tool-option">Schrift: <select id="tool-fontfamily">'
|
print '<label class="text-tool-option" title="Schriftart für Text-Annotationen">Schrift: <select id="tool-fontfamily" title="Schriftart">'
|
||||||
.'<option value="Helvetica">Helvetica</option>'
|
.'<option value="Helvetica">Helvetica</option>'
|
||||||
.'<option value="Arial">Arial</option>'
|
.'<option value="Arial">Arial</option>'
|
||||||
.'<option value="Times New Roman">Times New Roman</option>'
|
.'<option value="Times New Roman">Times New Roman</option>'
|
||||||
|
|
@ -291,18 +291,18 @@ if (!$bericht) {
|
||||||
.'<option value="Verdana">Verdana</option>'
|
.'<option value="Verdana">Verdana</option>'
|
||||||
.'<option value="Georgia">Georgia</option>'
|
.'<option value="Georgia">Georgia</option>'
|
||||||
.'</select></label>';
|
.'</select></label>';
|
||||||
print '<label class="text-tool-option">Größe: <input type="number" id="tool-fontsize" min="8" max="120" value="24" style="width:60px"></label>';
|
print '<label class="text-tool-option" title="Schriftgröße in Pixel">Größe: <input type="number" id="tool-fontsize" min="8" max="120" value="24" style="width:60px" title="Schriftgröße"></label>';
|
||||||
print '<label class="text-tool-option"><input type="checkbox" id="tool-bold"> <b>B</b></label>';
|
print '<label class="text-tool-option" title="Fett"><input type="checkbox" id="tool-bold" title="Fett"> <b>B</b></label>';
|
||||||
print '<label class="text-tool-option"><input type="checkbox" id="tool-italic"> <i>I</i></label>';
|
print '<label class="text-tool-option" title="Kursiv"><input type="checkbox" id="tool-italic" title="Kursiv"> <i>I</i></label>';
|
||||||
print '<span class="sep"></span>';
|
print '<span class="sep"></span>';
|
||||||
// Zoom
|
// Zoom
|
||||||
print '<button type="button" id="btn-zoom-out" title="Zoom -">🔍−</button>';
|
print '<button type="button" id="btn-zoom-out" title="Verkleinern (Zoom -)">🔍−</button>';
|
||||||
print '<span id="zoom-label" style="min-width:42px;text-align:center;font-size:12px;">100%</span>';
|
print '<span id="zoom-label" title="Aktueller Zoom" style="min-width:42px;text-align:center;font-size:12px;">100%</span>';
|
||||||
print '<button type="button" id="btn-zoom-in" title="Zoom +">🔍+</button>';
|
print '<button type="button" id="btn-zoom-in" title="Vergrößern (Zoom +)">🔍+</button>';
|
||||||
print '<button type="button" id="btn-zoom-reset" title="Zoom 100%">⟳%</button>';
|
print '<button type="button" id="btn-zoom-reset" title="Zoom auf 100% zurücksetzen">⟳%</button>';
|
||||||
print '<span class="sep"></span>';
|
print '<span class="sep"></span>';
|
||||||
print '<button type="button" id="btn-rotate-left" title="'.$langs->trans("BerichtRotateLeft").'">⟲</button>';
|
print '<button type="button" id="btn-rotate-left" title="'.$langs->trans("BerichtRotateLeft").' (Seite 90° nach links drehen)">⟲</button>';
|
||||||
print '<button type="button" id="btn-rotate-right" title="'.$langs->trans("BerichtRotateRight").'">⟳</button>';
|
print '<button type="button" id="btn-rotate-right" title="'.$langs->trans("BerichtRotateRight").' (Seite 90° nach rechts drehen)">⟳</button>';
|
||||||
print '</div>';
|
print '</div>';
|
||||||
print '<div class="bericht-canvas-wrap">';
|
print '<div class="bericht-canvas-wrap">';
|
||||||
print '<canvas id="pdf-canvas"></canvas>';
|
print '<canvas id="pdf-canvas"></canvas>';
|
||||||
|
|
|
||||||
48
js/editor.js
48
js/editor.js
|
|
@ -41,15 +41,58 @@
|
||||||
const pdfCanvas = document.getElementById('pdf-canvas');
|
const pdfCanvas = document.getElementById('pdf-canvas');
|
||||||
let currentTool = 'select';
|
let currentTool = 'select';
|
||||||
|
|
||||||
|
/* ---------- Settings-Persistenz (localStorage) ---------- */
|
||||||
|
const SETTINGS_KEY = 'bericht.editor.settings.v1';
|
||||||
|
function loadSettings() {
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(SETTINGS_KEY);
|
||||||
|
if (!raw) return {};
|
||||||
|
return JSON.parse(raw) || {};
|
||||||
|
} catch (e) { return {}; }
|
||||||
|
}
|
||||||
|
function saveSettings(patch) {
|
||||||
|
try {
|
||||||
|
const cur = loadSettings();
|
||||||
|
const merged = Object.assign({}, cur, patch);
|
||||||
|
localStorage.setItem(SETTINGS_KEY, JSON.stringify(merged));
|
||||||
|
} catch (e) { /* localStorage full/blocked */ }
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------- Init ---------- */
|
/* ---------- Init ---------- */
|
||||||
function init() {
|
function init() {
|
||||||
|
// Gespeicherte Einstellungen anwenden — VOR Fabric-Init
|
||||||
|
const s = loadSettings();
|
||||||
|
const colorEl = document.getElementById('tool-color');
|
||||||
|
const strokeEl = document.getElementById('tool-stroke');
|
||||||
|
const ffEl = document.getElementById('tool-fontfamily');
|
||||||
|
const fsEl = document.getElementById('tool-fontsize');
|
||||||
|
const boldEl = document.getElementById('tool-bold');
|
||||||
|
const italicEl = document.getElementById('tool-italic');
|
||||||
|
|
||||||
|
if (s.color) colorEl.value = s.color;
|
||||||
|
if (s.stroke) strokeEl.value = s.stroke;
|
||||||
|
if (s.fontFamily) ffEl.value = s.fontFamily;
|
||||||
|
if (s.fontSize) fsEl.value = s.fontSize;
|
||||||
|
if (typeof s.bold !== 'undefined') boldEl.checked = !!s.bold;
|
||||||
|
if (typeof s.italic !== 'undefined') italicEl.checked = !!s.italic;
|
||||||
|
if (s.zoom) currentZoom = parseFloat(s.zoom) || 1.0;
|
||||||
|
document.getElementById('zoom-label').textContent = Math.round(currentZoom * 100) + '%';
|
||||||
|
|
||||||
// Fabric initialisieren (wird beim ersten Seitenrendern dimensioniert)
|
// Fabric initialisieren (wird beim ersten Seitenrendern dimensioniert)
|
||||||
fabricCanvas = new fabric.Canvas('fabric-canvas', {
|
fabricCanvas = new fabric.Canvas('fabric-canvas', {
|
||||||
isDrawingMode: false,
|
isDrawingMode: false,
|
||||||
selection: true,
|
selection: true,
|
||||||
});
|
});
|
||||||
fabricCanvas.freeDrawingBrush.color = document.getElementById('tool-color').value;
|
fabricCanvas.freeDrawingBrush.color = colorEl.value;
|
||||||
fabricCanvas.freeDrawingBrush.width = parseInt(document.getElementById('tool-stroke').value, 10);
|
fabricCanvas.freeDrawingBrush.width = parseInt(strokeEl.value, 10);
|
||||||
|
|
||||||
|
// Listener: speichern bei jeder Änderung
|
||||||
|
colorEl.addEventListener('change', () => saveSettings({ color: colorEl.value }));
|
||||||
|
strokeEl.addEventListener('change', () => saveSettings({ stroke: parseInt(strokeEl.value, 10) }));
|
||||||
|
ffEl.addEventListener('change', () => saveSettings({ fontFamily: ffEl.value }));
|
||||||
|
fsEl.addEventListener('change', () => saveSettings({ fontSize: parseInt(fsEl.value, 10) }));
|
||||||
|
boldEl.addEventListener('change', () => saveSettings({ bold: boldEl.checked }));
|
||||||
|
italicEl.addEventListener('change', () => saveSettings({ italic: italicEl.checked }));
|
||||||
|
|
||||||
// Erste Seite laden (wenn vorhanden)
|
// Erste Seite laden (wenn vorhanden)
|
||||||
const firstThumb = document.querySelector('#bericht-page-list .page-thumb');
|
const firstThumb = document.querySelector('#bericht-page-list .page-thumb');
|
||||||
|
|
@ -312,6 +355,7 @@
|
||||||
async function setZoom(z) {
|
async function setZoom(z) {
|
||||||
currentZoom = Math.max(0.25, Math.min(3.0, Math.round(z * 100) / 100));
|
currentZoom = Math.max(0.25, Math.min(3.0, Math.round(z * 100) / 100));
|
||||||
document.getElementById('zoom-label').textContent = Math.round(currentZoom * 100) + '%';
|
document.getElementById('zoom-label').textContent = Math.round(currentZoom * 100) + '%';
|
||||||
|
saveSettings({ zoom: currentZoom });
|
||||||
await rerenderCurrent();
|
await rerenderCurrent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue