diff --git a/.claude/rules/pdf-viewer.md b/.claude/rules/pdf-viewer.md index 3467c15..6cc7d4b 100644 --- a/.claude/rules/pdf-viewer.md +++ b/.claude/rules/pdf-viewer.md @@ -23,6 +23,9 @@ paths: - DRAW วาดเส้นตรง: **ปล่อยเมาส์แล้ว snap อัตโนมัติ** เมื่อจุดทุกจุดห่างจากเส้นตรง จุดเริ่ม→จุดสุดท้าย ไม่เกิน max(5% ของความยาว, 3px) และเส้นยาว ≥ 24px (`isNearlyStraight`) — หรือกดค้าง **Shift** ระหว่างลาก (กด/ปล่อยกลางทางได้ — listener ระดับ window + reset ตอน blur) เพื่อบังคับตรงเสมอ → บันทึกเหลือจุดเริ่ม→จุดสุดท้าย 2 จุด (ความหนา uniform — ไม่เก็บ `widths` จาก pressure) — ใช้ได้เฉพาะโหมดวาดอิสระ ไม่ใช่ shape/eraser/redact; เส้นโค้ง/ขดจริงหลุดเกณฑ์จึงเหลือ freehand - Tool `pan` (มือเลื่อนหน้า — ปุ่มแยกถัดจาก select ในแถบ tool): ลากบน `
` = `window.scrollBy` สวนทางการลาก + cursor grab/grabbing; ระหว่างใช้ pan ทุก overlay ปิด pointer-events ผ่านตัวแปร `overlayFrozen` (`inkActive || pan`) **ยกเว้น InkLayer ต้องไม่ active** (ไม่งั้น pan กลายเป็นวาดเส้น) - HIGHLIGHT มี `style?` 4 แบบ: highlight ทึบเหมือนเดิม / underline = เส้นที่ขอบล่าง rect ต่อบรรทัด / strikethrough = เส้นกลางบรรทัด / squiggle = svg path ขยุกขยิก (`squigglePath`) ที่ขอบล่าง — export วาด line/sine แทน rect ทึบ; สร้างได้จาก **tool "highlight" ทางเดียว** (dropdown บนปุ่ม = รูปแบบ + สี → คลุมข้อความ = สร้างทันที พร้อม live preview ผ่าน `selectionchange` + ซ่อน native selection) — tool "เลือกข้อความ" คลุมแล้วเกิด popup ไม่ได้แล้ว (ถอดออก) และคีย์ลัด `H` สลับไป tool highlight +- **คลุมข้อความได้ 5 tool** (`TEXT_SELECTION_TOOLS` set ใน PDFViewer: select/highlight/comment/textbox/stamp — ที่เหลือ textLayer ปิด pointer-events คลุมไม่ได้): ทั้งหมด inject ` )} {/* UX review 2026-09-09: backdrop กันคลิกทะลุใต้ sidebar overlay (เฉพาะ < xl) @@ -3067,14 +3085,14 @@ export default function PDFViewer({ onMouseUp={() => handleMouseUpOnPage(i)} onClick={(e) => handlePageClick(e, i, e.currentTarget)} onMouseDown={(e) => { - // จุดเริ่มเส้นทางลากของ tool highlight/select (กรอง selection rects) - if (tool !== "highlight" && tool !== "select") return; + // จุดเริ่มเส้นทางลากของ tool คลุมข้อความ (กรอง selection rects) + if (!TEXT_SELECTION_TOOLS.has(tool)) return; selDragStartRef.current = { x: e.clientX, y: e.clientY }; selDragEndRef.current = { x: e.clientX, y: e.clientY }; }} onMouseMove={(e) => { // ตำแหน่งเมาส์ล่าสุดระหว่างลากค้างปุ่ม (buttons=1) - if ((tool === "highlight" || tool === "select") && e.buttons === 1) { + if (TEXT_SELECTION_TOOLS.has(tool) && e.buttons === 1) { selDragEndRef.current = { x: e.clientX, y: e.clientY }; } handlePageHoverMove(e, i);