これは
2018/10/15にリリースされた Adobe XD 13 から、プラグインを作れるようになったらしい
JavaScriptで作れて便利そうなので、試しに作ってみた
- GitHub: CSS Gradient plugin
- 成果物: adobexd-css-gradient-plugin_0.0.1.xdx
参考にする/したもの
開発準備
基本的には、 誰もが見ているはずのHelloWorldの記事 を見れば分かるはずなのでここでは説明しない
本記事では、上の記事の helloHandlerFunction
を編集するものとして説明する
何を作るか
XDにはcssを書き出す機能がないので、それを作ればよさそうと思った
何を自動で生成させるとよさそうかと考えたとき、グラデーションをcssにできれば便利そうだと思った
Adobe XDで作れるグラデーション
線形グラデーション (linear-gradient)
![スクリーンショット 2018-10-17 1.10.18.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F99161%2F129e92c2-92f7-76a0-3a75-691039d83ff9.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=5742012978bdefaec97c6b717998b355)
円形グラデーション (radial-gradient)
作っていくよ
とりあえず選択した図形の情報を取ってみる
選択した図形は selection.items
に配列で入る
なので適当に console.log
で出してあげれば何かわかりそう
function helloHandlerFunction(selection) {
console.log(selection.items);
}
![スクリーンショット 2018-10-17 1.19.50.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F99161%2F760aa360-89b6-311b-2fa1-d5e14dac0485.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=a125336e8a9d968badc14716e2bc7dfe)
[ Rectangle ('長方形') {
width: 258, height: 242
global X,Y: 943, 5
parent: Artboard ('Web 1920 – 1')
stroke: ff707070
fill: LinearGradientFill
},
Ellipse ('楕円形') {
width: 273, height: 273
global X,Y: 1259, 5
parent: Artboard ('Web 1920 – 1')
stroke: ff707070
fill: fff08c8c
},
Line ('線') {
width: 186, height: 229
global X,Y: 1581.5, 18.5
parent: Artboard ('Web 1920 – 1')
stroke: ff7be539
} ]
長方形の LinearGradientFill
を見るとグラデーションがわかりそう
塗り情報を詳しく見てみる
単純にそれぞれの fill
を見るだけ
function helloHandlerFunction(selection) {
const items = selection.items;
items.forEach(item => {
console.log(item.fill);
});
}
さっきの図形たちで確認する
// 長方形 (グラデーション)
{ endY: 1,
endX: 1,
startY: 0,
startX: 0,
colorStops: [ { color: [Object], stop: 0 }, { color: [Object], stop: 1 } ],
sx: 1,
sy: 1 }
// 楕円形 (ベタ塗り)
{ value: 4293954700 }
// 線 (塗りの概念なし)
null
長方形は LinearGradientFill
の詳細が見えた
リファレンスはこちら
![スクリーンショット 2018-10-17 1.35.41.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F99161%2F0604f541-8cc6-e42c-ab0a-e7f3f7f29da9.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=59ae2124ab6dfd6b800995def5933a19)
ちなみに、
ベタ塗りの楕円形は #F08C8C
の上2桁に alpha情報 FF
をつけた FFF08C8C
の10進数
線は塗りの概念がないのでnull
塗りの数値をrgbaにするコードがこちら
多分もっといい書き方があると思う
(追記編集) String.slice 使うほうがいいじゃん
(更に追記編集) Color.toRgba()
が用意されていた
/**
* 色をcssのrgba()に変換
* @param {Color} color 変換する色
*/
function toCssRgba(color) {
const {r, g, b, a} = color.toRgba();
return `rgba(${r}, ${g}, ${b}, ${a})`;
}
グラデーションの色情報を見てみる
colorStops
を詳しく見てみる
またここからは楕円形、線は見ないことにする
function helloHandlerFunction(selection) {
const items = selection.items;
items.forEach(item => {
console.log(item.fill.colorStops);
});
}
[ { color: { value: 4280795042 }, stop: 0 },
{ color: { value: 4282601983 }, stop: 1 } ]
色が切り替わるポイントの位置と、その位置の色が、ポイントの配列で分かる
stop
がグラデーションの線分を1としたときの位置
パーセンテージにすればcssでそのまま利用できる
また、color.value
で色が分かる
グラデーションの角度を求める
長方形の幅、高さ、グラデーション線分の座標が取得できているので、計算するだけ
2点間の距離と角度と座標の求め方 を参考にした
function helloHandlerFunction(selection) {
const items = selection.items;
items.forEach(item => {
const startX = item.width * item.fill.startX;
const startY = item.height * item.fill.startY;
const endX = item.width * item.fill.endX;
const endY = item.height * item.fill.endY;
const deg = Math.atan2(endY - startY, endX - startX) * 180 / Math.PI + 90;
console.log(`${deg}deg`);
});
}
133.16716049405795deg
そのまま linear-gradient()
にいれる角度として使える
また90度を足さないと、正しい角度にならないっぽいので足す
cssに変換する
今まで出した情報を linear-gradient()
にいれていくだけ
function helloHandlerFunction(selection) {
const items = selection.items;
const css = items.map(item => {
// degを求める
const startX = item.width * item.fill.startX;
const startY = item.height * item.fill.startY;
const endX = item.width * item.fill.endX;
const endY = item.height * item.fill.endY;
const deg = Math.atan2(endY - startY, endX - startX) * 180 / Math.PI + 90;
const colors = item.fill.colorStops
.map(point => {
// 色の10進数の数値を16進数の文字列に変更
const color = toCssRgba(point.color);
return `${color} ${point.stop * 100}%`;
})
.join(', ');
return `.${item.name} { background: linear-gradient(${deg}deg, ${colors}); }`;
});
console.log(css.join('\n'));
}
これを実行すると
.長方形 {
background: linear-gradient(133.16716049405795deg, rgba(39, 191, 162, 255) 0%, rgba(67, 81, 255, 255) 100%);
}
無事 linear-gradient
を取得できた
XDのグラデーション
![スクリーンショット 2018-10-17 2.06.36.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F99161%2Fe54ba1c4-ad80-2592-b8cc-64214d82f34f.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=956923e024601a9d5379b27e24f1797b)
出力したcssを適用させた<div>
![スクリーンショット 2018-10-17 2.07.10.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F99161%2F37272bef-99a9-bd5f-67af-92a8403a18b0.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=a189692ef47785579928b5bdcbbc7f4e)
完全に一致
今できていないこと
グラデーション線分の位置が中途半端なときの計算
![スクリーンショット 2018-10-17 2.10.20.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F99161%2F74ed905c-86e5-1c95-5646-4fb0395ac788.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=c59466c9254ad237f20109e23dc8e78e)
グラデーションの開始・終了位置が変わるため、linear-gradient
での色の位置を調整する必要がある
このまま出力するとこんなになり、全然違う
![スクリーンショット 2018-10-17 2.12.26.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.amazonaws.com%2F0%2F99161%2F42897f67-8c65-ba85-5fdc-932492a6cadc.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=8c1611fc9cbfd5993a99b4cf57c286c6)
radial-gradient
多分できるが、寝たいのでやらなかった
プラグイン作成に便利そうなもの
AdobeXD typings
AdobeXD公式が typings を提供しており、TypeScriptでの開発も柔軟にできそう
終わりに
煮るなり焼くなりしていただけると幸い
- GitHub: CSS Gradient plugin
- 成果物のDLページ: adobexd-css-gradient-plugin_0.0.1.xdx
プラグインの開発のしやすさがとても気持ちよかった
はじめてのAdobe XDプラグイン開発!定番のHello Worldを表示させてみよう を見ればいいが、プラグインの再読込がショートカットでできたり、デベロッパーコンソールもとてもいい機能
AdobeXDは Sketchと比べるとまだまだ機能が少ないが、少ないからこそシンプルだったり、軽かったり、プロトタイピング機能が便利だったりするので、使うプロジェクトも増えてきていると思う
そこでアホみたいな手作業をプラグインによって自動化できれば、楽しい未来しか見えてこないのではないかと感じた