JavaScript、HTML、CSSを使用してSketchプラグインを作成する方法(パート1)
公開: 2022-03-10このチュートリアルは、Sketchアプリを知っていて使用していて、コードに手を出すことを恐れない人を対象としています。 それを最大限に活用するには、JavaScript(および、オプションでHTML / CSS)を作成するための基本的な経験が少なくともある程度必要です。
作成するプラグインは「モザイク」と呼ばれます。 パート1では、Sketchプラグインを構成する基本的なファイルについて学習します。 JavaScriptを記述し、HTMLとCSSを使用してプラグインのユーザーインターフェイスを作成します。 次の記事では、ユーザーインターフェイスをコアプラグインコードに接続する方法、プラグインの主な機能を実装する方法について説明します。最後に、コードを最適化する方法とプラグインの動作についても学習します。
また、プラグインのコード(JS、HTML、CSS)と、学習目的で調べて使用できるファイルを共有します。
スケッチプラグインとは何ですか、そしてそれらはどのように機能しますか?
Sketchでは、プラグインは「箱から出して」Sketchにはない機能を追加する方法です。 特定のプログラムにはほとんどの場合、機能や統合が欠けていることを考えると(特に、個々の設計者が持つ可能性のある膨大な数のニーズを考えると)、プラグインが特に便利で強力であることが想像できます。 スケッチプラグインは、レイヤーの色、形、サイズ、順序、スタイル、グループ化、効果の操作など、期待するほとんどすべてのことを実行できますが、インターネットリソースへのリクエスト、ユーザーの提示なども実行できます。インターフェイス、およびはるかに!
プログラミング側では、すべてのSketchプラグインはJavaScriptコードで記述されています。 まあ、実際には、それは完全に真実ではありません。 ほとんどのSketchプラグインはJavaScriptで記述されていると言った方が正確です。これは、JavaScriptの知識が少し必要な場合でも、Appleのプログラミング言語の1つであるObjective-CとSwiftでSketchプラグインを記述できるためです。
でも心配しないでください。 この記事では、JavaScript、HTML、およびCSSのみを使用してSketchプラグインを構築する方法に焦点を当てます。 HTML、CSS、またはJavaScriptの基本については説明しません。この記事では、これら3つすべてに関する知識と経験が少なくともある程度あることを前提としています。 MDN開発者のWebサイトは、Web開発についてさらに学ぶのに最適な場所です。
始めましょう!
まず、私たちは何を作っていますか?
このチュートリアルでは、レイヤーを作成、複製、変更できる基本的な初心者向けのプラグインを作成する方法と、ユーザーに優れたユーザーインターフェイスを提供する方法を説明します。 そうすることで、私の目標は、独自のプラグインを作成するために構築および使用できる基本的な知識を確立することです。
構築するプラグインはMosaicと呼ばれ、事実上「パターンジェネレーター」です。 レイヤーをフィードし、いくつかの設定を微調整すると、パターンが作成されます。
Mosaicをインストールして試してみたい場合は、完成したプラグインをGitHubからダウンロードできます。
ちょっとした歴史:Mosaicの大部分は、 Twist-and-Fadeと呼ばれる昔ながらのAdobeFireworksプラグインに触発されています。 ツイストアンドフェードは非常に強力で、色相、位置、回転、サイズ、不透明度を調整しながら、レイヤーを何度でも複製できました。 プラグインは、このようなアニメーションGIFを生成することもでき、カセットテープ内の2つの回転要素のフレームを作成しました。
(これがどのように機能するかを正確に確認したい場合は、ツイストとフェードのデモビデオをご覧ください。)
このチュートリアルの目的のために、Sketch用のやや類似したプラグインを構築しますが、チュートリアルにできるだけアクセスできるように意図的に簡略化しています。 具体的には、プラグインは次のことができるようになります。
- スケッチレイヤー(ビットマップまたはベクター)を複製し、複製したレイヤーの位置、回転、不透明度を微調整します。 これにより、SketchのJavaScriptAPIを使用してレイヤーを操作する方法を紹介します。
- HTML、CSS、およびJSを使用して作成されたユーザーインターフェイスを表示します。これにより、既に使い慣れているWebテクノロジを使用して、プラグインのインターフェイスを簡単に作成する方法がわかります。 プラグインインターフェイスは、ユーザーが結果のモザイク画像をどのように表示するかに関するユーザーの入力を収集する方法であるため、非常に重要です。
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…」という単語で始まる目立たないツールチップメッセージが表示されます。これは、貼り付けたコードが正確に示しているものです。やること。 これが、この手法を非常に優れたものにしている理由です。プラグインを最初から作成しなくても、コードの貼り付け、変更、テストが簡単になります。 ブラウザのWebコンソールに精通している、またはこれまでに遊んだことがある場合、これは基本的にそれです。 コードをビルドしてテストするときに、このツールをバックポケットに入れることは必須です。
追加したコードの機能を簡単に説明してみましょう。
まず、Sketchの組み込みJSライブラリのsketch/ui
モジュールをインポートし、それをUI
変数に割り当てます。 このモジュールには、いくつかの便利なインターフェイス関連のメソッドが含まれています。そのうちの1つを使用します。
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
拡張子を「バンドル」(ファイルとして表示される特殊な種類のフォルダ)として登録し、自動的に開くように要求したためです。開いたときに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 StudioCodeやAtomなどのお気に入りのコードエディター内で開きます。
現時点では、ここの内部は比較的少ないことがわかりますが、すぐに追加します。 プラグインマニフェストは、主に2つの目的を果たします。
- まず、プラグインを説明するメタデータ(名前、バージョン、作成者の名前など)をユーザーに提供します。 Sketchは、
Sketch -> Preferences -> Plugins
]ダイアログでこの情報を使用して、プラグインのリストと説明を作成します。 - 第二に、それはまたあなたのビジネスに取り掛かる方法についてスケッチに伝えます。 つまり、プラグインのメニューをどのように表示するか、プラグインに割り当てるホットキー、およびプラグインのコードが存在する場所(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
キーを見てみましょう。 これら2つは、Sketchにどのコードを呼び出すか、そして何に応答するかを指示する責任があります。
menu
キーを見ると、 title
キーが含まれていることがわかります。その値は、プラグインがPlugins
メニューに表示される名前です。 また、コマンド識別子のリストであるitems
キーもあります。
{ "menu": { "title": "Mosaic", "items": [ "com.bohemiancoding.sketch.runscriptidentifier" ] } }
現在、このリストには"com.bohemiancoding.sketch.runscriptidentifier"
1つのコマンド識別子しかありません。 コマンドIDは、常にcommands
リスト内のコマンドを指します。 現在、プラグインには1つのコマンドしかありません。これは、次の識別子を持つコマンドです。
{ "commands": [ { "script" : "script.cocoascript", "name" : "Mosaic", "handlers" : { "run" : "onRun" }, "identifier" : "com.bohemiancoding.sketch.runscriptidentifier" } ] }
menu
エントリにコマンド識別子を追加するたびに、Sketchはその識別子を持つコマンドエントリを検索し、そのname
キー(この場合は「Mosaic」)の値を表示し、代わりにプラグインのメニューに表示します識別子の。
コマンドが果たす役割については、コマンドエントリは、プラグインのJavaScriptコードで、そのコマンドが呼び出されたときに実行する関数をSketchに指示する方法と考えることができます。「呼び出し」は通常、ユーザーが関連メニューをクリックすることです。アイテム。 コマンドエントリはそれ自体では何もしません。JSONだけです。コマンドが呼び出されたときに実行する必要のあるJavaScriptを探す場所をSketchに説明するだけです。
これまで、コマンドのname
キーとidentifier
キーの機能について説明してきましたが、コマンドには、 script
とhandlers
という2つのキーを指定する必要があります。
script
キーは、実行するJavaScriptファイルの場所をSketchに指示します。 問題のスクリプトファイルがSketch/
フォルダーにあると、Sketchがどのように想定しているかに注意してください。そのため、簡単にするために、すべてのJavaScriptコードがSketch/
フォルダーの下にあることを確認する必要があります。 このキーから先に進む前に、前にファイルの名前を変更したのと同じように、このキーの値をindex.js
に変更することを確認することが重要です。 そうしないと、SketchはJavaScriptファイルを見つけて実行できません。
handlers
キーの値は、JavaScriptで呼び出す関数を決定するためにSketchが調べるものです。 ここでは、ハンドラーセットが1つだけありますrun
、値はonRun
です。 run
は、事前定義された組み込みのSketchアクションの名前です。 このrun
アクションは、ユーザーがこのコマンドを参照するメニュー項目をクリックすると常に呼び出されます。 onRun
は、自動生成されたscript.cocoascript
ファイル( index.js
に名前を変更)内の関数の名前であり、 run
イベントが発生したとき、つまりユーザーがメニュー項目をクリックしたときに呼び出される関数です。
これまでの例では、このプロセスは次のようになります。
- ユーザーがメニュー項目をクリックします。
- Sketchは、そのメニュー項目に関連付けられているコマンドを見つけます。
- Sketchは、コマンドが参照するスクリプトファイルを見つけて実行します(この場合、
index.js
でJavaScriptを実行します)。 - このコマンドはメニュー項目のクリックによって呼び出されたため、
run
アクションと見なされます。 つまり、Sketchは、次に呼び出す関数(この場合はonRun
)のコマンドのhandlers.run
値を調べます。 - Sketchは
onRun
関数を呼び出します。
コマンドは、ユーザーがメニュー項目の1つをクリックしたことに応答して呼び出されるのが最も一般的ですが、ユーザーが選択範囲やレイヤーのプロパティを変更するなど、他のユーザーアクションに応答して呼び出すこともできます。 ただし、このプラグインでは、これらの他のアクションは使用しません。 (アクションとその動作について詳しくは、Action APIヘルプページをご覧ください。)
このマニフェストから先に進む前に、他に2つの調整を行います。 現在、メニューの構造は次のとおりです。
Mosaic └ Mosaic
…プラグインにはメニュー項目が1つしかないため、これは少し冗長です。 また、プラグインを呼び出すのに1回ではなく2回クリックするようになったため、ユーザーに少し不必要な摩擦が加わります。 これを修正するには、 menu
にisRoot: true
を追加します。
{ "menu": { "title" : "Mosaic", "items" : [ "com.bohemiancoding.sketch.runscriptidentifier" ], "isRoot": true } }
これにより、Sketchは、メニューのtitle
の下にネストするのではなく、 Plugins
メニューのすぐ下に最初のレベルのメニュー項目を配置するように指示されます。
保存を押してSketchに戻ります。 これで、 Mosaic -> Mosaic
がMosaic
だけに置き換えられたことがわかります。完璧です。
2番目の調整については、先に進んで、このコマンド識別子の名前を扱いにくいものに変更しましょう。 コマンド識別子は個々のプラグインのコンテキスト内で一意である必要があるだけなので、 "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" ] } ] } }
プラグインのユーザーインターフェイスの構築
これまでに、いくつかのデモコードを記述し、プラグインのマニフェストをカスタマイズしました。 次に、ユーザーインターフェイスの作成に移ります。これは、基本的にウィンドウに埋め込まれたWebページです(使い慣れたブラウザーと同様)。
窓
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){
コマンドとその機能について話し、メニュークリックに応答して呼び出すように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
の場合、ウィンドウに閉じるボタンとタイトルバーを設定し、サイズを変更できるようにすることを示すビットマスクを使用します。 - 次の2つの引数、
backing
とdefer
は、常にNSBackingStoreBuffered
とfalse
に設定されるため、これらについて心配する必要はありません。 (このメソッドのドキュメントでは、これがなぜであるかについてさらに詳しく説明しています。)
window.releasedWhenClosed = false; window.makeKeyAndOrderFront(null);
ここでは、 NSWindow
のreleasedWhenClosed
プロパティをfalse
に設定します。これは、次のことを意味します。 ユーザーがウィンドウを閉じたからといって、このウィンドウをメモリから削除しないでください。」 次に、 makeKeyAndOrderFront
(null)
を呼び出します。これは、「このウィンドウを最前面に移動し、キーボードフォーカスを与える」ことを意味します。
Webビュー:インターフェイス
簡単にするために、使用するプラグインのWebユーザーインターフェイスのHTMLおよびCSSコードをすでに作成しました。 追加する必要がある残りのコードは、Sketchプラグインコードと通信できるようにすることだけです。
次に、HTMLおよびCSSコードをダウンロードします。 ダウンロードしたら、解凍して、「web-ui」という名前のフォルダーをプラグインのResourcesフォルダーに移動します。
注:実際のHTML / CSSコードの記述と最適化は、プラグインのコア機能を強化するJavaScriptに焦点を当てているため、このチュートリアルの範囲外です。 しかし、もっと知りたい場合は、このトピックに関するチュートリアルがWeb上にたくさんあります。
今すぐプラグインを実行すると、ウィンドウが表示されます。 しかし、それは空で、タイトルがなく、まだ特に有用ではありません。 Webインターフェイスを表示するために取得する必要があります。 そのためには、別のネイティブクラスであるWKWebView
を使用する必要があります。これは、Webコンテンツを表示するために特別に作成されたビューです。
ウィンドウ用に作成したコードの下に、 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); };
プラグインを実行すると、Webユーザーインターフェイスを表示するウィンドウが開いていることがわかります。 成功!
繰り返しますが、先に進む前に、追加したコードが何をするかを調べてみましょう。
const webView = WKWebView.alloc().init();
これは見覚えがあるはずです。基本的には、 NSWindow
を作成したときと同じです。Webビューにメモリを割り当ててから、初期化します。
window.contentView = webView;
このコード行は、作成したWebビューを表示するようにウィンドウに指示します。
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
ファイルを直接指す2番目のURLを作成する必要があります。
const indexURL = webUIFolderURL.URLByAppendingPathComponent("index.html");
最後に、Webビューにindex.html
をロードして、 web-ui
フォルダーのコンテンツへのアクセスを許可するように指示します。
webView.loadFileURL_allowingReadAccessToURL(indexURL, webUIFolderURL);
大丈夫。 これまでのところ、必要に応じてWebユーザーインターフェイスを表示するウィンドウがあります。 ただし、まだ完全ではありません。元のデザインにはタイトルバー(または「クローム」)がありませんが、現在のウィンドウにはあります。 また、Sketchドキュメント内をクリックすると、そのドキュメントがウィンドウの前に移動するという事実もありますが、これは私たちが望んでいることではありません。ユーザーがプラグインウィンドウとSketchドキュメントを操作しなくても操作できるようにする必要があります。常に1つのウィンドウから別のウィンドウに焦点を合わせ直します。
これを修正するには、最初にデフォルトのウィンドウクロームを削除し、ボタンのみを保持する必要があります。 以下の2行のコードを追加すると、タイトルバーが削除されます。
注:以前と同様に、以下で使用しているすべてのプロパティとメソッドは、 NSWindow
のドキュメントページに記載されています。
window.titlebarAppearsTransparent = true; window.titleVisibility = NSWindowTitleHidden;
次の2行のコードでは、不要なウィンドウボタン(MacOS用語では「信号機」とも呼ばれます)が削除され、「ズーム」と「最小化」が削除され、「閉じる」ボタンのみが残ります。
window.standardWindowButton(NSWindowZoomButton).hidden = true; window.standardWindowButton(NSWindowMiniaturizeButton).hidden = true;
その間、ウィンドウの背景色をWebUIの背景色と一致するように変更してみましょう。
window.backgroundColor = NSColor.colorWithRed_green_blue_alpha(1, 0.98, 0.98, 1);
次に、フローティングプラグインウィンドウを他のウィンドウの上に保持するために何かを行う必要があります。これにより、ユーザーはMosaicのウィンドウが消えることを心配せずにSketchドキュメントを操作できます。 これには、 NSPanel
と呼ばれる特別なタイプのNSWindow
を使用できます。これは、他のウィンドウの「上にとどまる」ことができます。 これに必要なのは、 NSWindow
をNSPanel
に変更することだけです。これは、1行のコード変更です。
const window = NSPanel.alloc().initWithContentRect_styleMask_backing_defer(
次に、パネルウィンドウをフロートさせ(他のすべての上にとどまる)、必要な場合にのみキーボード/マウスのフォーカスを取得するように指示します。
window.floatingPanel = true; window.becomesKeyOnlyIfNeeded = true;
ウィンドウを微調整して、最後の位置で自動的に再び開くようにすることもできます。
window.frameAutosaveName = "mosaic-panel-frame";
この行は基本的に、「キーmosaic-panel-frame
下にSketchの設定で保存して、このウィンドウの位置を覚えておいてください」と言っています。
これで、次のコードが完成しました。
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
フォルダの下。 また、Webビューやウィンドウの作成など、実行する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 };
ここで行った重要な変更点がいくつかありますが、注意が必要です。 ウィンドウとそのWebビューの作成、非表示、表示のための特定の関数を作成したという事実に加えて、ユーザーインターフェイスコードもモジュール化しました。
下部にあるmodule.exports = { loadAndShow, cleanup }
行に注意してください。 これは、このUIコードをインポートするオブジェクトと関数スクリプトが使用できるオブジェクトと関数を正確に指定する方法です(そして、心配したくないものを非表示にします)。つまり、対話するためのより組織化されたAPIがあります。 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!