LoginSignup
12

More than 3 years have passed since last update.

Adobe XDでアセットをSCSS用に変数とmixinを書き出すプラグインを開発する

Posted at

はじめに

AdobeXDを使ってデザインを作ってると「アセットをこのままCSSに書き出せたらなぁ」って一度は思いますよね。自分は思いました。
2019年5月のアップデートで今までの「シンボル」の概念から「コンポーネント」という概念に変わり、よりコンポーネントの扱いが便利になりました。

今回はAdobeXDで登録したカラーアセットとフォントスタイルをSCSSで使える変数やmixinに書き出すプラグインを作ってみました。
動作は下の動画のようになります。
demo.gif

開発環境

AdobeXDのプラグインはES2018で開発ができます。
今回はTypeScriptで開発をしました。
理由はいくつかあるのですが、大きな理由としてAdobe公式の型定義ファイルが用意されているのでコード補完が効くという点があります。かなり独自のクラスが多いのでTypeScriptで開発をすることをおすすめします。

また、今回はダイアログでのユーザー操作はあまり発生しないプラグインなのでフロントエンドフレームワークを使用せずに開発を行いました。

開発環境の構築はこちらの記事を参考にさせていただきました。
Adobe XDプラグインをVueとBabel/TypeScriptで開発する方法

上記の記事にも記載されていますが、AdobeXD/xdpmという開発補助ツールが便利です。

アセットを取得する

アセットを取得するのは意外と簡単でassetsモジュールを使うと簡単に取得できます。

まずはカラーアセット

以下のコードのように.get() メソッドを実行することでカラーアセットの配列を取得できます。

let palettes = assets.colors.get() as assets.ColorAsset[];

取得した配列をforEachでループを回して各要素の色を取得します。
colorToCss()というアルファ値を持っていたらrgba()で、持っていなかったら16進数表記で返すようなメソッドを作成します。(基本的にアルファ値を持った色はアセットにしないと思いますが…)
取得してきた色情報をもとにSCSSで使う変数名を生成し、カラーコードを代入します。

colorPaletteToCSS(palettes: assets.ColorAsset[]) {
    palettes.forEach(p => {
        let c = this.colorToCss(p.color);
        let name = `$color-${c.replace('#', '')}`;
        this.resultCSS += `${name}: ${c};\n`;
    });
}

colorToCss(c:sg.Color):string {
    if (c.a !== 255) {
        return `rgba(${c.r}, ${c.g}, ${c.b}, ${this.num(c.a / 255)})`;
    } else {
        /* sg.Colorは16進数でカラーコードを返してくれるメソッドが用意されています */
        return c.toHex(true);
    }
}
/* 数値を丸め込む */
num(value:number):number {
    return Math.round(value * 100) / 100;
}

次にフォントアセット

フォントアセットはcharacterStyles.get()メソッドを実行することで取得できます。

let styles = assets.characterStyles.get();

そして、同様にforEachでループを回してフォントスタイルを取得します。

fontAssetToCSS(styles: assets.CharacterStyleAsset[]) {
    styles.forEach(item => {
        let mixinName = `${item.style.fontFamily.replace(/ /g, "")}-${item.style.fontStyle.replace(/ /g, "")}-${Math.floor(item.style.fontSize)}px`;
        this.resultCSS += `@mixin ${mixinName} { \n`;
        this.resultCSS += this.fontStyleToCSS(item.style);
        this.resultCSS += `}\n`
    });
}

fontStyleToCSS(f: assets.CharacterStyle):string {
    let result = "";

    // font-familyを取得
    // フォント名に空白があるか確認
    if (f.fontFamily.includes(' ')) {
        result += `font-family: "${f.fontFamily}";\n`;
    } else {
        result += `font-family: '${f.fontFamily}';\n`;
    }

    //font-weightを取得
    result += `font-weight: ${this.fontweightToCSS(f.fontStyle)};\n`;

    // 斜体の場合
    if (this.isItalic(f.fontStyle)) {
        result += `font-style: italic;\n`;
    }

    // 下線がある場合
    if (f.underline) {
        result += `text-decoration: underline;\n`;
    }

    result += `font-size: ${this.num(f.fontSize)}px;\n`;

    return result;
}

isItalic(f: string): boolean {
    return /\bItalic\b/i.test(f);
}

基本的にAdobeXDのフォントスタイルの値はそのままCSSに流用することができます。
しかし、font-weightは使用しているフォントによって太さの単位が違ったりする(例:W3、Regularなど)ので、これらを判別するメソッドを作りCSS用の値に変換する必要があります。
また、斜体に関しても同様に斜体であるかどうかを判別するメソッドを作成しました。

fontweightToCSS(f: string):string {
    let fontWeight = f;

    switch (true) {
        case /\bBold\b/i.test(fontWeight):
            return "bold";

        /* 省略 */

        case /\bW[0-9]\b/i.test(fontWeight):
            let weight = fontWeight.replace(/W/i, "");
            let result = 100 * Number(weight);

            return String(result);

        default:
            return "normal";
    }
}

クリップボードにコピーする

生成したSCSSのコードをクリップボードに渡します。
クリップボードにコピーするのはとても簡単です。
clipboardモジュールが用意されているので.copyText()メソッドを呼び出して引数に文字列を渡してあげるだけでクリップボードに文字列がコピーされます。

clipboard.copyText(generateCSS.resultCSS);

完了ダイアログを出す

今回は完了をお知らせするという、すごくシンプルなダイアログを出します。
ダイアログ要素を生成しbody要素に追加します。WebのDOM操作と同じ感覚で開発できます。

今回は様々な完了メッセージを出力することを想定して、メッセージの文字列を引数としています。

function createDialog(message:string) {
    const container = document.createElement('div');
    container.style.maxWidth = "320px";

    const title = document.createElement('h1');
    title.textContent = "XD to Sass!";
    title.style.paddingBottom = '20px';
    container.appendChild(title);

    const p = document.createElement('p');
    p.textContent = message;
    container.appendChild(p);

    const btnClose = document.createElement("button");
    btnClose.textContent = "close";
    btnClose.style.marginTop = "20px";
    container.appendChild(btnClose);
    btnClose.onclick = e => {
        dialog.close();
    };

    const dialog = document.createElement("dialog");
    document.body.appendChild(dialog);
    dialog.appendChild(container);
    dialog.showModal();
}

まとめ

今回はカラーアセットとフォントアセットをSCSSの変数やmixinとして書き出すプラグインを開発することができました。
XDで作ったデザインをCSSとしてエクスポートする事によって、コーディングをより効率化させることができます。

また、このプラグインはこれからも機能開発を続けていこうと考えています。
次に実装したいのは、アートボード上のマスターコンポーネントをSCSSのコードで書き出すという機能ですかね…。
いずれはこのプラグインを公開したいと思います。

皆さんもAdobeXDを使ってコーディングを効率化させていきましょう!

参考サイト

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12