JavaScript, HTML 및 CSS로 스케치 플러그인을 빌드하는 방법(1부)
게시 됨: 2022-03-10이 튜토리얼은 Sketch 앱을 알고 사용하며 코드 사용을 두려워하지 않는 사람들을 대상으로 합니다. 이를 최대한 활용하려면 JavaScript(및 선택적으로 HTML/CSS) 작성에 대한 최소한의 기본 경험이 필요합니다.
우리가 만들 플러그인은 "모자이크"입니다. 1부에서는 Sketch 플러그인을 구성하는 기본 파일에 대해 알아보겠습니다. HTML과 CSS를 사용하여 JavaScript를 작성하고 플러그인에 대한 사용자 인터페이스를 만들 것입니다. 다음 기사에서는 사용자 인터페이스를 핵심 플러그인 코드에 연결하는 방법, 플러그인의 주요 기능을 구현하는 방법에 대해 설명하고 마지막에는 코드를 최적화하는 방법과 플러그인 작동 방식도 배우게 됩니다.
또한 플러그인의 코드(JS, HTML, CSS)와 학습 목적으로 검토하고 사용할 수 있는 파일을 공유할 것입니다.
스케치 플러그인이란 무엇이며 어떻게 작동합니까?
Sketch에서 플러그인은 Sketch에 없는 기능을 "즉시" 추가할 수 있는 방법입니다. 주어진 프로그램에 거의 항상 누락된 기능이나 통합이 있다는 점을 고려하면(특히 개별 디자이너가 가질 수 있는 방대한 요구 사항을 감안할 때!) 플러그인이 어떻게 특히 유용하고 강력할지 상상할 수 있습니다. 스케치 플러그인은 색상, 모양, 크기, 순서, 스타일, 그룹화 및 레이어 효과를 조작하는 것과 같이 사용자가 예상하는 거의 모든 작업을 수행할 수 있을 뿐만 아니라 인터넷 리소스에 요청하고 사용자에게 표시하는 것과 같은 작업도 수행할 수 있습니다. 인터페이스, 그리고 훨씬 더!
프로그래밍 측면에서 모든 Sketch 플러그인은 JavaScript 코드로 작성됩니다. 사실, 그것은 완전히 사실이 아닙니다. 대부분 의 Sketch 플러그인이 JavaScript로 작성되었다고 말하는 것이 더 정확합니다. Apple의 프로그래밍 언어 중 하나인 Objective-C 및 Swift 중 하나로 Sketch 플러그인을 작성하는 것도 가능하기 때문입니다. 비록 약간의 JavaScript 지식이 필요하더라도 말이죠.
하지만 걱정하지 마십시오. 이 기사에서는 JavaScript, HTML 및 CSS 만 사용하여 Sketch 플러그인을 빌드하는 방법에 중점을 둘 것입니다. HTML, CSS 또는 JavaScript의 기본 사항은 다루지 않을 것입니다. 이 기사에서는 이 세 가지 모두에 대한 최소한의 지식과 경험이 있다고 가정합니다. MDN 개발자 웹사이트는 웹 개발에 대해 더 많이 배울 수 있는 좋은 장소를 제공합니다.
시작하자!
첫째, 우리는 무엇을 만들고 있습니까?
이 튜토리얼에서는 레이어를 생성, 복제 및 수정할 수 있을 뿐만 아니라 사용자에게 멋진 사용자 인터페이스를 제공할 수 있는 기본적이고 초보자 친화적인 플러그인을 구축하는 방법을 알려 드리겠습니다. 그렇게 함으로써, 제 목표는 기반으로 할 수 있는 기본적인 지식을 확립하고 이를 사용하여 자신만의 플러그인을 만드는 것입니다.
우리가 만들 플러그인은 모자이크 라고 하며 사실상 "패턴 생성기"입니다. 레이어를 제공하고 몇 가지 설정을 조정하면 패턴이 생성됩니다.
Mosaic을 설치하고 놀고 싶다면 GitHub에서 완성된 플러그인을 다운로드할 수 있습니다.
약간의 역사: Mosaic은 대부분 Twist-and-Fade 라는 구식 Adobe Fireworks 플러그인에서 영감을 받았습니다. Twist-and-Fade는 색조, 위치, 회전, 크기 및 불투명도를 조정하면서 레이어를 여러 번 복제할 수 있는 매우 강력했습니다. 플러그인은 다음과 같은 애니메이션 GIF도 생성할 수 있었습니다. 여기에서 카세트 테이프에 있는 두 개의 회전 요소에 대한 프레임을 생성했습니다.
(정확하게 어떻게 작동하는지 알고 싶다면 Twist와 Fade를 시연하는 비디오가 있습니다.)
이 튜토리얼의 목적을 위해 우리는 튜토리얼을 가능한 한 액세스할 수 있도록 의도적으로 단순화했지만 Sketch용으로 다소 유사한 플러그인을 빌드할 것입니다. 특히 플러그인은 다음을 수행할 수 있습니다.
- 스케치 레이어(비트맵 또는 벡터)를 복제하고 복제 레이어의 위치, 회전 및 불투명도를 조정합니다. Sketch의 JavaScript API를 사용하여 레이어를 조작하는 방법을 소개합니다.
- HTML, CSS 및 JS를 사용하여 만든 사용자 인터페이스를 표시합니다. 이 인터페이스에서는 이미 친숙한 웹 기술을 사용하여 플러그인 인터페이스를 쉽게 만드는 방법을 알려줍니다. 플러그인 인터페이스는 사용자가 결과 모자이크 이미지가 어떻게 보이길 원하는지에 대한 사용자 입력을 수집하는 방법이기 때문에 매우 중요합니다.
10초 만에 기본 플러그인 만들기
먼저 빌드하려는 플러그인에 대한 "기본"(또는 템플릿)을 생성합니다. 플러그인을 구성하는 데 필요한 모든 파일과 폴더를 수동으로 만들 수 있지만 다행히 그럴 필요가 없습니다. 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 플러그인을 작성하셨습니다!
"모자이크"를 클릭한 후 볼 수 있는 것은 위의 짧은 비디오와 같아야 합니다. 화면 하단에 "Hey there..."라는 단어로 시작하는 눈에 잘 띄지 않는 툴팁 메시지가 표시됩니다. 할 것. 이것이 이 기술을 훌륭하게 만드는 이유 입니다. 플러그인을 처음부터 빌드하지 않고도 코드를 쉽게 붙여넣고, 수정하고, 테스트할 수 있습니다. 브라우저의 웹 콘솔에 익숙하거나 사용해 본 적이 있다면 기본적으로 그렇습니다. 코드를 빌드하고 테스트할 때 이 도구를 주머니에 넣어두는 것은 필수품입니다.
추가한 코드가 하는 일을 간략히 살펴보겠습니다.
먼저 Sketch에 내장된 JS 라이브러리의 sketch/ui
모듈을 가져와서 UI
변수에 할당합니다. 이 모듈에는 몇 가지 유용한 인터페이스 관련 메서드가 포함되어 있으며 그 중 하나를 사용할 것입니다.
const UI = require("sketch/ui");
다음으로, 우리가 본 툴팁에 표시하려는 텍스트 문자열을 사용하여 ( sketch/ui
모듈의 일부인) message
메서드를 호출합니다.
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는 ~/Library/Application Support/com.bohemiancoding.sketch3/Plugins
디렉토리에서 찾을 수 있는 Mosaic.sketchplugin
이라는 폴더로 플러그인을 저장했습니다. 그것은 기억하기가 약간 길고 성가시다. 바로 가기로 Plugins -> Manage Plugins -> (right-click your plugin) -> Reveal Plugins Folder
를 통해 가져올 수도 있습니다. Finder에 단일 파일로 표시되지만 실제로는 플러그인이 Sketch를 실행하는 데 필요한 모든 것이 포함된 폴더입니다. 폴더 임에도 불구하고 단일 파일로 표시되는 이유는 Sketch를 처음 설치할 때 Sketch에서 .sketchplugin
확장자를 "번들"(파일로 표시되는 특수한 종류의 폴더)로 등록하고 자동으로 열리도록 요청했기 때문입니다. 스케치에서 열 때.
내부를 살펴보겠습니다. 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과 같은 즐겨 사용하는 코드 편집기에서 엽니다.
현재로서는 내부에 비교적 적은 양이 있지만 곧 더 추가할 예정입니다. 플러그인 매니페스트는 주로 두 가지 용도로 사용됩니다.
- 첫째, 플러그인을 설명하는 메타데이터(이름, 버전, 작성자 이름 등)를 사용자에게 제공합니다. Sketch는
Sketch -> Preferences -> Plugins
대화 상자에서 이 정보를 사용하여 플러그인에 대한 목록과 설명을 생성합니다. - 둘째, 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" }
저는 개인적으로 모든 메타데이터 관련 키(제목, 작성자, 식별자 등)를 가져와 매니페스트 상단 근처에 그룹화하여 모든 곳에 흩어져 있지 않도록 하고 찾을 필요가 있을 때 제 정신을 유지하는 데 도움이 됩니다. .
다음으로 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
키(이 경우 "모자이크") 값을 표시하고 대신 플러그인 메뉴에 표시합니다. 식별자의.
역할 명령이 수행하는 역할과 관련하여 명령 입력은 플러그인의 JavaScript 코드에서 해당 명령이 호출될 때 실행하려는 기능이 무엇인지 Sketch에 알리는 방법으로 생각할 수 있습니다. "호출"은 일반적으로 관련 메뉴에서 사용자가 클릭하는 것입니다. 안건. 명령 항목은 자체적으로 아무 작업도 수행하지 않으며 단지 JSON일 뿐입니다. 단순히 명령이 호출될 때 실행해야 하는 JavaScript를 찾을 위치에 대한 설명 을 Sketch에 제공합니다.
지금까지 명령의 name
과 identifier
키가 하는 일에 대해 이야기했지만 명령에는 script
와 handlers
라는 두 개의 다른 키를 지정해야 합니다.
script
키는 Sketch가 실행해야 하는 JavaScript 파일의 위치를 알려줍니다. Sketch가 문제의 스크립트 파일이 Sketch/
폴더에 있다고 가정하는 방법에 유의하십시오. 따라서 단순성을 위해 모든 JavaScript 코드가 Sketch/
폴더 아래 어딘가에 있는지 확인하고 싶을 것입니다. 이 키에서 이동하기 전에 이전에 파일 이름을 바꾼 것처럼 이 키의 값을 index.js
로 변경하는 것이 중요 합니다. 그렇지 않으면 Sketch가 JavaScript 파일을 찾아 실행할 수 없습니다.
handlers
키의 값은 Sketch가 JavaScript에서 호출할 함수를 결정하기 위해 확인하는 것입니다. 여기에서는 onRun
값을 가진 run
이라는 하나의 핸들러 세트만 있습니다. run
은 미리 정의된 기본 제공 Sketch 작업 의 이름입니다. 이 run
작업은 사용자가 이 명령을 참조하는 메뉴 항목을 클릭할 때 항상 호출됩니다. onRun
은 자동 생성된 script.cocoascript
파일( index.js
로 이름 변경)에 있는 함수의 이름 이며 run
이벤트가 발생할 때, 즉 사용자가 메뉴 항목을 클릭할 때 호출하려는 함수입니다.
지금까지의 예에서 이 프로세스는 다음과 같이 수행됩니다.
- 사용자가 메뉴 항목을 클릭합니다.
- Sketch는 해당 메뉴 항목과 관련된 명령을 찾습니다.
- Sketch는 명령이 참조하는 스크립트 파일을 찾아 실행합니다(이 경우
index.js
에서 JavaScript를 실행함을 의미합니다). - 이 명령은 메뉴 항목 클릭에 의해 호출되었으므로
run
작업으로 간주됩니다. 즉, Sketch는 다음에 호출할 함수에 대한 명령의handlers.run
값을 확인합니다. 이 경우에는onRun
입니다. - 스케치는
onRun
함수를 호출합니다.
명령은 가장 일반적으로 메뉴 항목 중 하나를 클릭한 사용자에 대한 응답으로 호출되지만 사용자가 레이어의 선택 항목이나 속성을 변경하는 것과 같은 다른 사용자 작업에 대한 응답으로 호출될 수도 있습니다. 그러나 이 플러그인의 경우 이러한 다른 작업은 사용하지 않습니다. (액션 API 도움말 페이지에서 작업 및 작동 방식에 대해 자세히 알아볼 수 있습니다.)
이 매니페스트에서 계속 진행하기 전에 두 가지 다른 조정을 하고 싶습니다. 현재 메뉴의 구조는 다음과 같습니다.
Mosaic └ Mosaic
... 플러그인에는 메뉴 항목이 하나만 있기 때문에 약간 중복됩니다. 또한 플러그인이 이제 한 번의 클릭이 아닌 두 번의 클릭으로 호출되기 때문에 사용자에게 약간의 불필요한 마찰이 추가됩니다. menu
에 isRoot: true
를 추가하여 이 문제를 해결할 수 있습니다.
{ "menu": { "title" : "Mosaic", "items" : [ "com.bohemiancoding.sketch.runscriptidentifier" ], "isRoot": true } }
이것은 메뉴 항목의 첫 번째 수준을 메뉴 title
아래에 중첩하지 않고 Plugins
메뉴 바로 아래에 배치하도록 Sketch에 지시합니다.
저장을 누르고 스케치로 돌아갑니다. 이제 Mosaic -> Mosaic
이 Mosaic
으로 대체되었음을 알 수 있습니다. 완벽합니다!
두 번째 조정에 관해서는 이 명령 식별자의 이름을 다루기 힘든 이름으로 바꾸겠습니다. 명령 식별자는 개별 플러그인의 컨텍스트 내에서만 고유하면 되므로 "open"
과 같이 보다 간결하고 명확한 이름으로 안전하게 이름을 바꿀 수 있습니다.
{ "commands": [ { ... "identifier" : "open" } ], "menu": { ... "items" : [ "open" ] } }
계속 진행하기 전에 메뉴에 다른 메뉴도 포함될 수 있다는 점에 유의하는 것이 좋습니다. 다른 메뉴의 items
목록 안에 다른 { title: ..., items: ... }
항목을 중첩하여 하위 메뉴를 쉽게 만들 수 있습니다.
{ "menu": { "title" : "Mosaic", "items" : [ "open", { "title" : "I'm a sub-menu!", "items" : [ "another-command-identifier" ] } ] } }
플러그인의 사용자 인터페이스 구축
지금까지 데모 코드를 작성하고 플러그인 매니페스트를 사용자 정의했습니다. 이제 기본적으로 창에 포함된 웹 페이지인 사용자 인터페이스를 만드는 것으로 넘어갈 것입니다.
창
Mosaic의 사용자 인터페이스 디자인에는 가장 기본적인 구성 요소라고 할 수 있는 자체 창이 있습니다. 시작하겠습니다. 창을 만들고 표시하려면 기본적으로 macOS에 내장된 NSWindow
라는 클래스를 사용해야 합니다. 이 튜토리얼의 나머지 부분에서 우리는 실제로 이것을 꽤 많이 할 것입니다( NSWindow
와 같은 내장 API 사용). 익숙하지 않은 경우 약간 어려울 수 있지만 걱정하지 마십시오. 설명하겠습니다. 길을 따라 모든 것!
참고: 내장 API에 대해 이야기하는 동안 이 클래스 를 전혀 사용할 수 없는 이유는 Sketch 플러그인에서 사용하는 JavaScript 런타임에 있는 브리지 덕분입니다. 이 브리지는 일반적으로 기본 응용 프로그램에서만 사용할 수 있는 이러한 내장 클래스, 메서드 및 기능을 자동으로 가져옵니다.
코드 편집기에서 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 );
여기에서 실제로 몇 가지 작업을 수행하고 있습니다.
- 먼저
NSWindow
에서alloc()
을 호출합니다. 이것은 기본적으로 "NSWindow 인스턴스를 위해 일부 메모리를 따로 설정"을 의미합니다. 생성하려는 네이티브 클래스의 모든 인스턴스 에 대해 이 작업을 수행해야 한다는 것을 아는 것으로 충분합니다.alloc
메소드는 모든 네이티브 클래스에서 사용할 수 있습니다. - 다음으로,
NSWindow
의 초기화 메서드(즉, 실제로NSWindow
의 인스턴스를 생성하는 메서드)를 호출합니다. 이 메서드는initWithContentRect:styleMask:backing:defer:
로 명명됩니다. 위의 코드에서 호출한 것과는 다른 점을 알 수 있습니다. 모든 인수 사이에 콜론(:
)이 많이 있습니다. JavaScript에서는 해당 구문을 사용할 수 없기 때문에 Sketch는 콜론을 밑줄로 대체하여 실제로 사용할 수 있는 것으로 편리하게 이름을 바꿉니다. 이것이 JS 이름인initWithContentRect_styleMask_backing_defer
를 얻는 방법입니다. - 다음으로 메서드에 필요한 각 인수를 전달합니다. 첫 번째 인수인
contentRect
에 대해 사용자 인터페이스에 충분히 큰 크기의 직사각형을 제공합니다. -
styleMask
의 경우 창에 닫기 버튼과 제목 표시줄이 있고 크기를 조정할 수 있는 비트마스크를 사용합니다. - 다음 두 인수
backing
및defer
는 항상NSBackingStoreBuffered
및false
로 설정되므로 걱정할 필요가 없습니다. (이 방법에 대한 문서는 그 이유에 대해 자세히 설명합니다.)
window.releasedWhenClosed = false; window.makeKeyAndOrderFront(null);
여기에서 NSWindow
의 releasedWhenClosed
속성을 false
로 설정했습니다. 이는 “Hey! 사용자가 창을 닫았다고 해서 메모리에서 이 창을 삭제하지 마십시오." 그런 다음 makeKeyAndOrderFront
(null)
를 호출합니다. 이는 "이 창을 맨 앞으로 이동하고 키보드 포커스를 제공합니다."를 의미합니다.
웹 보기: 인터페이스
일을 더 쉽게 하기 위해 우리가 사용할 플러그인 웹 사용자 인터페이스의 HTML 및 CSS 코드를 이미 작성했습니다. 추가해야 할 남아 있는 유일한 코드는 이 코드와 Sketch 플러그인 코드 간에 통신할 수 있는지 확인하는 것입니다.
다음으로 HTML 및 CSS 코드를 다운로드합니다. 다운로드한 후 압축을 푼 다음 "web-ui"라는 폴더를 플러그인의 Resources 폴더로 이동합니다.
참고 : 실제 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/");
여기서 우리의 목표는 이전에 만든 web-ui
폴더를 가리키는 URL을 만드는 것입니다. 해당 URL을 얻으려면 플러그인 번들이 사용자의 파일 시스템에서 어디에 있는지 알아낼 방법이 필요합니다. 여기에서 현재 실행 중인 스크립트 의 URL을 제공하는 context.scriptURL
속성을 사용합니다. 그러나 이것은 예상한 대로 JavaScript String
을 제공하지 않지만 URL 문자열을 더 쉽게 조작할 수 있도록 하는 몇 가지 메서드가 있는 기본 클래스인 NSURL
의 인스턴스를 제공합니다.
context.scriptURL
이 제공하는 것을 바꿔야 합니다.
file://path-to-your-plugin/Contents/Sketch/index.js
- 안으로:
file://path-to-your-plugin/Contents/Resources/web-ui/
단계별:
-
URLByDeletingLastPathComponent()
를 처음 호출하면file://path-to-your-plugin/Contents/Sketch/
제공됩니다. -
URLByDeletingLastPathComponent()
를 다시 호출하면file://path-to-your-plugin/Contents/
제공됩니다. - 마지막으로
URLByAppendingPathComponent
("Resources/web-ui/")
를 사용하여 끝에Resources/web-ui/
를 추가하면file://path-to-your-plugin/Contents/Resources/web-ui/
제공됩니다.
또한 index.html
파일을 직접 가리키는 두 번째 URL도 만들어야 합니다.
const indexURL = webUIFolderURL.URLByAppendingPathComponent("index.html");
마지막으로 웹 보기에 index.html
을 로드하고 web-ui
폴더의 내용에 대한 액세스 권한을 부여하도록 지시합니다.
webView.loadFileURL_allowingReadAccessToURL(indexURL, webUIFolderURL);
괜찮은. 지금까지 원하는 대로 웹 사용자 인터페이스를 표시하는 창이 있습니다. 그러나 아직 완전하지는 않습니다. 원래 디자인에는 제목 표시줄(또는 "크롬")이 없지만 현재 창에는 있습니다. 또한 Sketch 문서 내부를 클릭하면 해당 문서가 창 앞으로 이동하는데 이는 우리가 원하지 않습니다. 사용자가 별도의 작업 없이 플러그인 창 및 Sketch 문서와 상호 작용할 수 있기를 바랍니다. 한 창에서 다른 창으로 지속적으로 초점을 다시 맞춥니다.
이 문제를 해결하려면 먼저 기본 창 크롬을 제거하고 버튼만 유지해야 합니다. 아래에 두 줄의 코드를 추가하면 제목 표시줄이 제거됩니다.
참고: 이전과 마찬가지로 아래에서 사용하는 모든 속성과 메서드는 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);
다음으로, 사용자가 Mosaic의 창이 사라지는 것에 대해 걱정할 필요 없이 Sketch 문서와 상호 작용할 수 있도록 부동 플러그인 창을 다른 창 위에 유지하기 위해 무언가를 해야 합니다. 이를 위해 NSPanel
이라고 하는 특별한 유형의 NSWindow
를 사용할 수 있습니다. 이는 다른 창의 "최상위"에 있을 수 있습니다. 이를 위해 필요한 것은 NSWindow
를 NSPanel
로 변경하는 것입니다. 이는 한 줄의 코드 변경입니다.
const window = NSPanel.alloc().initWithContentRect_styleMask_backing_defer(
이제 패널 창에 부동(다른 모든 창 위에 유지)하고 필요할 때만 키보드/마우스 포커스를 가져오도록 지시합니다.
window.floatingPanel = true; window.becomesKeyOnlyIfNeeded = true;
마지막 위치에서 자동으로 다시 열리도록 창을 조정할 수도 있습니다.
window.frameAutosaveName = "mosaic-panel-frame";
이 줄은 기본적으로 "키 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 코드를 가져오는 스크립트가 사용할 수 있는 객체와 함수를 정확히 지정하는 방법입니다(그리고 걱정하고 싶지 않은 것은 숨김). UI를 보여주고 파괴합니다.
추천 자료 : 스케치에서 상징의 잠재력을 최대한 발휘하기
이것이 실제로 어떻게 보이는지 봅시다. index.js
로 돌아가서 이전 코드를 제거하고 다음을 추가합니다.
const UI = require("./ui"); function onRun(context){ UI.loadAndShow(context.scriptURL); };
우리는 require
코드를 가져 ui.js
반환된 모듈을 UI
변수에 할당하기 위해 Sketch가 자동으로 사용할 수 있도록 하는 특별한 기능을 사용하고 있습니다. 이를 통해 사용자 인터페이스를 트리거하기 위한 간소화된 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!