ฉันสร้าง PDF Ink เพื่อการเรียนรู้ออนไลน์ที่สะดวกสบายจากหนังสือ PDF ได้อย่างไร

ทำไมต้องอ่าน PDF หากคุณไม่สามารถเขียนอะไรลงไปได้เลย?

สวัสดีทุกคน! ฉันชื่อ Albert และฉันรักในการทำให้เครื่องมือต่างๆ ทำงานได้สะดวกขึ้น

หากคุณเคยลองเรียนรู้ด้วยตนเอง ศึกษาตำราเรียนเขียนโปรแกรม หรืออ่านเอกสารทางเทคนิคที่ซับซ้อนจากไฟล์ PDF บนแล็ปท็อปหรือแท็บเล็ตของคุณ คุณจะรู้ถึงความยุ่งยากนี้ดี คุณเปิดหนังสือขึ้นมา ต้องการไฮไลท์โค้ดสำคัญ วาดลูกศรแผนภาพด่วนถัดจากคำอธิบาย หรือจดโน้ตไว้ที่ระยะขอบ — และพบว่าโปรแกรมดู PDF มาตรฐานนั้นเทอะทะ เป็นโปรแกรมเสียเงิน หรือทำภาพวาดของคุณหายไปทั้งหมดหากเผลอกดรีเฟรชหน้าเว็บ

ฉันต้องการแก้ไขปัญหานี้และสร้าง PDF Ink — เว็บแอปพลิเคชันที่มีน้ำหนักเบาและรวดเร็วสำหรับการอ่านและเขียนบันทึกโต้ตอบบนหนังสือ PDF ได้โดยตรงในเบราว์เซอร์


แนวคิดและเทคโนโลยีที่ใช้

เป้าหมายหลักคือการสร้างเครื่องมือที่:

  1. เปิดใช้งานได้ในคลิกเดียวบนเบราว์เซอร์ที่ทันสมัยใดๆ
  2. ช่วยให้คุณโหลดตำราเรียน PDF จากเครื่องของคุณได้
  3. ช่วยให้คุณวาดบนหน้าเพจด้วยเมาส์ ปากกาสไตลัส หรือการสัมผัส และพิมพ์ข้อความบันทึกย่อได้
  4. ที่สำคัญที่สุด: บันทึกหน้าปัจจุบัน ระดับการซูม รายชื่อหนังสือ และโน้ตภาพวาดทั้งหมดไว้ในเครื่องของคุณอย่างปลอดภัย เพื่อให้คุณกลับมาเรียนต่อได้ทุกเมื่อ

สำหรับการนำไปใช้งาน ฉันเลือกเทคโนโลยีสมัยใหม่: React + TypeScript + Vite + TailwindCSS

สำหรับเอนจินการเรนเดอร์ PDF ฉันใช้ pdfjs-dist (PDF.js) ที่น่าเชื่อถือของ Mozilla ซึ่งเรนเดอร์หน้าเอกสารลงบนองค์ประกอบ HTML5 <canvas> โดยตรง


สถาปัตยกรรมแคนวาสแบบสองชั้น (Double-Layer)

เพื่อให้แอปพลิเคชันทำงานได้ประสิทธิภาพสูงและตอบสนองได้อย่างรวดเร็วระหว่างการโต้ตอบด้วยเมาส์หรือการสัมผัส ฉันจึงแบ่งพื้นที่ทำงานออกเป็นสองชั้นที่เป็นอิสระต่อกัน:

  1. PDF Layer: แคนวาสพื้นหลังแบบสแตติกที่เรนเดอร์รูปภาพหน้า PDF ตามขนาดซูมที่ใช้งานอยู่
  2. Annotation Layer: แคนวาสโปร่งใสวางซ้อนทับด้านบนซึ่งคอยดักจับ pointer events ของผู้ใช้ (PointerEvents) วาดเส้นเวกเตอร์ และวางข้อความบันทึกย่อ

การใช้วิธีแคนวาสสองชั้นนี้ทำให้การวาดภาพรวดเร็วมาก: เมื่อผู้ใช้วาดเส้น แอปพลิเคชันจะอัปเดตเฉพาะชั้นเวกเตอร์ที่มีน้ำหนักเบาเท่านั้น โดยปล่อยให้แคนวาส PDF ที่หนักกว่านั้นคงเดิม

สำหรับอุปกรณ์หน้าจอสัมผัส ฉันยังได้เพิ่ม:

  • การซูมด้วยการจีบนิ้ว (multi-touch pinch-to-zoom)
  • การวางโน้ตข้อความด้วยการลากและวางด้วยการสัมผัส โดยพิกัดจะคำนวณตามอัตราส่วนหน้าเพจ

วิวัฒนาการฐานข้อมูล: อัปเกรดเป็น IndexedDB v2

เวอร์ชันแรกเริ่มของโปรแกรมจำลองได้บันทึกไฟล์ PDF และภาพวาดทั้งหมดไว้ใน IndexedDB เป็นอ็อบเจกต์เดียวภายใต้คีย์ last-opened

อย่างไรก็ตาม เมื่อหนังสือมีขนาดใหญ่ขึ้น เราเจอปัญหาคอขวดด้านประสิทธิภาพ:

ปัญหา: ทุกครั้งที่ผู้ใช้วาดเส้นหรือย้ายโน้ตข้อความ แอปพลิเคชันจะบันทึกอัตโนมัติไปยัง IndexedDB การเขียน array buffer ขนาด 20MB ของไฟล์ PDF ดิบลงดิสก์ทุกๆ 250ms ทำให้หน้าเว็บหน่วงและทำให้อายุการใช้งาน SSD สั้นลง

วิธีแก้ไข: แยกไฟล์ออกจากโน้ตบันทึกย่อ

ฉันเขียนตัวจัดการ IndexedDB ใหม่และอัปเกรดสคีมาการจัดเก็บเป็นเวอร์ชัน 2:

  1. pdfs store: จัดเก็บไบต์ไฟล์ไบนารีดิบ (ArrayBuffer) โดยใช้ UUID ของเอกสารเป็นคีย์ ซึ่งจะเขียนเพียงครั้งเดียวเมื่ออัปโหลดไฟล์ใหม่เข้าไลบรารี
  2. pdfs_metadata store: จัดเก็บข้อมูล JSON Metadata ที่มีน้ำหนักเบา รวมถึงหมายเลขหน้า ระดับการซูม เส้นวาดเขียน และพิกัดข้อความ

ตอนนี้ เมื่อคุณวาดเขียน เฉพาะอ็อบเจกต์ข้อมูล Metadata ขนาดเล็กเท่านั้นที่ถูกอัปเดต การเขียนใช้เวลาไม่ถึงมิลลิวินาที ขจัดความหน่วงออกไปได้อย่างสิ้นเชิง!

ฉันยังเพิ่มสคริปต์การย้ายข้อมูลอัตโนมัติด้วย หากผู้ใช้เปิดแอปด้วยฐานข้อมูลเวอร์ชัน 1 ระบบจะดึงข้อมูลไบนารี สร้าง UUID ใหม่ แยกข้อมูล Metadata และทำการย้ายข้อมูลเซสชันการวาดเขียนของพวกเขาโดยอัตโนมัติ


ขัดเกลา UX: คลังหนังสือ ภาษา และแถบเครื่องมือพับได้

เพื่อให้ PDF Ink ให้ความรู้สึกเหมือนเครื่องมือระดับพรีเมียม ฉันได้รวมฟีเจอร์เพิ่มเติมสามอย่างเข้าด้วยกัน:

  • คลังหนังสือ PDF ที่ตอบสนองได้ดี: แถบด้านข้างพับได้ซึ่งแสดงรายการ PDF ที่อัปโหลด สถานะหน้า และสถิติโน้ต (จำนวนภาพวาด จำนวนข้อความ) พร้อมการ์ดโต้ตอบ
  • สวิตช์เปลี่ยนภาษา: สร้างระบบการแปลภาษาที่รองรับภาษาอังกฤษ (ค่าเริ่มต้น, EN เป็นหลัก) และภาษารัสเซีย (RU) โดยบันทึกการตั้งค่าลงใน localStorage
  • การตั้งค่าหัวแปรงพับได้: ปรับให้แถวการตั้งค่าปากกา (สี, แถบเลื่อนขนาด, ความโปร่งใส) เปิดปิดได้ผ่านไอคอน Sliders เพื่อให้ผู้ใช้สามารถซ่อนมันเพื่อเพิ่มพื้นที่หน้าจอให้มากที่สุดบนหน้าจอขนาดเล็ก

ทดลองใช้งานเลย!

คุณสามารถทดลองใช้งานเวอร์ชันจริงของแอปพลิเคชันได้ที่นี่:
👉 Practice Book PDF APP Live App


บทสรุป

เครื่องมือการเรียนรู้ควรช่วยให้คุณมีสมาธิกับการรับความรู้ ไม่ใช่ต้องมาสู้รบกับอินเตอร์เฟสของระบบ การพัฒนา PDF Ink แสดงให้ฉันเห็นว่าเบราว์เซอร์ API สมัยใหม่ (IndexedDB, PointerEvents, HTML5 Canvas) ช่วยให้นักพัฒนาสร้างเครื่องมือแบบ offline-first ที่ทรงพลังและเคารพความเป็นส่วนตัวของข้อมูลผู้ใช้ได้อย่างไร

ขอให้มีความสุขกับการเรียนรู้ และเขียนโค้ดที่ทำให้ชีวิตง่ายขึ้นกันเถอะ!