เทคนิคการเขียนโค้ดให้เป็นลายมือของฉัน
(amygoodchild.com)- เริ่มจากตัวสร้างตัวอักษรแบบบล็อกใน JavaScript แล้วขยายจนสามารถสร้าง ลายมือแบบตัวเขียน ด้วยโค้ดได้ภายในสองเดือน
- ตัวอักษรถูกสร้างโดยกำหนด จุดพิกัดหลัก ด้วยเครื่องมือ p5js แล้วเกลารูปทรงด้วยเส้นโค้ง Chaikin ก่อนแปลงเป็นเส้นทางที่มีความหนาแปรผัน
- สำหรับลายมือแบบตัวเขียน การเชื่อมต่อระหว่างคู่ตัวอักษรแตกต่างกัน จึงติด แท็ก 0~3 ไว้ที่จุดเริ่มและจุดจบของเส้นทางเพื่อแยกสถานะว่าเชื่อมไม่ได้, ที่ baseline, เหนือ baseline, หรือใกล้ x-height
- เมื่อต้องสร้างคำ ระบบจะเลือกหนึ่งเส้นทางจาก 2~3 แบบของแต่ละตัวอักษร แล้วเพิ่ม, ลบ, หรือแทนที่จุดตามระดับการเชื่อมของตัวอักษรข้างเคียง ก่อนเติมความสั่นไหวด้วย Perlin noise
- หลังย่อขนาดแล้ว คลาสตัวอักษรแบบตัวเขียนมีขนาด 26.1kb ซึ่งใหญ่กว่าตัวแบบบล็อกที่ 9.7kb โดยมีสาเหตุมาจากหลายเส้นทางและฟังก์ชันปรับแก้ตามตัวอักษรข้างเคียง
ขยายจากวิธีสร้างตัวอักษรแบบบล็อกไปสู่ลายมือแบบตัวเขียน
- ตัวสร้างตัวอักษรแบบบล็อกก่อนหน้านี้ใช้วิธีกำหนด จุดหลัก ของเส้นทางแต่ละตัวอักษรด้วยโค้ด
- วางจุดประมาณ 10 จุดต่อหนึ่งตัวอักษร
- ใช้อัลกอริทึมเส้นโค้ง Chaikin เพื่อทำให้เส้นทางนุ่มนวลขึ้น
- แปลงเส้นทางให้เป็นรูปทรงที่ความหนาเปลี่ยนไปตามความยาว
- วาดรูปทรงสุดท้ายด้วย p5js
- ในตัวอักษรแบบบล็อก ต้องเขียนพิกัดลงในโค้ดโดยตรง และปรับจุดด้วยมือซ้ำไปมาจนกว่าตัวอักษรจะดูเป็นธรรมชาติ
- ในการทำลายมือแบบตัวเขียน จึงสร้าง เครื่องมือออกแบบตัวอักษร แยกต่างหากเพื่อลดงานวนซ้ำนี้
เครื่องมือออกแบบเส้นทางตัวอักษรใน p5js
- สร้างและใช้งาน เครื่องมือกำหนดและแสดงจุดหลัก ในตัวแก้ไข p5js
- เครื่องมือนี้มีทั้งตัวอักษรตัวอย่างเพื่อแสดงสเกลและบริบท พร้อมพื้นที่สำหรับออกแบบตัวอักษรใหม่
- เมื่อคลิกเพื่อวางจุดหลักของเส้นทาง จะแสดงผลลัพธ์ที่ผ่านเส้นโค้ง Chaikin
- กดปุ่ม
pเพื่อสลับไปยังโหมดแก้ไข - เลือกจุดแล้วลากเพื่อปรับตำแหน่ง
- กดปุ่ม
enterเพื่อส่งออกเส้นทางไปยังคอนโซล
- สำหรับแต่ละตัวอักษร ได้สร้าง ตัวเลือก 2~3 แบบ และเส้นทางที่ได้จะอยู่ในรูปอาร์เรย์พิกัด
{x, y} - เพื่อใช้ลายมือตัวเองเป็นต้นแบบ จึงเขียนตัวอย่างตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ด้วยมือตรง ๆ แล้วนำภาพนั้นเข้าไปในเครื่องมือสร้างตัวอักษรเพื่อวาดตาม
- ใช้ปุ่ม
w/a/s/dเพื่อเลื่อนภาพ - ใช้ปุ่ม
r/eเพื่อขยายหรือย่อภาพ - ตัวเลขที่เขียนไว้บนกระดาษคือพิกัด x/y สำหรับจัดพื้นที่นั้นให้พอดีกับหน้าต่างสร้างตัวอักษร
- ใช้ปุ่ม
ปัญหาการเชื่อมลายมือแบบตัวเขียนและแท็ก 0~3
- คู่ตัวอักษรบางคู่สามารถเชื่อมได้อย่างเป็นธรรมชาติ เพียงนำเส้นทางจุดหลักของตัวอักษรถัดไปมาต่อท้ายเส้นทางของตัวก่อนหน้า แล้วใช้เส้นโค้ง Chaikin กับทั้งหมดในครั้งเดียว
- แต่ในบางชุด การลากเส้นเชื่อมกลับทำให้รูปทรงของตัวอักษรเสีย
- ใน
naจุดสุดท้ายของnอยู่ต่ำ แต่จุดแรกของaอยู่สูง ทำให้เส้นเชื่อมพาดเฉียงผ่านaจนดูคล้ายe - ใน
tiตัวtจบเหนือ baseline เล็กน้อย ขณะที่iเริ่มที่ baseline จึงเกิดสันที่ดูไม่เป็นธรรมชาติ
- ใน
- แทนที่จะเขียนกฎแยกสำหรับทุกคู่ตัวอักษร จึงแนบข้อมูล ระดับความสูงของจุดเชื่อม เป็นตัวเลขไว้ที่ต้นและท้ายของแต่ละเส้นทาง
0: เชื่อมกับตัวอักษรอื่นไม่ได้1: เชื่อมกับตัวอักษรอื่นใกล้ baseline2: เชื่อมกับตัวอักษรอื่นเหนือ baseline เล็กน้อย3: เชื่อมกับตัวอักษรอื่นใกล้ x-height
- แม้จะเป็นตัวอักษรเดียวกัน วิธีเพิ่มหรือลบจุดก็เปลี่ยนไปตามว่าอยู่ต้นคำหรือมีตัวอักษรใดอยู่หน้าและหลัง
- ถ้า
aอยู่ต้นคำ การเพิ่มจุดอาจดูแปลก - ใน
aที่ตามหลังwเส้นอาจพาดข้ามaด้วยวิธีที่ต่างออกไป - ถ้า
tต่อกับkรูปทรงอาจบิดเปลี่ยน
- ถ้า
- ได้ทดสอบทุกคู่ตัวอักษร และสร้าง ความแปรผัน ด้วยตัวเลือกเส้นทางหลายแบบและการแก้ไขตามตัวอักษรข้างเคียง
- ในอุดมคติอยากให้แต่ละตัวอักษรมีตัวเลือกเส้นทาง 5~6 แบบ แต่ต้องรักษาสมดุลกับขนาดไฟล์
ขั้นตอนการสร้างคำ
- เมื่อต้องสร้างคำ ระบบจะเลือกหนึ่งเส้นทางจาก เส้นทางพื้นฐาน 2~3 แบบ ของแต่ละตัวอักษรก่อน
- ข้อมูลการเชื่อมที่ต้นและท้ายของเส้นทางที่เลือกจะถูกส่งต่อไปยังตัวอักษรข้างเคียง
- แม้จะเป็นตัวอักษรเดียวกัน ข้อมูลจุดปลายก็อาจต่างกันตามตัวเลือกเส้นทางที่ถูกเลือก ดังนั้นจึงต้องเลือกเส้นทางของทุกตัวอักษรก่อน
- จากนั้นเส้นทางพื้นฐานจะถูกปรับให้เข้ากับตัวอักษรข้างเคียง
- ถ้าความสูงปลายของตัวก่อนหน้าเป็น
2อาจลบจุดเริ่มต้นหนึ่งจุดของเส้นทางปัจจุบันออก - ถ้าความสูงเริ่มต้นของตัวถัดไปเป็น
1อาจเพิ่มจุดในตำแหน่งที่กำหนด
- ถ้าความสูงปลายของตัวก่อนหน้าเป็น
- ฟังก์ชันปรับแต่งทำงานต่างกันไปในแต่ละตัวอักษร
- ฟังก์ชันปรับของ
qมีโอกาส 70% ที่จะเพิ่มรอยขาดไว้ที่ท้าย และจะสลับหรือเพิ่มจุดตามข้อมูลปลายของตัวก่อนหน้าหรือข้อมูลต้นของตัวถัดไป - ฟังก์ชันปรับของ
nจะสร้างรอยขาดด้วยโอกาส 30% หรือย้ายจุดสุดท้าย เมื่ออักษรถัดไปเริ่มจาก3
- ฟังก์ชันปรับของ
- เมื่อนำเส้นทางพื้นฐานของทุกตัวอักษรมารวมกัน ค่า
1,2,3จะถูกมองข้าม และหากเจอ0จะเริ่มเส้นทางใหม่เพื่อสร้าง รอยขาด - จากนั้นจึงใช้เส้นโค้ง Chaikin กับเส้นทางที่รวมแล้ว แปลงให้เป็นรูปทรงความหนาแปรผัน และเพิ่มความสั่นไหวเล็กน้อยด้วย Perlin noise
ขนาดไฟล์และรูปแบบการใช้งาน
- คลาสตัวอักษรสำหรับแบบบล็อกมีขนาด 9.7kb ส่วนคลาสตัวอักษรแบบตัวเขียนที่ผ่านการย่อขนาดแล้วปัจจุบันมีขนาด 26.1kb
- เหตุผลที่ฝั่งตัวเขียนใหญ่กว่า เพราะแต่ละตัวอักษรมีหลายเส้นทาง และมีฟังก์ชันที่ปรับจุดให้เข้ากับตัวอักษรข้างเคียง
- ยังมีแนวคิดสำหรับลดขนาดเพิ่มเติมอยู่
- ตอนนี้ตัวอักษรถูกออกแบบโดยอิงขนาดฟอนต์พื้นฐาน 20 แล้วค่อยปรับขนาดอีกที
- ทำให้มีพิกัดอย่าง
x: 14.5อยู่จำนวนมาก - ถ้าเปลี่ยนขนาดพื้นฐานเป็น 200 ก็จะเขียนเป็น
145ได้และตัดเลขทศนิยมออกเพื่อลดขนาดของแต่ละตัวอักษร - การเปลี่ยนนี้ต้องทำอย่างระมัดระวัง จึงถูกเก็บไว้ในรายการงานภายหลัง
- การใช้งานหลักของลายมือนี้คือใช้กับชื่อเรื่อง, ป้ายกำกับ และบันทึกขีดเขียนใน ไดอะแกรม ที่กำลังทำอยู่
- การใช้เส้นทางที่เข้ารหัสไว้แทนฟอนต์ ทำให้สามารถ จัดการเส้นทาง ได้โดยตรง เช่น เปลี่ยนตำแหน่งตัวอักษรหรือความหนาภายในของตัวอักษรแต่ละตัว
- ยังมีการจำหน่ายงานพิมพ์
Meaningful Nonsenseที่ใช้เวอร์ชันพัฒนาของโค้ดลายมือนี้ โดยงานพิมพ์แต่ละชิ้นจะเป็นผลลัพธ์เฉพาะตัวที่สร้างขึ้นเมื่อมีการสั่งซื้อ
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ถ้า เข้ารหัสลายมือ ของฉัน ก็คงมองว่าเป็นแฮชทางเดียวได้เหมือนกัน
เพราะพอกลับมาอ่านทีหลัง ก็ไม่มีทางถอดได้เลยว่าจริง ๆ ตั้งใจจะเขียนว่าอะไร
มีวิดีโอ YouTube ของ Stuff Made Here ที่พูดถึงเรื่องคล้ายกัน ซึ่งเจ๋งมาก: https://www.youtube.com/watch?v=cQO2XTP7QDw
เขาอธิบายทั้งขั้นตอนลองผิดลองถูกด้วย เลยดูเพลินมาก และคลังสำหรับสังเคราะห์ลายมือก็น่าสนใจด้วย: https://github.com/sjvasquez/handwriting-synthesis
งานภาพ ตอนท้ายนี่สวยมาก
สงสัยว่าขั้นต่อไปจะเป็นการทำให้มันกลายเป็นฟอนต์จริง ๆ เพื่อให้พิมพ์ได้ในโปรแกรมไหนก็ได้หรือเปล่า
ต่างจากฟอนต์ที่เรามักนึกถึง เพราะมันต้องเป็นเส้นทางสำหรับให้ลากตาม ไม่ใช่เส้นขอบไว้ระบายเติม
แต่อาจจะน่าเบื่อถ้าต้องทำด้วยมือ หรือถ้าอยากทำแบบนั้นเอง
ฉันไม่ค่อยเข้าใจประเด็นที่บอกว่าการเชื่อมตัวอักษรไม่ถูกต้อง
สำหรับฉัน แก่นของการเขียนหวัดคือการไม่ยกปากกาขึ้นจากกระดาษ ดังนั้นวิธีเชื่อมตัวอักษรก็รวมอยู่ในตัวการเขียนตั้งแต่แรกแล้ว
ดูเหมือนว่าผู้เขียนจะไม่ได้เขียนแบบนั้นจริง ๆ เลยเกิดปัญหานี้ขึ้น
ถึงอย่างนั้น ส่วนที่เหลือของบทความซึ่งแก้ปัญหาด้วยวิธีที่ง่ายที่สุดในการวาดหลายตัวอักษรบนหน้าจอโดยไม่ไปแตะฟอนต์ก็สนุกมาก
ในการเขียนหวัด การเชื่อมระหว่างตัวอักษรนั้น ขึ้นกับบริบท
อย่างเช่นหลัง
bถัดไปเป็นaหรือoรูปร่างอาจเปลี่ยนไปเพื่อให้อ่านง่ายขึ้น และแม้แต่ภายในคำเดียวกัน บางกรณีก็อาจอยากยกปากการะหว่างตัวอักษรแต่นั่นก็ไม่ได้ถือว่าผิด “กฎ” ของการเขียนหวัด
คุณอาจเรียนมาอีกแบบและสิ่งที่เรียนมาก็อาจถูกต้อง แต่ฉันไม่ค่อยรู้จักรูปแบบการเขียนหวัดที่การเชื่อมไม่ควรขึ้นกับบริบท
แม้ในฟอนต์ที่ไม่เชื่อมติดกัน ก็ยังต้องเข้ารหัสว่าลำดับหลายตัวอักษรจะดูออกมาอย่างไร คล้ายกับ kerning
งดงาม! อยากให้มี ฟอนต์ลายมือแบบเขียนหวัด มากกว่านี้
งานที่ฉันทำไว้เมื่อ 2 ปีก่อนอยู่ที่นี่: https://certik.github.io/slabikar-otf/
เจ๋งดีนะ แต่ฉันอยากให้ลายมือของตัวเองดีพอที่จะอยากเอาไปทำเป็นฟอนต์ส่วนตัว :)
ถ้าเปลี่ยนขนาดตั้งต้นเป็น 200 แทน
< 14.5ก็จะกำหนดจุดเป็น 145 ได้ ทำให้ลดอักขระจุดทศนิยมไปได้หนึ่งตัวเห็นมีฟังก์ชันชื่อ
adjustอยู่ ฉันไม่ได้รู้สเปกฟอนต์มากนัก แต่สงสัยว่าถ้าทำ serialization ของ0,{x:12.2,y:13.2}เป็นแบบอื่น เช่น0,[12.2,13.2]แล้วค่อยแปลงในฟังก์ชันadjustจะเป็นยังไง