これは、 Sketch 3 のプラグインに未来を見た男の物語である。つまり Sketch Developer の要約とメモ。
プラグインで何ができるのか
- 複雑なルールに基づいて、ドキュメント内のものを選択する
- レイヤーのプロパティを操作する
- 新しいレイヤーを作成する
- サポートされている全てのフォーマットでアセットを出力する
- ユーザからの入力を受け付けたり、ユーザへ示すことができる
- 外部ファイルやウェブサービスからデータを取得することができる
- クリップボードを使うことができる
- Sketch の環境を操作することができる (ガイド、ズームなど)
- プラグインからメニューを呼び出すことにより、既存の機能を自動化する
ちなみに例えば、こんなプラグインがある
イントロダクション
プラグインの動かしかた
インストールする方法で変わるので、 Sketch > Plugins > Reveal Plugins Folder
からパスを確認する。基本的にここに置いておけば自動認識して Plugins
の中に表示される
JSTalk
SketchPlguin を記述する言語は JSTalk です。 JavaScript と Obj-C を混ぜて2で割って全部捨てた感じがする。
拡張子は、プラグイン本体は .sketchplugin
。外部ファイルとして .jstalk
, .js
が使える。
注意
-
3.0.2 で YES, NO が消えた
何か元々 true, false の alias だったらしいですがそれが消えました。なので、サンプルコードとかで YES, NO が使われてても使えません。もしくは自分で alias 貼ってください。
標準変数
Sketch Plugin からアクセスできるグローバルな標準変数
-
doc
:MSDocument
のインスタンス。現在のドキュメントへの参照を持つ。 -
selection
:NSArray
のインスタンス。現在選択しているレイヤーたち -
scriptPath
:NSString
のインスタンス。現在のプラグインへのパス。
Cocoa へのアクセス
JSTalk スクリプトから Cocoa API へアクセスできる。以下は、 File Picker panel を開く例である。
// NSOpenPanel クラスを使う
var openPanel = [NSOpenPanel openPanel]
[openPanel setCanChooseDirectories:false]
[openPanel setCanChooseFiles:true]
[openPanel setCanCreateDirectories:false]
[openPanel setDirectoryURL:[NSURL fileURLWithPath:"~/Documents/"]]
[openPanel setTitle:@"Choose a file"]
[openPanel setPrompt:@"Choose"]
[openPanel runModal]
デバッグ
基本的に以下のようなコードを埋め込むと、 system.log へ出力してくれる。らしい。
log(SOME_VALUE);
-
Console.app で拾う ← まちがい
-
tail で拾う ← せいかい
$ tail -f /var/log/system.log|grep Sketch
おまけ
何か適当に alert 出したりしたかったら
- alert, [doc showMessage], Cocoa dialogs 何かが使える
- もしくは Sam Deane’s log panel こういう感じのテクを使う
基本情報
Plugin をまたいだ共通のコードの作り方
#import 'path/to/file'
のように、 #import
文が使えるので、それで共通のファイルを読み込む。
- 読み込むファイルは jstalk, js のどちらでも読める
-
#import
文は必ずシングルクォートで囲む - インポートされたファイル内の検索パスは、現在のフォルダ, プラグインのルートフォルダ の順になる
選択対象に対して Plugin を動作させる
上にかいた selection
を使います。現在選択されてるオブジェクトたちが入った NSArray
[selection count]
で現在の選択数が取れる
// count を使ってみる
if ([selection count] == 0) {
// nothing is selected
}
// 回してみる
for (var i = 0; i < [selection count]; i++) {
// do something with item
var item = selection[i]
}
// Obj-C みたいに回すこともできる
var loop = [selection objectEnumerator]
while (item [loop nextObject]) {
// dosomething with item
}
選択解除
[page deselectAllLayers]
をつかう
// 現在のページで選択しているアイテムを解除する
[[doc currentPage] deselectAllLayers]
アイテムを選択する
コードから指定したアイテムを洗濯する場合は、 MSLayer がもつ select:byExpandingSelection
を使う
// 全選択解除
[[doc currentPage] deselectAllLayers]
var allLayers = [[doc currentPage] layers]
for (var i = 0; i < [allLayers length]; i++) {
var layer = allLayers[i]
if ([layer name] == "Rectangle") {
[layer select:false byExpandingSelection:true]
}
}
ユーザ入力を取得する
[doc askForUserInput]
を使って、ユーザからの値を得ることができる。また、 initialValue
でデフォルトの値を入れておくこともできる。
var name = [doc askForUserInput:"What is your name?" initialValue:""]
Note initialValue
は必須の引数。"" (空文字) を指定すれば空にできる。
より複雑なユーザ入力を行う場合は NSAlert クラスを用いる。
function createSelect(msg, items, selectedItemIndex) {
selectedItemIndex = selectedItemIndex || 0
var accessory = [[NSComboBox alloc] initWithFrame:NSMakeRect(0, 0, 200, 25)
[accessory addItemsWithObjectValues:items]
[accessory selectItemAtIndex:selectedItemIndex]
var alert = [[NSAlert alloc] init]
[alert setMessageText:msg]
[alert addButtonWithTitle:'OK']
[alert addButtonWithTitle:'CANCEL']
[alert setAccessoryView:accessory]
var responseCode = [alert runModel]
var sel = [accessory indexOfSelectedItem]
return [responseCode, sel]
}
var options = ['None', 'One', 'Two', 'Three']
var choice = createSelect('Choose an option', options, 1)
log(choice)
フィードバック
ユーザに対して何らかのフィードバックを返す場合、 [doc showMessage]
もしくは [NSApplication displayDialog]
を使う。前者は一行のメッセージが表示でき、後者はタイトルと内容付きのアラートダイアログが表示できる
// [doc showMessage]
[doc showMessage:"The operation is complete"]
// NSApplication
var app = [NSApplication sharedApplication]
[app displayDialog:"The operation is complete" withTitle:"We're done"]