window.receiverSignature = (() => { const pads = new Map(); function getPosition(canvas, event) { const rect = canvas.getBoundingClientRect(); const source = event.touches && event.touches.length ? event.touches[0] : event; return { x: (source.clientX - rect.left) * (canvas.width / rect.width), y: (source.clientY - rect.top) * (canvas.height / rect.height) }; } function initialize(canvasId) { const canvas = document.getElementById(canvasId); if (!canvas || pads.has(canvasId)) return; const context = canvas.getContext('2d'); context.lineWidth = 2.5; context.lineCap = 'round'; context.lineJoin = 'round'; context.strokeStyle = '#111'; const state = { drawing: false, hasSignature: false }; pads.set(canvasId, state); const start = event => { event.preventDefault(); const pos = getPosition(canvas, event); state.drawing = true; context.beginPath(); context.moveTo(pos.x, pos.y); }; const move = event => { if (!state.drawing) return; event.preventDefault(); const pos = getPosition(canvas, event); context.lineTo(pos.x, pos.y); context.stroke(); state.hasSignature = true; }; const end = event => { if (!state.drawing) return; event.preventDefault(); state.drawing = false; }; canvas.addEventListener('mousedown', start); canvas.addEventListener('mousemove', move); window.addEventListener('mouseup', end); canvas.addEventListener('touchstart', start, { passive: false }); canvas.addEventListener('touchmove', move, { passive: false }); canvas.addEventListener('touchend', end, { passive: false }); } function clear(canvasId) { const canvas = document.getElementById(canvasId); const state = pads.get(canvasId); if (!canvas || !state) return; canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height); state.hasSignature = false; } function getDataUrl(canvasId) { const canvas = document.getElementById(canvasId); const state = pads.get(canvasId); if (!canvas || !state || !state.hasSignature) return null; return canvas.toDataURL('image/png'); } return { initialize, clear, getDataUrl }; })();