Smart Communication Design Company
ホーム > ナレッジ > Blog > フロントエンドBlog > 2018年11月 > Vue.jsを使ったモダンなAdobe XDプラグイン開発

フロントエンドBlog

Webのフロントエンドを構成する技術、特にHTMLやCSS、JavaScript、またそれらに関連する話題を扱うBlogです。

Vue.jsを使ったモダンなAdobe XDプラグイン開発

UI開発者 加藤

10/15にリリースされたAdobe XDバージョン13より、アプリケーション上でサードパーティーのプラグインを使用できるようになりました。XDがはじめてリリースされた当初はプロトタイピング機能が特に注目されていましたが、毎月のアップデートにより今では単なるプロトタイプツールとしてではなくデザインツールとしてSketchなどのアプリケーションとよく比較されています。今年の5月にはXD専用の無料プランが発表され、より多くの人が手軽に使用できるようになりました。さらに、今回のアップデートで誰でもプラグインを作ることが可能になったことで、今まで以上に便利になることが期待できます。

プラグイン開発の基本的な情報はAdobe Creative Stationに投稿されている「はじめてのAdobe XDプラグイン開発!定番のHello Worldを表示させてみよう」にわかりやすくまとめられています。今回の記事ではVue.jsを用いてテキストを置換するプラグインを例としてご紹介します。

Vue.jsで開発する場合も、最終的にmanifest.jsonmain.jsの2つのファイルが開発フォルダーに含まれていれば問題ありません。 ただし、ユーザーの入力を受けるようなインターフェースをプラグイン上で提供する場合は、2つのファイルのほかにAdobeが提供しているライブラリを含める必要があります。あらかじめダウンロードして開発フォルダーにコピーしておきましょう。

今回のフォルダー構成は次の通りです。

replaceText/
 ├ lib
 │   └ dialog.js
 │   └ manifest.js
 ├ src
 │   └ App.vue
 │   └ MyFooter.vue
 │   └ MyInput.vue
 │   └ main.js
 ├ manifest.json
 ├ package.json
 └ webpack.config.js

核となるmain.jsApp.vueのみ記載します。

main.js

// setTimeoutとclearTimeoutを定義しないとエラーになるため、書いておきます
global.setTimeout = function (fn) { fn() };
global.clearTimeout = function () { };

const { Artboard, Text } = require("scenegraph");
const Vue = require("vue").default;
const App = require('./App.vue').default;

function createDialog(id = "dialog") {
    document.body.innerHTML = `<dialog id="${id}"><div id="container"></div></dialog>`;
    let dialog = document.getElementById(id);
    new Vue({
        el: "#container",
        components: { App },
        render(h) {
            return h(App, { props: { dialog } });
        },
    });

    return dialog;
}

function replaceText(children, prev, after) {
    children.forEach(elm => {
        if (elm instanceof Text) {
            elm.text = elm.text.replace(prev, after);
        }
    });
}
// エントリポイントとなるメソッドです
async function showReplaceDialog(selection, root) {
    const dialog = createDialog();
    const result = await dialog.showModal();
    if (result) {
        root.children.forEach(elm => {
            if (elm instanceof Artboard) {
                replaceText(elm.children, new RegExp(result[0], 'g'), result[1]);
            }
        });
    }
}
// manifest.jsonで指定したコマンドIDとファンクションを紐づけます
module.exports = {
    commands: {
        showReplaceDialog
    }
};

App.vue

<template>
    <div class="wrapper">
        <form @submit="onSubmit">
            <h1>テキスト置換!</h1>
            <MyInput ref="prev" label="置換前のテキスト"></MyInput>
            <MyInput ref="after" label="置換後のテキスト"></MyInput>
            <p class="attention">※実行をクリックするとアートボード直下のテキストのみが置換されます。</p>
            <MyFooter @onClickCancel="onCancelHandler" @onClickExecution="onClickExecution"></MyFooter>
        </form>
    </div>
</template>
<script>
    import MyFooter from './MyFooter.vue';
    import MyInput from './MyInput.vue';
    export default {
        components: {
            MyFooter,
            MyInput,
        },
        props: {
            dialog: {
                type: Object,
                required: true,
            },
        },
        methods: {
            onSubmit(e) {
                e.preventDefault();
            },
            onCancelHandler() {
                this.dialog.close();
            },
            onClickExecution() {
                this.dialog.close([this.$refs.prev.getValue(), this.$refs.after.getValue()]);
            },
        },
    }
</script>
<style scoped>
    .wrapper {
        width: 300px;
    }

    .attention {
        color: #999;
        font-size: 12px;
    }
</style>

form要素は必須ではありませんが、/lib/dialog.js内部でform要素に囲まれている前提のスタイルが用意されているのでそれを利用するのが良いと思います。ただし、styleだけでなくsubmit時のイベントリスナーも設定されているため、今回はsubmit時にpreventDefaultしています。

またXDプラグインには「エディットコンテキスト」というルールがあります。エディットコンテキストとはプラグインから操作できるノードの範囲を示しており、選択されたノードの直下のノード、もしくはアートボードの直下のノードまでのみがプラグインから編集できる対象になります。たとえば、アートボードに置かれたシンボル内のテキストを変換したい場合は一度変換したいシンボルを選択してからプラグインを実行する必要があるので注意しましょう。

実際にWindows版のXDでプラグインを実行した結果がこちらです。

テキスト置換プラグイン動作イメージ

XDプラグインの良い点は手軽にプラグインを共有できるところです。作成したプラグインフォルダー内のファイルをzipに圧縮し、拡張子を「.xdx」に変更するだけでXD用のプラグインファイルと認識されます。あとはこのファイルを共有し、受け取った側はダブルクリックするだけでインストールができます。

これまでのAdobe CCアプリケーション用のプラグインは「Common Extensibility Platform(CEP)」というアーキテクチャをベースとしていました。今回XD用のプラグインでは新しく「Unified Extensibility Platform(UXP)」というアーキテクチャが採用されています。UXPのベースはCEPと変わりませんがES6やReact,Vue.jsといったフレームワークを使用できるため、よりモダンで効率的な開発ができます。また、プラグインからローカルファイルを読み込んだり、プラグイン内でOAuthの設定もできます。XD以外のアプリケーションもプラグインの拡張はいずれUXPベースになるとのことなので、今から手を付けておいて損はないでしょう。

Adobe XD PlatformにはPlugin API Roadmapが公開されており、もうすぐ追加される予定の機能や将来的にサポートされる機能がたくさん待ち構えているのがわかります。今後のアップデートも楽しみですね!