import React, { useRef, useState, useEffect } from 'react'; import './SignaturePad.css'; export default function SignaturePad() { const pad = useRef(null); const canvas = useRef(null); const drawing = useRef(false); const last = useRef(null); const strokes = useRef([]); const cur = useRef([]); const [hasInk, setHasInk] = useState(false); const [saved, setSaved] = useState(''); const ctx = () => canvas.current.getContext('2d'); const fit = () => { const r = pad.current.getBoundingClientRect(); canvas.current.width = r.width; canvas.current.height = r.height; redraw(); }; const pos = (e) => { const r = canvas.current.getBoundingClientRect(); const t = e.touches && e.touches[0]; return { x: (t ? t.clientX : e.clientX) - r.left, y: (t ? t.clientY : e.clientY) - r.top }; }; const down = (e) => { e.preventDefault(); drawing.current = true; last.current = pos(e); cur.current = [last.current]; strokes.current.push(cur.current); setHasInk(true); }; const move = (e) => { if (!drawing.current) return; e.preventDefault(); const p = pos(e); ctx().lineTo(p.x, p.y); ctx().stroke(); cur.current.push(p); }; const up = () => { drawing.current = false; last.current = null; }; const undo = () => { strokes.current.pop(); redraw(); if (!strokes.current.length) setHasInk(false); }; const clear = () => { strokes.current = []; redraw(); setHasInk(false); setSaved(''); }; const save = () => setSaved('已导出(' + canvas.current.width + '×' + canvas.current.height + ')'); const redraw = () => { const c = canvas.current; const x = c.getContext('2d'); x.clearRect(0, 0, c.width, c.height); x.strokeStyle = '#1F2329'; x.lineWidth = 2; x.lineCap = 'round'; x.lineJoin = 'round'; strokes.current.forEach((s) => { x.beginPath(); s.forEach((p, i) => (i ? x.lineTo(p.x, p.y) : x.moveTo(p.x, p.y))); x.stroke(); }); }; useEffect(() => { fit(); window.addEventListener('resize', fit); return () => window.removeEventListener('resize', fit); // eslint-disable-next-line }, []); return (