見出し画像

【Adobe XD】初めてUIトレースをしたら高さと幅を0.5px変えるショートカットがなかったのでプラグインで作った。

こんちには。chinamiです。

おもむろにUIデザインに興味を持ったので少し手を動かして見ました。UIデザインの入門としてUIトレースという手段があると聞いたことがありました。今回は、個人的に好きなアプリである「ジャンプ+」をトレースしてみました。

スクリーンショット 2020-10-10 19.46.01

アプリの分析編については別の記事を書く予定です。今回はUIトレースをして欲しいと思ったショートカットをプラグインとして実装してみた記事です。

Adobe XDのショートカット

UIトレースしていて思ったことは、比較的同じ作業の繰り返しになるので、ショートカットを覚えて効率化するのがよいということです。

「この作業何回もでてくるなぁ〜」と感じるたびにショートカットを検索してあれば覚えるということを繰り返しながら進めていきました。


オブジェクトを0.5px単位で変形させるショートカットが欲しい

このように進めていく中で、割と使うにもかかわらず実装されていないショートカットがあることに気付きました。

「オブジェクトの幅、高さを0.5px単位で変更するショートカット」です。

私がトレースした「ジャンプ+」は0.5px単位のオブジェクトや余白がしばしば登場します。1px単位の大きさの変更はMacだと「Cmd+矢印キー」で実装されているのですが、そのあとに0.5px単位の調整をする必要がありました。

スクリーンショット 2020-10-10 19.10.02

図1: 右上でW:102.5px, H:102.5pxとなっている 

こういったオブジェクトが出てくるたびに、右のプロパティインスペクタの幅、高さの入力部分をクリックし、0.5と入力する必要がありました。

いちいち入力しなくていいショートカットがあって欲しいと感じました。


既存のものがないなら作ってみよう

調べてみるとAdobe XDには開発者向けの機能としてプラグインというものがあり、APIの範囲で欲しい機能が作れるようです。ショートカットを登録するというのが基本的な使い方のようだったので、ちょうどいいじゃんと思いました。

こちらの記事を参考にしました。

はじめてのAdobe XDプラグイン開発!定番のHello Worldを表示させてみよう
https://blogs.adobe.com/japan/web-getting-started-with-xd-plugin-development/


出来たもの

結果としてできたものがこちらです。現状、プラグインとして配布などはしていません。

Cntl+7: オブジェクトの幅を0.5px減少
Cntl+8: オブジェクトの高さを0.5px増加
Cntl+9: オブジェクトの高さを0.5px減少
Ctrl+0: オブジェクトの幅を0.5px増加

スクリーンショット 2020-10-10 2.23.31

図2: 実装したプラグインがメニューで確認できる


ショートカットの割当について

本当は既存のショートカットである「Cmd+矢印キー:オブジェクトを1px変拡大、縮小する」に近い「Cmd+Ctrl+矢印キー」などを割り当てようとしたのですが、ショートカットとして矢印キーを割り当てる方法は見つかりませんでした。

ショートカット割当について試したこと

vimのキーマップで矢印キーを指定するときのように<Up><Down>という記法で示そうとしましたがこれは駄目でした。
また、矢印キーがだめならと、近いキーで右下の`/`などを使おうとしたら以下のエラーが出ました。ショートカットの割当としては1文字の英数字が想定されているらしいです。

manifest.json: Expected a single alphanumeric character as shortcut key: ctrl+/

結果として、4キーまとまってショートカットが割当たっていないキーとして「Ctrl+7,8,9,0」の数字キーを採用しました。本当は「Cmd+数字」がよかったのですが、「Cmd+0」(アートボードを画面サイズに合わせる)や「Cmd+8」(パスに変換)はショートカットがすでに割当たっています。そこでCtrlを選びました。

ちなみに、Cmdキーに位置的に近いShiftキーにしようとも思いましたがそれもダメでした。

manifest.json: Expected a Command or a Control key to be specified for a shortcut: shift+7

少し試行錯誤がありましたが、必要な機能は実装できました。数字キーは若干遠いのでよりよい割当が思いつけば改善したいと思います。

コードはgithubで公開しています。


個人的に他に欲しいショートカットとして、オブジェクトの線の色を指定するためのスポイトを起動するショートカットがあります。オブジェクトの色は「i」でスポイトが起動できるのですが、線の色を指定するためのスポイトを起動するショートカットはなさそうです。Ctrl+iなどで起動したいなぁと思っています。現状ではスポイトを起動するAPIはなさそうではありますが、なんとかしたいと思っています。

ここまでで基本的に記事の内容は終わりです。読んでいただいてありがとうございました。
以下はおまけ的なメモのようなものです。


完成までの経緯(おまけ)

最初の目標
・長方形オブジェクトの幅と高さを0.5pxで変形する。

操作している長方形オブジェクトがどのように表現されているかconsole.logしてみる

function ShrinkWidthHalfpx(selection) {
 console.log("resize function is called!");
 console.log(selection.items);
}

Developer Consoleを開きながらショートカットを動作させてみます。

スクリーンショット 2020-10-08 22.14.09

おお、選んでいる長方形オブジェクトの情報が見えました。
あれ、これはこのwidthとheightを書き換えたらもうよいのでは?
ちなみにselection自体は何も見えないです。見えて欲しい...

function ShrinkWidthHalfpx(selection) {
 console.log("resize function is called!");
 console.log(selection);
}

スクリーンショット 2020-10-08 22.20.02


widthの値を書き換えてみる

function ShrinkWidthHalfpx(selection) {
 console.log("resize function is called!");
 selection.items[0].width -= 0.5;
 console.log(selection.items);
}

Developer Consoleを開きながらショートカットを動作させてみます。(Cntl+7:オブジェクトの幅を0.5px減少のショートカット)

スクリーンショット 2020-10-08 22.29.40

おお、うまく動作してますね。
もう完成じゃん。


パスに変換すると変形しなくなる問題

完成してしまったと思ったのですが、問題がありました。
長方形オブジェクトをパスに変換したときにうまく動作しなくなります。

長方形オブジェクトをダブルクリックするとパスに変換されます。

スクリーンショット 2020-10-09 23.42.29


もしくは「Cmd+8」のショートカットを用いてもパスに変形できます。

このときに先ほどプラグインとして実装した「Cntl+7:オブジェクトの幅を0.5px減少」のショートカットを使ってみます。

スクリーンショット 2020-10-09 23.44.31

先ほどと違って、widthの値が減少していません。
私にとってはダブルクリックで意図せずしてパスに変形してしまうことはしばしばありましたし、長方形に限らないパスについてもwidthとheightという設定項目があるので同様にショートカットが動いて欲しいところです。


パスでwidthとheightが変わらない原因調査

Adobe XDのプラグイン開発者向け公式ドキュメントを見てみましょう。このページ、開いているページと左のサイドバーが連携していないので、個人的にはとても読みづらかったです。

パス(path)に関するページがありました。

また、長方形(Rectangle)に関するページと見比べてみましょう。


PathとRectangleの違い

それぞれの仕様を比較してみるとオブジェクトが持っているプロパティが異なることがわかりました。
先ほどの画像のように、長方形にしても、パスにしてもconsole.logでインスタンスの情報を表示すると両方にwidthとheightがあったにもかかわらず、パスにはwidthとheightという項目がありません。

Rectangle
.width : number
.height : number
~~~~~~~
Path
.pathData : string

つまりパスに対してショートカットを実行しているときは先ほどのコードにおける、selection.items[0].width がundefinedとなっているとわかりました。

function ShrinkWidthHalfpx(selection) {
 console.log("resize function is called!");
 selection.items[0].width -= 0.5;
 console.log(selection.items);
}


ではパスの幅と高さをどのように変形するか

1. path.pathDataで変形する。
2. sceneNode.localBoundsとsceneNode.resize(width, height)で変形する。

path.pathData

これはpathを表現している文字列で、SVGの<path>要素で使用される文法にのっとっているようです。

pathDataを出力してみると、このような文法が見えます。

スクリーンショット 2020-10-10 1.58.37

まず、M命令でスタート位置(x, y)=(0, 0)が示されています。次に、L命令によって座標位置(x, y)=(100, 150)まで線が引かれ、L命令が繰り返されて長方形のパスになっているようですね。

このようにSVGの文法で示されているpathDataを操作すればwidth、heightの値を変更することも可能そうでした。
しかし、今回はこの方法は見送りました。パスが長方形でない場合に設定が難しいですし、SVGのデータをいじるのはレイヤが低すぎる気がします。最悪この方法を取るとして、他の方法を探りました。

しかしながら、パスを自由に操作できるという知見を得ることはできました。


sceneNode.localBounds、sceneNode.resize

クラスの継承関係に注目してみると、path<-GraphicNode<-sceneNodeという構成になっています。

sceneNode.localBoundsに注目してみると、Boundsという単語に馴染みがなかったですが、これはBoundsという型の値を持っており、以下のプロパティを持っています。

Bounds :
!{x:number, y:number, width:number, height:number}

ここで現在の幅と高さを取得し、sceneNode.resize(width, height)を適用することで目的の動作を得ることができそうです。

function ShrinkWidthHalfpx(selection) {
 console.log("resize function is called!");
 const width = selection.items[0].localBounds.width;
 const height = selection.items[0].localBounds.height;
 selection.items[0].resize(width+0.5, height+0.5);
 console.log(selection.items);
}

スクリーンショット 2020-10-10 2.19.43

これで、パスに対してもショートカットが有効になることを確認できました。なんでパスのときもwidthとheightがもっているオブジェクトのように表示されてるんだろう?

以上です。おまけまで読んでくださりありがとうございました。

この記事が気に入ったらサポートをしてみませんか?