วิธีสร้างปลั๊กอิน Sketch ด้วย JavaScript, HTML และ CSS (ตอนที่ 1)

เผยแพร่แล้ว: 2022-03-10
สรุปอย่างรวดเร็ว ↬ หากคุณเคยทำงานกับ Sketch มีโอกาสมากมายที่คุณเคยคิดว่า “ถ้า Sketch เท่านั้นที่สามารถทำสิ่งนี้ได้เพียงอย่างเดียว ฉันก็จะสามารถทำงานให้สำเร็จลุล่วงได้ เร็วขึ้น ง่ายขึ้น และดีขึ้นมาก” ก็ไม่ต้องวิตกอีกต่อไป! ในบทความสองส่วนนี้ คุณจะได้เรียนรู้วิธีสร้างปลั๊กอิน Sketch ของเราเองตั้งแต่ต้น โดยมอบทักษะที่จำเป็นในการแก้ปัญหาประเภทนี้

บทช่วยสอนนี้มีไว้สำหรับผู้ที่รู้จักและใช้แอป Sketch และไม่กลัวที่จะเล่นโค้ด ในการทำกำไรให้ได้มากที่สุด คุณจะต้องมีประสบการณ์พื้นฐานในการเขียน JavaScript อย่างน้อย (และ HTML/CSS หรือไม่ก็ได้)

ปลั๊กอินที่เราจะสร้างเรียกว่า “โมเสค” ในส่วนที่หนึ่ง เราจะเรียนรู้เกี่ยวกับไฟล์พื้นฐานที่ประกอบเป็นปลั๊กอิน Sketch เราจะเขียน JavaScript และสร้างอินเทอร์เฟซผู้ใช้สำหรับปลั๊กอินของเราด้วยความช่วยเหลือของ HTML และ CSS บทความต่อไปจะเกี่ยวกับวิธีเชื่อมต่ออินเทอร์เฟซผู้ใช้กับโค้ดปลั๊กอินหลัก วิธีใช้งานคุณลักษณะหลักของปลั๊กอิน และในตอนท้าย คุณจะได้เรียนรู้วิธีเพิ่มประสิทธิภาพโค้ดและวิธีการทำงานของปลั๊กอินด้วย

ฉันจะแชร์โค้ดของปลั๊กอิน (JS, HTML, CSS) และไฟล์ที่คุณสามารถตรวจสอบและใช้เพื่อการเรียนรู้

ปลั๊กอิน Sketch คืออะไรและทำงานอย่างไร

ใน Sketch ปลั๊กอินเป็นวิธีเพิ่มคุณลักษณะและฟังก์ชันการทำงานที่ไม่มีอยู่ใน Sketch "แบบสำเร็จรูป" เมื่อพิจารณาว่าคุณลักษณะหรือการผสานรวมที่ขาดหายไปในโปรแกรมใดๆ เกือบทุกครั้ง (โดยเฉพาะอย่างยิ่งเมื่อพิจารณาจากความต้องการจำนวนมากที่นักออกแบบแต่ละคนอาจมี!) เราจึงสามารถเริ่มจินตนาการได้ว่าปลั๊กอินจะมีประโยชน์และทรงพลังเป็นพิเศษเพียงใด ปลั๊กอิน Sketch สามารถทำได้แทบทุกอย่างที่คุณคาดหวัง เช่น การจัดการสี รูปร่าง ขนาด ลำดับ สไตล์ การจัดกลุ่ม และเอฟเฟกต์ของเลเยอร์ แต่ยังสามารถทำสิ่งต่างๆ เช่น ร้องขอทรัพยากรอินเทอร์เน็ต นำเสนอผู้ใช้ อินเทอร์เฟซและอีกมากมาย!

ในด้านการเขียนโปรแกรม ปลั๊กอิน Sketch ทั้งหมดเขียนด้วยโค้ด JavaScript อันที่จริงไม่เป็นความจริง ทั้งหมด พูดได้ถูกต้องกว่าที่จะบอกว่าปลั๊กอิน Sketch ส่วนใหญ่ เขียนด้วย JavaScript เนื่องจากสามารถเขียนปลั๊กอิน Sketch ในภาษาการเขียนโปรแกรม Objective-C และ Swift ของ Apple ได้ แม้ว่าจะต้องมีความรู้เกี่ยวกับ JavaScript เพียงเล็กน้อยก็ตาม

ไม่ต้องกังวลแม้ว่า ในบทความนี้ เราจะเน้นที่วิธีสร้างปลั๊กอิน Sketch โดยใช้ JavaScript, HTML และ CSS เพียงอย่างเดียว เราจะไม่พูดถึงพื้นฐานของ HTML, CSS หรือ JavaScript — บทความนี้จะถือว่าอย่างน้อยมีความรู้และประสบการณ์กับทั้งสามสิ่งนี้ เว็บไซต์นักพัฒนา MDN เป็นสถานที่ที่ดีเยี่ยมในการเรียนรู้เพิ่มเติมเกี่ยวกับการพัฒนาเว็บ

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

มาเริ่มกันเลย!

ประการแรก เรากำลังทำอะไรอยู่?

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

ปลั๊กอินที่เราจะสร้างเรียกว่า Mosaic และเป็น "ตัวสร้างรูปแบบ" อย่างมีประสิทธิภาพ ป้อนเลเยอร์ของคุณ ปรับแต่งการตั้งค่าเล็กน้อย แล้วมันจะสร้างรูปแบบ:

รูปภาพแสดง UI ของปลั๊กอิน Mosaic และรูปแบบตัวอย่างบางส่วน
UI ของ Mosaic และตัวอย่างบางส่วนของรูปแบบที่สร้างขึ้น (ตัวอย่างขนาดใหญ่)

หากคุณต้องการติดตั้งและทดลองใช้ Mosaic คุณสามารถดาวน์โหลดปลั๊กอินที่เสร็จสมบูรณ์ได้จาก GitHub

ประวัติศาสตร์เล็กน้อย: โมเสกได้รับแรงบันดาลใจจากปลั๊กอิน Adobe Fireworks แบบเก่าที่เรียกว่า Twist-and-Fade Twist-and-Fade ค่อนข้างทรงพลัง สามารถทำซ้ำเลเยอร์ได้หลายครั้งในขณะที่ปรับสี ตำแหน่ง การหมุน ขนาด และความทึบ ปลั๊กอินยังสามารถสร้าง GIF แบบเคลื่อนไหวได้ เช่นเดียวกับที่สร้างเฟรมสำหรับองค์ประกอบที่หมุนได้ทั้งสองในเทปคาสเซ็ตต์:

ภาพแสดงเทปเพลงพร้อมกลองหมุน
เทปคาสเซ็ตต์เคลื่อนไหว (ที่มา) (ตัวอย่างขนาดใหญ่)

(นี่คือวิดีโอสาธิต Twist and Fade หากคุณสนใจที่จะได้เห็นว่ามันทำงานอย่างไร)

สำหรับจุดประสงค์ของบทช่วยสอนนี้ เราจะสร้างปลั๊กอินที่ค่อนข้างคล้ายคลึงกันสำหรับ Sketch แม้ว่าจะมีการทำให้เข้าใจง่ายขึ้นโดยตั้งใจ เพื่อให้บทช่วยสอนสามารถเข้าถึงได้มากที่สุด โดยเฉพาะอย่างยิ่ง ปลั๊กอินของเราจะสามารถ:

  • ทำซ้ำเลเยอร์ Sketch (บิตแมปหรือเวกเตอร์) และปรับแต่งตำแหน่ง การหมุน และความทึบของเลเยอร์ที่ซ้ำกัน ข้อมูลนี้จะแนะนำเราเกี่ยวกับการจัดการเลเยอร์โดยใช้ JavaScript API ของ Sketch
  • แสดงอินเทอร์เฟซผู้ใช้ที่สร้างขึ้นโดยใช้ HTML, CSS และ JS ซึ่งจะสอนคุณเกี่ยวกับวิธีสร้างอินเทอร์เฟซสำหรับปลั๊กอินอย่างง่ายดาย โดยใช้เทคโนโลยีเว็บที่คุณอาจคุ้นเคยอยู่แล้ว อินเทอร์เฟซของปลั๊กอินมีความสำคัญมาก เนื่องจากเป็นวิธีที่เราจะรวบรวมอินพุตของผู้ใช้ว่าผู้ใช้ต้องการให้ภาพโมเสคที่ออกมาเป็นอย่างไร

การสร้างปลั๊กอินพื้นฐานของเราในสิบวินาทีแบน

อันดับแรก เราจะสร้าง "ฐาน" (หรือเทมเพลต) สำหรับปลั๊กอินที่เราต้องการสร้าง เราสามารถสร้างไฟล์และโฟลเดอร์ที่จำเป็นทั้งหมดที่ประกอบขึ้นเป็นปลั๊กอินได้ด้วยตนเอง แต่โชคดีที่เราไม่จำเป็นต้องทำ เพราะ Sketch สามารถสร้างปลั๊กอินได้ หลังจากที่เราสร้างปลั๊กอินเทมเพลตแล้ว เราจะสามารถปรับแต่งได้ตามที่เห็นสมควร

มีเทคนิคที่ง่ายและรวดเร็วมากที่เราสามารถใช้เพื่อสร้างปลั๊กอินเทมเพลต ซึ่งเป็นวิธีการเกือบทุกอย่างของฉันเมื่อฉันต้องการรวมปลั๊กอินเข้าด้วยกันเพื่อแก้ปัญหาที่ฉันเผชิญในขณะนั้น นี่คือวิธีการทำงาน:

เมื่อเปิด Sketch ขึ้นมา ให้เลือกแถบเมนูที่ด้านบนของหน้าจอ แล้วคลิก Plugins -> Run Script ซึ่งจะเปิดกล่องโต้ตอบที่เราสามารถใช้ทดสอบและเรียกใช้โค้ดได้ นอกจากนี้เรายังสามารถบันทึกโค้ดใดๆ ที่เราป้อนเป็นปลั๊กอิน ซึ่งเป็นส่วนที่เราสนใจเป็นพิเศษในตอนนี้

ล้างรหัสที่มีอยู่แล้วในกล่องโต้ตอบนี้ และแทนที่ด้วยรหัสสาธิตต่อไปนี้:

 const UI = require("sketch/ui"); UI.message(" Hey there, you fantastic plugin developer you! This is your plugin! Talking to you from the digital computer screen! In Sketch! Simply stupendous!");

ถัดไป กด Save Script as Plugin ที่ด้านล่างซ้ายของหน้าต่าง ป้อนชื่อที่คุณต้องการให้ปลั๊กอินนี้มี (ในกรณีของเราคือ "โมเสค") จากนั้น Save Script as Plugin อีกครั้ง

กด "บันทึก" ที่ด้านล่างซ้ายของหน้าต่าง แล้วป้อนชื่อที่คุณต้องการให้ปลั๊กอินนี้มี (ตัวอย่างขนาดใหญ่)

เชื่อหรือไม่ เราทำเสร็จแล้ว เหลือแค่กินเค้กที่เราเพิ่งอบ มาถึงส่วนที่สนุก เมื่อเปิดเมนูปลั๊กอินอีกครั้ง คุณควรเห็นสิ่งนี้: ปลั๊กอินใหม่เอี่ยมของคุณถูกระบุว่าเป็น "โมเสค"! คลิกเลย!

(ตัวอย่างขนาดใหญ่)

ขอแสดงความยินดี คุณเพิ่งเขียนปลั๊กอิน Sketch แรกของคุณ!

สิ่งที่คุณควรเห็นหลังจากคลิก “โมเสก” ควรเป็นเหมือนวิดีโอสั้น ๆ ด้านบน โดยมีข้อความคำแนะนำเครื่องมือที่ไม่เป็นการรบกวนปรากฏขึ้นที่ด้านล่างของหน้าจอโดยขึ้นต้นด้วยคำว่า “เฮ้ … ทำ. นี่คือสิ่งที่ทำให้เทคนิคนี้ยอดเยี่ยมมาก: ทำให้ ง่ายต่อการวาง แก้ไข และทดสอบโค้ดโดยไม่ต้องสร้างปลั๊กอินตั้งแต่เริ่มต้น หากคุณคุ้นเคยหรือเคยเล่นกับเว็บคอนโซลของเบราว์เซอร์ ข้อมูลพื้นฐานก็คือ การมีเครื่องมือนี้อยู่ในกระเป๋าหลังของคุณในขณะที่คุณสร้างและทดสอบโค้ดเป็นสิ่งที่ต้องมี

มาสรุปกันสั้นๆ ว่าโค้ดที่คุณเพิ่มมีไว้ทำอะไร:

ขั้นแรก จะนำเข้าโมดูล Sketch sketch/ui ของไลบรารี JS ในตัวของ Sketch และกำหนดให้กับตัวแปร UI โมดูลนี้มีวิธีการที่เกี่ยวข้องกับอินเทอร์เฟซที่มีประโยชน์สองสามวิธี ซึ่งหนึ่งในนั้นเราจะใช้:

 const UI = require("sketch/ui");

ต่อไป จะเรียกเมธอด message (ซึ่งเป็นส่วนหนึ่งของโมดูล sketch/ui ) ด้วยสตริงข้อความที่เราต้องการให้แสดงในคำแนะนำเครื่องมือที่เราเห็น:

 UI.message(" Hey there, you fantastic plugin developer you! This is your plugin! Talking to you from the digital computer screen! In Sketch! Simply stupendous!");

เมธอด message() เป็นวิธีที่ยอดเยี่ยมในการนำเสนอข้อความที่ไม่สร้างความรำคาญให้กับผู้ใช้ เหมาะอย่างยิ่งสำหรับกรณีที่คุณไม่จำเป็นต้องขโมยโฟกัส (ไม่ใช่โมดอล) และไม่ต้องการปุ่มหรือฟิลด์ข้อความแฟนซี นอกจากนี้ยังมีวิธีอื่นๆ ในการนำเสนอองค์ประกอบ UI ทั่วไป เช่น การแจ้งเตือน การแจ้ง เป็นต้น ซึ่งเราจะใช้บางส่วนในการสร้าง Mosaic

การปรับแต่งข้อมูลเมตาของปลั๊กอิน

ตอนนี้เรามีปลั๊กอินพื้นฐานที่จะเริ่มต้นแล้ว แต่เรายังต้องปรับแต่งเพิ่มเติมและทำให้เป็นของเราอย่างแท้จริง ขั้นตอนต่อไปของเราคือการเปลี่ยนข้อมูลเมตาของปลั๊กอิน

สำหรับขั้นตอนนี้ เราจะต้องดูสิ่งที่เรียกว่า ชุดปลั๊กอิน เมื่อคุณกดบันทึกในหน้าต่าง 'เรียกใช้สคริปต์' Sketch จะบันทึกปลั๊กอินของคุณเป็นโฟลเดอร์ชื่อ Mosaic.sketchplugin ที่คุณสามารถหาได้ในไดเร็กทอรี ~/Library/Application Support/com.bohemiancoding.sketch3/Plugins มันค่อนข้างยาวและน่ารำคาญที่จะจำ เป็นทางลัด คุณสามารถดึงมันขึ้นมาได้โดยใช้ Plugins -> Manage Plugins -> (right-click your plugin) -> Reveal Plugins Folder แม้ว่าจะปรากฏใน Finder เป็นไฟล์เดียว แต่จริงๆ แล้วเป็นโฟลเดอร์ที่มีทุกอย่างที่ปลั๊กอินของเราต้องการให้ Sketch เรียกใช้ สาเหตุที่ปรากฏเป็นไฟล์เดียว ทั้งๆ ที่เป็นโฟลเดอร์ก็เพราะเมื่อคุณติดตั้ง Sketch ครั้งแรก Sketch ได้ลงทะเบียนนามสกุล .sketchplugin เป็น "bundle" (โฟลเดอร์ชนิดพิเศษที่ปรากฏเป็นไฟล์) และขอให้เปิดโดยอัตโนมัติ ใน Sketch เมื่อเปิด

มาดูข้างในกัน คลิกขวาที่ Mosaic.sketchplugin จากนั้นคลิก “แสดงเนื้อหาแพ็คเกจ” ภายใน คุณควรเห็นโครงสร้างไดเร็กทอรีต่อไปนี้:

 Contents/ └ Resources/ └ Sketch/ └ manifest.json └ script.cocoascript

คุณอาจสงสัยว่าเหตุใดจึงมีไฟล์ที่มีนามสกุล . .cocoascript ไม่ต้องกังวล มันเป็นเพียงไฟล์ JavaScript ปกติ และมีเฉพาะรหัสที่เราป้อนก่อนหน้านี้ ไปข้างหน้าและเปลี่ยนชื่อไฟล์นี้เป็น index.js ซึ่งจะเปลี่ยนโครงสร้างไดเร็กทอรีให้ดูเหมือนด้านล่าง:

 Contents/ └ Resources/ └ Sketch/ └ manifest.json └ index.js

วิธีทั่วไปในการจัดระเบียบไฟล์ภายในบันเดิลปลั๊กอินมีดังนี้: รหัสของคุณ (JavaScript) และ manifest.json อยู่ใน Sketch/ และทรัพยากร (คิดว่าเป็นรูปภาพ ไฟล์เสียง ไฟล์ข้อความ ฯลฯ) อยู่ใน Resources/

เริ่มต้นด้วยการปรับแต่งไฟล์ชื่อ manifest.json เปิดในโปรแกรมแก้ไขโค้ดที่คุณชื่นชอบ เช่น Visual Studio Code หรือ Atom

คุณจะเห็นว่าในขณะนี้มีค่อนข้างน้อยภายในนี้ แต่เราจะเพิ่มในเร็วๆ นี้ รายการปลั๊กอินมีจุดประสงค์หลักสองประการ:

  1. อันดับแรก จะให้ข้อมูลเมตาที่อธิบายปลั๊กอินแก่ผู้ใช้ เช่น ชื่อ เวอร์ชัน ชื่อผู้เขียน และอื่นๆ Sketch ใช้ข้อมูลนี้ในกล่องโต้ตอบ Sketch -> Preferences -> Plugins เพื่อสร้างรายการและคำอธิบายสำหรับปลั๊กอินของคุณ
  2. ประการที่สอง ยังบอก Sketch เกี่ยวกับวิธีการทำธุรกิจของคุณ นั่นคือ มันบอก Sketch ว่าคุณต้องการให้เมนูปลั๊กอินของคุณดูเป็นอย่างไร แป้นลัดใดที่จะกำหนดให้กับปลั๊กอินของคุณ และตำแหน่งที่โค้ดของปลั๊กอินของคุณอาศัยอยู่ (เพื่อให้ Sketch สามารถเรียกใช้ได้)

เมื่อพิจารณาถึงจุดประสงค์ #1 ในการอธิบายปลั๊กอินให้ผู้ใช้ฟัง คุณอาจสังเกตเห็นว่าขณะนี้ยังไม่มีคำอธิบาย หรือ ผู้แต่ง ซึ่งจะทำให้ผู้ใช้สับสนและทำให้ระบุปลั๊กอินได้ยาก มาแก้ไขโดยการปรับค่าของคีย์ที่เกี่ยวข้องเป็น:

 { "description": "Generate awesome designs and repeating patterns from your layers!", "author": "=> Your name here <=" }

ต่อไป มาปรับตัวระบุของปลั๊กอินกัน ตัวระบุนี้ใช้สิ่งที่เรียกว่า "สัญกรณ์โดเมนย้อนกลับ" ซึ่งเป็นวิธีที่กระชับ (หรือน่าเบื่อ เลือกของคุณ) เพื่อพูดว่า "นำโดเมนของไซต์ของคุณ ย้อนลำดับ แล้วใส่ชื่อผลิตภัณฑ์ของคุณต่อท้าย" สิ่งนี้จะออกมาเช่น: com.your-company-or-your-name-its-not-that-big-a-deal.yourproduct

คุณไม่จำเป็นต้องยึดติดกับรูปแบบการตั้งชื่อนี้ — คุณสามารถใส่อะไรก็ได้ที่คุณต้องการที่นี่ ตราบใดที่มันไม่ซ้ำกันพอที่จะหลีกเลี่ยงความขัดแย้งกับปลั๊กอินอื่น ๆ (แม้ว่า จะ เป็นความคิดที่ดีที่จะยึดติดกับรูปแบบ RDN โดยเฉพาะอย่างยิ่งเมื่อมีให้ ระบบที่เรียบง่าย ใช้ซ้ำได้สำหรับตัวระบุปลั๊กอินของคุณ)

ให้เปลี่ยนตัวระบุของคุณเป็น com.your-name.mosaic :

 { "identifier": "com.your-name.mosaic" }

โดยส่วนตัวแล้วฉันชอบนำคีย์ที่เกี่ยวข้องกับข้อมูลเมตาทั้งหมด (ชื่อ ผู้เขียน ตัวระบุ ฯลฯ) และจัดกลุ่มไว้ใกล้กับด้านบนสุดของไฟล์ Manifest เพื่อไม่ให้กระจายไปทั่วและช่วยรักษาสติของฉันเมื่อฉันต้องการค้นหา .

ต่อไปเรามาดูที่ menu และปุ่ม commands กัน สองคนนี้มีหน้าที่บอก Sketch ว่าจะเรียกโค้ดอะไรและตอบสนองต่ออะไร

หากคุณดูที่ปุ่ม menu คุณจะเห็นว่ามีคีย์ title ซึ่งค่าคือชื่อที่ปลั๊กอินของเราจะแสดงในเมนู Plugins นอกจากนี้ยังมีคีย์ items ซึ่งเป็นรายการของ ตัวระบุคำสั่ง :

 { "menu": { "title": "Mosaic", "items": [ "com.bohemiancoding.sketch.runscriptidentifier" ] } }

ขณะนี้มีตัวระบุคำสั่งเพียงตัวเดียวในรายการนี้ "com.bohemiancoding.sketch.runscriptidentifier" ตัวระบุคำสั่งจะชี้ไปที่คำสั่งในรายการ commands เสมอ ตอนนี้ปลั๊กอินของเรามีเพียงหนึ่งคำสั่ง ซึ่งเป็นคำสั่งที่มีตัวระบุนี้:

 { "commands": [ { "script" : "script.cocoascript", "name" : "Mosaic", "handlers" : { "run" : "onRun" }, "identifier" : "com.bohemiancoding.sketch.runscriptidentifier" } ] }

เมื่อใดก็ตามที่คุณเพิ่มตัวระบุคำสั่งลงในรายการ menu Sketch จะค้นหารายการคำสั่งที่มีตัวระบุนั้นและจะแสดงค่าของคีย์ name (ซึ่งในกรณีนี้คือ “โมเสค”) และจะแสดงรายการนั้นในเมนูปลั๊กอินของคุณแทน ของตัวระบุ

สำหรับบทบาทคำสั่งเล่น เราสามารถนึกถึงรายการคำสั่งเพื่อบอก Sketch ว่าฟังก์ชันใดในโค้ด JavaScript ของปลั๊กอินที่เราต้องการเรียกใช้เมื่อมีการเรียกใช้คำสั่งนั้น "การเรียกใช้" มักจะเป็นการคลิกที่ผู้ใช้ในเมนูที่เกี่ยวข้อง รายการ. รายการคำสั่งไม่ได้ดำเนินการใดๆ เลย เป็นเพียง JSON — มันเพียงให้ คำอธิบาย ใน Sketch ว่าจะค้นหา JavaScript ได้ที่ไหนเมื่อเรียกใช้คำสั่ง

จนถึงตอนนี้ เราได้พูดคุยเกี่ยวกับสิ่งที่ name คำสั่งและคีย์ identifier ทำ แต่มีอีกสองคีย์ในคำสั่งที่จำเป็นต้องได้รับการแก้ไข: script and handlers

คีย์ script จะบอก Sketch ว่าไฟล์ JavaScript ที่ควรรันอยู่ที่ใด สังเกตว่า Sketch ถือว่าไฟล์สคริปต์ที่เป็นปัญหาอยู่ในโฟลเดอร์ Sketch/ ซึ่งเป็นเหตุผลว่าทำไมคุณจึงต้องการให้แน่ใจว่าโค้ด JavaScript ทั้งหมดของคุณอยู่ที่ใดที่หนึ่งภายใต้โฟลเดอร์ Sketch/ ก่อนที่เราจะดำเนินการต่อจากคีย์ นี้ คุณต้องแน่ใจว่าคุณเปลี่ยนค่าของคีย์นี้เป็น index.js เช่นเดียวกับที่เราเปลี่ยนชื่อไฟล์ก่อนหน้านี้ มิเช่นนั้น Sketch จะไม่สามารถค้นหาและเรียกใช้ไฟล์ JavaScript ของคุณได้

ค่าของคีย์ handlers คือสิ่งที่ Sketch พิจารณาเพื่อกำหนดว่าฟังก์ชันใดใน JavaScript ที่จะเรียกใช้ ที่นี่เรามีชุดตัวจัดการเพียงชุดเดียว: run โดยมีค่า onRun run คือชื่อของการ ทำงาน Sketch ที่กำหนดไว้ล่วงหน้า การ run การนี้จะถูกเรียกเสมอเมื่อผู้ใช้คลิกรายการเมนูที่อ้างอิงคำสั่งนี้ onRun เป็น ชื่อ ของฟังก์ชันในไฟล์ script.cocoascript ที่สร้างขึ้นโดยอัตโนมัติ (ซึ่งเราเปลี่ยนชื่อเป็น index.js ) และฟังก์ชันที่เราต้องการให้เรียกใช้เมื่อเหตุการณ์การ run เกิดขึ้น กล่าวคือ เมื่อผู้ใช้คลิกรายการเมนู

ในตัวอย่างที่เรามีจนถึงตอนนี้ กระบวนการนี้มีลักษณะดังนี้:

  1. ผู้ใช้คลิกรายการเมนูของเรา
  2. Sketch ค้นหาคำสั่งที่เกี่ยวข้องกับรายการเมนูนั้น
  3. Sketch ค้นหาไฟล์สคริปต์ที่คำสั่งอ้างถึงและเรียกใช้ (ซึ่งในกรณีนี้หมายความว่ามันรัน JavaScript ใน index.js )
  4. เนื่องจากคำสั่งนี้เรียกใช้โดยการคลิกรายการเมนู จึงถือเป็นการดำเนินการ run นั่นหมายความว่า Sketch จะดูที่ค่า handlers.run ของคำสั่งสำหรับฟังก์ชันที่จะเรียกใช้ต่อไป ซึ่งในกรณีนี้คือ onRun
  5. Sketch เรียกใช้ฟังก์ชัน onRun

โดยทั่วไปจะเรียกคำสั่งเพื่อตอบสนองต่อผู้ใช้ที่คลิกรายการเมนูรายการใดรายการหนึ่งของคุณ แต่สามารถเรียกใช้เพื่อตอบสนองต่อการกระทำอื่นๆ ของผู้ใช้ได้ เช่น ผู้ใช้เปลี่ยนการเลือกหรือคุณสมบัติบนเลเยอร์ อย่างไรก็ตาม สำหรับปลั๊กอินนี้ เราจะไม่ใช้การดำเนินการอื่นๆ เหล่านี้ (คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับการดำเนินการและวิธีการทำงานในหน้าวิธีใช้ Action API)

ก่อนที่เราจะดำเนินการต่อจากรายการนี้ เราต้องการปรับแต่งอีกสองรายการ ตอนนี้เมนูของเรามีโครงสร้างดังนี้

 Mosaic └ Mosaic 
รูปภาพแสดงรายการเมนู Mosaic ซ้อนกันซ้ำซ้อนภายในเมนูอื่นชื่อ Mosaic
ค่อนข้างซ้ำซ้อนใช่มั้ย? (ตัวอย่างขนาดใหญ่)

…ซึ่งค่อนข้างซ้ำซ้อนเล็กน้อยเนื่องจากปลั๊กอินของเรามีรายการเมนูเดียวเท่านั้น นอกจากนี้ยังเพิ่มความเสียดทานที่ไม่จำเป็นให้กับผู้ใช้ของเรา เนื่องจากตอนนี้ปลั๊กอินของเราใช้การคลิกสองครั้งเพื่อเรียกใช้แทนที่จะเรียกใช้เพียงครั้งเดียว เราสามารถแก้ไขได้โดยเพิ่ม isRoot: true ลงใน menu ของเรา:

 { "menu": { "title" : "Mosaic", "items" : [ "com.bohemiancoding.sketch.runscriptidentifier" ], "isRoot": true } }

สิ่งนี้บอกให้ Sketch วางรายการเมนูระดับแรกไว้ใต้เมนู Plugins โดยตรง แทนที่จะซ้อนรายการเหล่านี้ไว้ใต้ title เมนู

กดบันทึกและกลับไปที่ Sketch คุณควรเห็นว่าตอนนี้ Mosaic -> Mosaic ถูกแทนที่ด้วย Mosaic — สมบูรณ์แบบ!

รูปภาพแสดง UI . ของปลั๊กอิน Mosaic
UI ของโมเสค (ตัวอย่างขนาดใหญ่)

สำหรับการปรับแต่งครั้งที่สอง เรามาเปลี่ยนชื่อตัวระบุคำสั่งนี้เป็นอะไรที่ยากกว่า เนื่องจากตัวระบุคำสั่งจะต้องไม่ซ้ำกันภายในบริบทของปลั๊กอินแต่ละตัว เราจึงสามารถเปลี่ยนชื่อให้สั้นกระชับและชัดเจนขึ้นได้อย่างปลอดภัย เช่น "open" :

 { "commands": [ { ... "identifier" : "open" } ], "menu": { ... "items" : [ "open" ] } }

ก่อนที่เราจะไปต่อ ควรสังเกตว่าเมนูสามารถประกอบด้วยเมนูอื่นๆ ได้เช่นกัน คุณสามารถสร้างเมนูย่อยได้ง่ายๆ โดยซ้อนรายการ { title: ..., items: ... } รายการอื่นภายใน items ของเมนูอื่น:

 { "menu": { "title" : "Mosaic", "items" : [ "open", { "title" : "I'm a sub-menu!", "items" : [ "another-command-identifier" ] } ] } }

การสร้างอินเทอร์เฟซผู้ใช้ของปลั๊กอิน

จนถึงตอนนี้ เราได้เขียนโค้ดสาธิตและปรับแต่งรายการของปลั๊กอิน ตอนนี้เราจะเริ่มสร้างอินเทอร์เฟซผู้ใช้ ซึ่งโดยพื้นฐานแล้วคือหน้าเว็บที่ฝังอยู่ในหน้าต่าง (คล้ายกับเบราว์เซอร์ที่คุณคุ้นเคย):

หน้าต่างของปลั๊กอิน (ตัวอย่างขนาดใหญ่)
รูปภาพแสดงส่วนประกอบที่ประกอบขึ้นเป็นอินเทอร์เฟซของปลั๊กอิน: มุมมองหน้าต่างและเว็บ
ส่วนประกอบที่ประกอบขึ้นเป็นปลั๊กอินของเรา (ตัวอย่างขนาดใหญ่)

หน้าต่าง

การออกแบบส่วนต่อประสานผู้ใช้ของ Mosaic มีหน้าต่างของตัวเอง ซึ่งเราสามารถพิจารณาองค์ประกอบพื้นฐานที่สุดได้ เราจะเริ่มต้นด้วยมัน ในการสร้างและแสดงหน้าต่าง เราจะต้องใช้คลาสที่สร้างไว้ใน macOS โดยค่าเริ่มต้น เรียกว่า NSWindow ตลอดช่วงที่เหลือของบทช่วยสอนนี้ เราจะทำสิ่งนี้กันสักหน่อย (โดยใช้ API ในตัว เช่น NSWindow ) ซึ่งอาจดูน่ากลัวเล็กน้อยหากคุณไม่คุ้นเคย แต่ไม่ต้องกังวล ฉันจะอธิบาย ตลอดทาง!

หมายเหตุ: ในขณะที่เรากำลังพูดถึง API ในตัว เหตุผลที่เราสามารถใช้คลาสนี้ ได้ ก็ต้องขอบคุณบริดจ์ที่มีอยู่ในรันไทม์ JavaScript ที่ใช้โดยปลั๊กอิน Sketch บริดจ์นี้จะนำเข้าคลาส เมธอด และฟังก์ชันในตัวเหล่านี้โดยอัตโนมัติ ซึ่งโดยปกติแล้วจะพร้อมใช้งานสำหรับแอปพลิเคชันดั้งเดิมเท่านั้น

เปิด Sketch/index.js ในตัวแก้ไขโค้ดของคุณ ลบที่มีอยู่แล้ววางลงในรายการต่อไปนี้:

 function onRun(context){ const window = NSWindow.alloc().initWithContentRect_styleMask_backing_defer_( NSMakeRect(0, 0, 145, 500), NSWindowStyleMaskClosable | NSWindowStyleMaskTitled | NSWindowStyleMaskResizable, NSBackingStoreBuffered, false ); window.releasedWhenClosed = false; window.makeKeyAndOrderFront(nil); };

มาดูกันดีกว่าว่าโค้ดบิตแรกนี้ทำอะไรได้บ้าง:

 function onRun(context){

จำได้ไหมว่าก่อนหน้านี้เมื่อเราพูดถึงคำสั่งและวิธีการทำงาน และเราบอกให้ Sketch โทรตอบสนองต่อการคลิกเมนูเรียกว่า onRun ? (ถ้าคุณต้องการทบทวน ให้ทบทวนส่วนนั้นด้านบน แล้วกลับมาใหม่) บิตทั้งหมดนี้สร้างฟังก์ชันนั้น คุณจะสังเกตเห็นว่าฟังก์ชัน onRun ของเราใช้อาร์กิวเมนต์ context นี่เป็นอาร์กิวเมนต์ Sketch จะเรียกตัวจัดการคำสั่งของคุณซึ่งสามารถให้ข้อมูลบางอย่างแก่เราได้ ต่อมา เราจะใช้เพื่อรับ URL ของชุดปลั๊กอินของเราบนคอมพิวเตอร์ของผู้ใช้

 const window = NSWindow.alloc().initWithContentRect_styleMask_backing_defer( NSMakeRect(0, 0, 145, 500), NSWindowStyleMaskClosable | NSWindowStyleMaskTitled | NSWindowStyleMaskResizable, NSBackingStoreBuffered, false );

เรากำลังดำเนินการบางอย่างอยู่:

  1. อันดับแรก เราเรียก alloc() บน NSWindow ; โดยพื้นฐานแล้วหมายถึง "จัดสรรหน่วยความจำบางส่วนสำหรับอินสแตนซ์ของ NSWindow" เพียงพอแล้วที่จะรู้ว่าคุณจะต้องทำเช่นนี้กับ ทุกอินสแตนซ์ ของคลาสดั้งเดิมที่คุณต้องการสร้าง เมธอด alloc มีอยู่ในคลาสเนทีฟทุกคลาส
  2. ต่อไป เราเรียกวิธีการเริ่มต้นของ NSWindow (นั่นคือวิธีที่สร้างอินสแตนซ์ของ NSWindow จริง ๆ ) ซึ่งมีชื่อว่า initWithContentRect:styleMask:backing:defer: คุณจะสังเกตเห็นว่ามันแตกต่างจากที่เราเรียกในโค้ดด้านบนนี้ — มันมีโคลอน ( : ) จำนวนมากอยู่ระหว่างอาร์กิวเมนต์ทุกข้อ เนื่องจากเราไม่สามารถใช้ไวยากรณ์นั้นใน JavaScript ได้ Sketch จึงเปลี่ยนชื่อเป็นสิ่งที่เรา สามารถใช้ได้ จริงโดยสะดวกโดยการแทนที่โคลอนด้วยเครื่องหมายขีดล่าง ซึ่งเป็นวิธีที่เราได้รับชื่อ JS: initWithContentRect_styleMask_backing_defer
  3. ต่อไป เราจะส่งต่อข้อโต้แย้งแต่ละข้อที่เมธอดต้องการ สำหรับอาร์กิวเมนต์แรก contentRect เราจัดหาสี่เหลี่ยมผืนผ้าที่มีขนาดที่ใหญ่พอสำหรับส่วนต่อประสานผู้ใช้ของเรา
  4. สำหรับ styleMask เราใช้บิตมาสก์ที่ระบุว่าเราต้องการให้หน้าต่างของเรามีปุ่มปิด แถบชื่อเรื่อง และปรับขนาดได้
  5. อาร์กิวเมนต์สองข้อถัดไปคือ backing และ defer จะถูกตั้งค่าเป็น NSBackingStoreBuffered และ false เสมอ ดังนั้นเราจึงไม่จำเป็นต้องกังวลเกี่ยวกับสิ่งเหล่านี้จริงๆ (เอกสารสำหรับวิธีนี้มีรายละเอียดเพิ่มเติมว่าเหตุใดจึงเป็นเช่นนี้)
 window.releasedWhenClosed = false; window.makeKeyAndOrderFront(null);

ที่นี่เราตั้งค่าคุณสมบัติ releasedWhenClosed ของ NSWindow เป็น false ซึ่งหมายความว่า: “เฮ้! อย่าลบหน้าต่างนี้ออกจากหน่วยความจำเพียงเพราะผู้ใช้ปิดหน้าต่างนี้” จากนั้นเราเรียก makeKeyAndOrderFront (null) ซึ่งหมายความว่า: "ย้ายหน้าต่างนี้ไปที่แถวหน้า และกำหนดโฟกัสของแป้นพิมพ์"

มุมมองเว็บ: อินเทอร์เฟซ

เพื่อให้ง่ายขึ้น ฉันได้เขียนโค้ด HTML และ CSS ของอินเทอร์เฟซผู้ใช้บนเว็บของปลั๊กอินที่เราจะใช้แล้ว โค้ดเดียวที่เหลืออยู่ที่เราจะต้องเพิ่มเข้าไปจะจัดการเพื่อให้แน่ใจว่าเราสามารถสื่อสารระหว่างโค้ดดังกล่าวกับโค้ดปลั๊กอิน Sketch ของเราได้

ถัดไป ดาวน์โหลดโค้ด HTML และ CSS เมื่อคุณดาวน์โหลดแล้ว ให้แตกไฟล์ จากนั้นย้ายโฟลเดอร์ชื่อ “web-ui” ไปไว้ในโฟลเดอร์ทรัพยากรของปลั๊กอิน

หมายเหตุ : การเขียนและการเพิ่มประสิทธิภาพโค้ด HTML/CSS จริงอยู่นอกเหนือขอบเขตของบทช่วยสอนนี้ เนื่องจากเน้นที่ JavaScript ซึ่งสนับสนุนคุณลักษณะหลักของปลั๊กอิน แต่มีบทช่วยสอนมากมายบนเว็บในหัวข้อนี้ หากคุณต้องการเรียนรู้เพิ่มเติม

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

เราจะเพิ่มโค้ดที่จำเป็นในการสร้าง WKWebView ใต้โค้ดที่เราเขียนสำหรับหน้าต่างของเรา:

 function onRun(context){ // Create window const window = NSWindow.alloc().initWithContentRect_styleMask_backing_defer( NSMakeRect(0, 0, 145, 500), NSWindowStyleMaskClosable | NSWindowStyleMaskTitled | NSWindowStyleMaskResizable, NSBackingStoreBuffered, false ); window.releasedWhenClosed = false; // Create web view, and set it as the view for our window to display const webView = WKWebView.alloc().init(); window.contentView = webView; // Load our UI into the web view const webUIFolderURL = context.scriptURL .URLByDeletingLastPathComponent() .URLByAppendingPathComponent("../Resources/web-ui/"); const indexURL = webUIFolderURL.URLByAppendingPathComponent("index.html"); webView.loadFileURL_allowingReadAccessToURL(indexURL, webUIFolderURL); // Make window key and move to front window.makeKeyAndOrderFront(nil); };

หากเราเรียกใช้ปลั๊กอินในตอนนี้ เราจะเห็นว่าตอนนี้เรามีหน้าต่างที่เปิดขึ้นซึ่งแสดงส่วนต่อประสานผู้ใช้บนเว็บของเรา ความสำเร็จ!

อีกครั้ง ก่อนดำเนินการต่อ ให้ตรวจสอบว่าโค้ดที่เราเพิ่มเข้าไปทำอะไรได้บ้าง:

 const webView = WKWebView.alloc().init();

สิ่งนี้ควรดูคุ้นเคย — โดยพื้นฐานแล้วจะเหมือนกับสิ่งที่เราทำเมื่อเราสร้าง NSWindow : จัดสรรหน่วยความจำสำหรับมุมมองเว็บ แล้วเริ่มต้น

 window.contentView = webView;

โค้ดบรรทัดนี้บอกให้หน้าต่างแสดงมุมมองเว็บที่เราเพิ่งสร้าง

 const webUIFolderURL = context.scriptURL .URLByDeletingLastPathComponent() .URLByAppendingPathComponent("../Resources/web-ui/");

เป้าหมายของเราคือการสร้าง URL ที่ชี้ไปยังโฟลเดอร์ web-ui ที่เราทำไว้ก่อนหน้านี้ ในการรับ URL นั้น เราต้องการวิธีหาว่าบันเดิลปลั๊กอินของเราอยู่ที่ใดในระบบไฟล์ของผู้ใช้ ที่นี่เราใช้คุณสมบัติ context.scriptURL ซึ่งทำให้เรามี URL ของ สคริปต์ที่กำลังทำงาน อยู่ อย่างไรก็ตาม สิ่งนี้ไม่ได้ให้ String JavaScript แก่เราอย่างที่คุณคาดหวัง แต่อินสแตนซ์ของคลาสดั้งเดิม NSURL ที่มีวิธีการบางอย่างที่ทำให้การจัดการสตริง URL ง่ายขึ้น

เราจำเป็นต้องเปลี่ยนสิ่งที่ context.scriptURL มอบให้เรา —

 file://path-to-your-plugin/Contents/Sketch/index.js

- เข้าไปข้างใน:

 file://path-to-your-plugin/Contents/Resources/web-ui/

เป็นขั้นเป็นตอน:

  1. การเรียก URLByDeletingLastPathComponent() ในครั้งแรกทำให้เรามี file://path-to-your-plugin/Contents/Sketch/
  2. การเรียก URLByDeletingLastPathComponent() อีกครั้งทำให้เราได้ file://path-to-your-plugin/Contents/
  3. และสุดท้าย การเพิ่ม Resources/web-ui/ ต่อท้ายโดยใช้ URLByAppendingPathComponent ("Resources/web-ui/") ทำให้เรา file://path-to-your-plugin/Contents/Resources/web-ui/

เรายังต้องสร้าง URL ที่สองที่ชี้ไปที่ไฟล์ index.html โดยตรง:

 const indexURL = webUIFolderURL.URLByAppendingPathComponent("index.html");

สุดท้าย เราบอกให้มุมมองเว็บโหลด index.html และให้สิทธิ์เข้าถึงเนื้อหาของโฟลเดอร์ web-ui :

 webView.loadFileURL_allowingReadAccessToURL(indexURL, webUIFolderURL);

ไม่เป็นอะไร. จนถึงตอนนี้ เรามีหน้าต่างที่แสดงส่วนต่อประสานกับผู้ใช้เว็บของเรา ตามที่เราต้องการ อย่างไรก็ตาม มันยังไม่สมบูรณ์ — การออกแบบดั้งเดิมของเราไม่มีแถบชื่อเรื่อง (หรือ “โครเมียม”) แต่หน้าต่างปัจจุบันของเรามี นอกจากนี้ยังมีข้อเท็จจริงที่ว่าเมื่อเราคลิกภายในเอกสาร Sketch เอกสารนั้นจะย้ายไปที่หน้าหน้าต่างของเรา ซึ่งไม่ใช่สิ่งที่เราต้องการ เราต้องการให้ผู้ใช้สามารถโต้ตอบกับหน้าต่างปลั๊กอิน และ เอกสาร Sketch โดยไม่ต้อง โฟกัสใหม่อย่างต่อเนื่องจากหน้าต่างหนึ่งไปอีกหน้าต่างหนึ่ง

ในการแก้ไขปัญหานี้ ก่อนอื่นเราต้องกำจัด Chrome เริ่มต้นของหน้าต่างและเก็บปุ่มไว้เท่านั้น การเพิ่มโค้ดสองบรรทัดด้านล่างจะเป็นการกำจัดแถบชื่อเรื่อง

หมายเหตุ: เช่นเดียวกับเมื่อก่อน คุณสมบัติและวิธีการทั้งหมดที่เราใช้ด้านล่างนี้ได้รับการบันทึกไว้ในหน้าเอกสารประกอบของ NSWindow

 window.titlebarAppearsTransparent = true; window.titleVisibility = NSWindowTitleHidden;

โค้ดสองบรรทัดถัดไปนี้จะลบปุ่มหน้าต่าง (หรือที่เรียกว่า "สัญญาณไฟจราจร" ในศัพท์แสงของ MacOS) ที่เราไม่ต้องการ เช่น "ซูม" และ "ย่อเล็กสุด" โดยเหลือเพียงปุ่ม "ปิด":

 window.standardWindowButton(NSWindowZoomButton).hidden = true; window.standardWindowButton(NSWindowMiniaturizeButton).hidden = true;

ในขณะที่เรากำลังดำเนินการอยู่ เรามาเปลี่ยนสีพื้นหลังของหน้าต่างให้เข้ากับ UI เว็บของเรากันเถอะ:

 window.backgroundColor = NSColor.colorWithRed_green_blue_alpha(1, 0.98, 0.98, 1);

ต่อไป เราต้องทำอะไรบางอย่างเพื่อให้หน้าต่างปลั๊กอินแบบลอยของเราอยู่ด้านบนของหน้าต่างอื่นๆ เพื่อให้ผู้ใช้สามารถโต้ตอบกับเอกสาร Sketch ของพวกเขาโดยไม่ต้องกังวลว่าหน้าต่างของ Mosaic จะหายไป เราสามารถใช้ NSWindow ชนิดพิเศษได้ ซึ่งเรียกว่า NSPanel ซึ่งสามารถ "อยู่ด้านบนสุด" ของหน้าต่างอื่นได้ ทั้งหมดที่จำเป็นสำหรับสิ่งนี้คือการเปลี่ยน NSWindow เป็น NSPanel ซึ่งเป็นการเปลี่ยนแปลงโค้ดบรรทัดเดียว:

 const window = NSPanel.alloc().initWithContentRect_styleMask_backing_defer(

ตอนนี้เราบอกให้หน้าต่างพาเนลของเราลอย (อยู่เหนือส่วนอื่นทั้งหมด) และใช้การโฟกัสของแป้นพิมพ์/เมาส์เมื่อจำเป็นเท่านั้น:

 window.floatingPanel = true; window.becomesKeyOnlyIfNeeded = true;

เรายังปรับแต่งหน้าต่างของเราให้เปิดใหม่โดยอัตโนมัติในตำแหน่งสุดท้ายที่:

 window.frameAutosaveName = "mosaic-panel-frame";

บรรทัดนี้โดยพื้นฐานแล้วบอกว่า "จำตำแหน่งของหน้าต่างนี้ด้วยการบันทึกด้วยการตั้งค่าของ Sketch ภายใต้กรอบ mosaic-panel-frame หลัก"

เมื่อรวมกันแล้ว เรามีรหัสดังต่อไปนี้:

 function onRun(context){ // Create window const window = NSPanel.alloc().initWithContentRect_styleMask_backing_defer( NSMakeRect(0, 0, 145, 500), NSWindowStyleMaskClosable | NSWindowStyleMaskTitled | NSWindowStyleMaskResizable, NSBackingStoreBuffered, false ); window.becomesKeyOnlyIfNeeded = true; window.floatingPanel = true; window.frameAutosaveName = "mosaic-panel-frame"; window.releasedWhenClosed = false; window.standardWindowButton(NSWindowZoomButton).hidden = true; window.standardWindowButton(NSWindowMiniaturizeButton).hidden = true; window.titlebarAppearsTransparent = true; window.titleVisibility = NSWindowTitleHidden; window.backgroundColor = NSColor.colorWithRed_green_blue_alpha(1, 0.98, 0.98, 1); // Create web view, and set it as the view for our window to display const webView = WKWebView.alloc().init(); window.contentView = webView; // Load our UI into the webview const webUIFolderURL = context.scriptURL .URLByDeletingLastPathComponent() .URLByAppendingPathComponent("../Resources/web-ui/"); const indexURL = webUIFolderURL.URLByAppendingPathComponent("index.html"); webView.loadFileURL_allowingReadAccessToURL(indexURL, webUIFolderURL); // Make window key and move to front window.makeKeyAndOrderFront(nil); };

การจัดระเบียบรหัส

ก่อนที่เราจะไปยังส่วนถัดไป เป็นความคิดที่ดีที่จะจัดระเบียบโค้ดของเราเพื่อให้นำทางและปรับแต่งได้ง่ายขึ้น เนื่องจากเรายังมีโค้ดที่ต้องเพิ่มอีกมาก และเราต้องการหลีกเลี่ยง index.js ที่กลายเป็นจุดทิ้งขยะสำหรับโค้ดทั้งหมดของเรา มาแยกส่วนกันเล็กน้อยและย้ายโค้ดเฉพาะ UI ของเราไปเป็นไฟล์ชื่อ ui.js ภายใต้โฟลเดอร์ Sketch นอกจากนี้ เราจะแยกงาน UI บางอย่างที่เราทำ เช่น การสร้างมุมมองเว็บและหน้าต่าง ออกเป็นฟังก์ชันของตัวเอง

สร้างไฟล์ใหม่ชื่อ ui.js และใส่โค้ดด้านล่างเข้าไป:

 // Private var _window; function createWebView(pageURL){ const webView = WKWebView.alloc().init(); webView.loadFileURL_allowingReadAccessToURL(pageURL, pageURL.URLByDeletingLastPathComponent()); return webView; }; function createWindow(){ const window = NSPanel.alloc().initWithContentRect_styleMask_backing_defer( NSMakeRect(0, 0, 420, 646), NSWindowStyleMaskClosable | NSWindowStyleMaskTitled | NSWindowStyleMaskResizable, NSBackingStoreBuffered, false ); window.becomesKeyOnlyIfNeeded = true; window.floatingPanel = true; window.frameAutosaveName = "mosaic-panel-frame"; window.releasedWhenClosed = false; window.standardWindowButton(NSWindowZoomButton).hidden = true; window.standardWindowButton(NSWindowMiniaturizeButton).hidden = true; window.titlebarAppearsTransparent = true; window.titleVisibility = NSWindowTitleHidden; window.backgroundColor = NSColor.colorWithRed_green_blue_alpha(1, 0.98, 0.98, 1); return window; }; function showWindow(window){ window.makeKeyAndOrderFront(nil); }; // Public function loadAndShow(baseURL){ if(_window){ showWindow(_window); return; } const pageURL = baseURL .URLByDeletingLastPathComponent() .URLByAppendingPathComponent("../Resources/web-ui/index.html"); const window = createWindow(); const webView = createWebView(pageURL); window.contentView = webView; _window = window; showWindow(_window); }; function cleanup(){ if(_window){ _window.orderOut(nil); _window = null; } }; // Export module.exports = { loadAndShow, cleanup };

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

สังเกต module.exports = { loadAndShow, cleanup } บรรทัดที่ด้านล่าง? นี่เป็นวิธีให้เราระบุอย่างชัดเจนว่าสคริปต์ของอ็อบเจ็กต์และฟังก์ชันใดที่นำเข้าโค้ด UI นี้สามารถใช้ได้ (และซ่อนสิ่งที่เราไม่ต้องการให้พวกเขากังวล) ซึ่งหมายความว่าตอนนี้เรามี API ที่มีการจัดระเบียบมากขึ้นสำหรับการโต้ตอบด้วย แสดงและทำลาย UI ของเรา

การอ่านที่แนะนำ : ปลดปล่อยศักยภาพของสัญลักษณ์ในร่าง

ลองดูว่าสิ่งนี้มีลักษณะอย่างไรในทางปฏิบัติ กลับไปที่ index.js ลบโค้ดเก่าและเพิ่มสิ่งต่อไปนี้:

 const UI = require("./ui"); function onRun(context){ UI.loadAndShow(context.scriptURL); };

เรากำลังใช้ฟังก์ชันพิเศษที่ Sketch require ให้ใช้งานได้โดยอัตโนมัติ เพื่อนำเข้าโค้ด ui.js และกำหนดโมดูลที่ส่งคืนให้กับตัวแปร UI สิ่งนี้ทำให้เราเข้าถึง API แบบง่ายสำหรับการทริกเกอร์ส่วนต่อประสานผู้ใช้ของเรา ตอนนี้สิ่งต่าง ๆ เป็นระเบียบมากขึ้นและหาง่าย!

บทสรุป

ทำได้ดีมาก คุณมาไกลแล้ว! In the next part of this tutorial, we'll give our web UI the ability to send us a message when the “Apply” button is clicked, and we'll focus on the main plugin functionality: actually generating layer mosaics!