diff --git a/frontend/src/tools/linkliste.jsx b/frontend/src/tools/linkliste.jsx index 3614c80..1a70c94 100644 --- a/frontend/src/tools/linkliste.jsx +++ b/frontend/src/tools/linkliste.jsx @@ -10,7 +10,6 @@ const TOOL_ENTRIES = [ { url:'tool://bestellungen', label:'๐ฆ Bestellungen', group:'3D-Druck' }, { url:'tool://kalkulator3d', label:'๐งฎ Kostenrechner', group:'3D-Druck' }, { url:'tool://kanban', label:'๐ Kanban', group:'Werkzeuge' }, - { url:'tool://kanban', label:'๐ Kanban', group:'Werkzeuge' }, { url:'tool://whiteboard', label:'๐ Whiteboard', group:'Werkzeuge' }, { url:'tool://dateien', label:'๐ Dateien', group:'Werkzeuge' }, { url:'tool://nachrichten', label:'๐ฌ Nachrichten', group:'Werkzeuge' }, diff --git a/frontend/src/tools/whiteboard.jsx b/frontend/src/tools/whiteboard.jsx index c5c52c1..a399361 100644 --- a/frontend/src/tools/whiteboard.jsx +++ b/frontend/src/tools/whiteboard.jsx @@ -283,6 +283,7 @@ export default function Whiteboard({ toast, mobile }) { const [saving, setSaving] = useState(false); const [shareModal,setShareModal]= useState(false); const [textInput, setTextInput] = useState(null); + const [textPreview, setTextPreview] = useState(null); // Live-Vorschau wรคhrend Tippen const [selectedId,setSelectedId]= useState(null); // Kollaboration @@ -303,6 +304,7 @@ export default function Whiteboard({ toast, mobile }) { const vpRef = useRef({x:0,y:0,zoom:1}); const elementsRef = useRef([]); const selectedRef = useRef(null); + const textPreviewRef = useRef(null); // โโ Hilfsfunktionen โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ const syncVp = (vp) => { vpRef.current=vp; setViewport({...vp}); }; @@ -463,7 +465,25 @@ export default function Whiteboard({ toast, mobile }) { ctx.save(); ctx.fillStyle=c.color; ctx.font='10px monospace'; ctx.fillText('โถ '+c.username, sx+6, sy-4); ctx.restore(); } - }, [collab]); + // Text-Vorschau wรคhrend Tippen + if (textPreviewRef.current) { + const { text, x, y, fontSize, color } = textPreviewRef.current; + const vp = vpRef.current; + const sx = x * vp.zoom + vp.x; + const sy = y * vp.zoom + vp.y; + ctx.save(); + ctx.font = `${fontSize * vp.zoom}px monospace`; + ctx.fillStyle = color; + ctx.globalAlpha = 0.85; + ctx.fillText(text || '|', sx, sy); + // Cursor-Blinken simulieren: kleiner Strich hinter dem Text + if (text) { + const tw = ctx.measureText(text).width; + ctx.fillRect(sx + tw + 1, sy - fontSize * vp.zoom * 0.8, 2, fontSize * vp.zoom); + } + ctx.restore(); + } + }, [collab, textPreview]); useEffect(()=>{ render(); }, [elements, viewport, selectedId, collab, render]); @@ -507,6 +527,8 @@ export default function Whiteboard({ toast, mobile }) { // Text if (tool==='text') { + textPreviewRef.current = { text:'', x, y, fontSize:FONT_SIZES[fontSize], color }; + render(); setTextInput({ sx, sy, x, y }); return; } @@ -717,7 +739,6 @@ export default function Whiteboard({ toast, mobile }) { {textInput&&( mobile ? ( - // Mobile: festes Panel unten, kein Keyboard-Verschiebe-Problem