Atomのパッケージを見ていて、便利なパッケージが沢山あるなぁと思いつつ、真面目なパッケージばかりでもつまらないので、たまには不真面目で役に立たないパッケージがあってもいいかと思って作ったパッケージの話。

disturb-me

作ったのはdisturb-meというパッケージ。 Ctrl+Altを押しながらdmを押すとAtomウィンドウ内に画像が表示され、その画像がランダムに動き回り作業の邪魔をするというもの。

画像はパッケージの設定から指定できる。デフォルトではAtomのロゴ。

最初はpac-m●nというパッケージ名にして、ゲーム界のミッキーことパ●クマンが動き回るパッケージにしようと思ってたけど、バンダイナムコからダメだと言われてしまった。 この構想はいつかカタログIPオープン化プロジェクトを利用して実現しようと思う。

disturb-meの作り方

以前別のエントリでAtomパッケージの作り方の基本について書いたので、ここではそこで書かなかったことを書く。

  1. メインスクリプト - コマンド

    今回はコマンドを追加するのでCommandRegistryを使う。 CommandRegistryのインスタンスにはatom.commandsでアクセスでき、そのaddメソッドでコマンドを追加できる。

    addメソッドの引数は、第一引数から順に、

    1. target: コマンドを有効にするDOM要素か、それを示すCSSセレクタ。
    2. commandName: コマンドパレットに表示するコマンド名。全部小文字で、単語をハイフンでつないで、パッケージ名を先頭につけるのがルール。
    3. callback(event): コマンドを実行したときに呼ばれるメソッド。


    disturb-meのコマンドはAtomウィンドウ内のどこでも有効にしたいので、第一引数にはAtomウィンドウを表すカスタムタグであるatom-workspaceを指定する。 コードは以下の感じ。

      activate: (state) ->
        @subscriptions = new CompositeDisposable
        @subscriptions.add atom.commands.add 'atom-workspace', 'disturb-me:toggle': => @toggle()
    
      toggle: ->
        # 画像を挿入したり削除したりするコード。


    toggleの中では画像を挿入したり削除したりするわけだけど、この処理は、その画像を表す別のクラスにまかせることにする。 のでtoggleは以下のように書く。

      @disturber: null
    
      toggle: ->
        if @disturber?
          @disturber.stop()
          @disturber = null
        else
          @disturber = new Disturber()
          document.body.appendChild(@disturber.getElement())
          @disturber.start()

    Disturberが画像を表すクラス。別のファイル(lib/disturber.coffee)の中で定義して、スクリプトの先頭辺りでDisturber = require './disturber'のようにインポートする。

    document.body.appendChildしているところは、何かAtomのAPI(ViewRegistryとか)を使うべきなのかも。

  2. Disturber

    Disturberは以下のように書く。

    module.exports =
    class Disturber
    
      element: null
    
      constructor: ->
        # <img>を作って@elementに入れる。
    
      destroy: ->
        # @elementをDOMツリーから削除する。
    
      getElement: ->
        # @element返す。
    
      start: ->
        # @elementのsrcを設定して、ランダムに動かし始める。
    
      stop: ->
        # @elementを止める

    あまり取り立てて書くことないな…。

    因みに画像を動かすのにはVelocityを使い、DOMの操作とかにちょっとjQueryを使う。

  3. パッケージ設定

    動かす画像や動かす速度はユーザが設定できるようにする。 設定はメインスクリプトで定義でき、その値にはConfigクラスでアクセスできる。

    メインスクリプトでの定義は以下のように書く。

    module.exports = DisturbMe =
      disturber: null
      subscriptions: null
    
      config:
        bornImage:
          title: 'Born-Image'
          type: 'string'
          default: 'atom://disturb-me/assets/atom/white/atom_born.gif'
        bornDuration:
          title: 'Born-Duration'
          type: 'integer'
          default: 2000

    するとパッケージ設定画面が以下のようになる。

    settings


    各設定の定義に最低限必要な属性はtypedefault。オプショナルなものにtitledescriptionなどがある。 typeには、stringintegernumberbooleanarrayobjectcolorを指定できる。 詳しくはConfigクラスの説明に載ってる。

    Configクラスのインスタンスにはatom.configでアクセスでき、上で定義した設定を以下のように操作できる。

    imagePath = atom.config.get('disturb-me.bornImage')
    atom.config.set('disturb-me.bornDuration', '1000')
  4. キーバインディング

    メインスクリプト内でコマンドパレットに表示するコマンドを定義したが、これにキーボードショートカット(キーバインディング)を設定する。

    キーバインディングはkeymapsフォルダの中のcsonファイルで以下のように定義する。

    'atom-workspace':
      'ctrl-alt-d ctrl-alt-m': 'disturb-me:toggle'

    これ見ればだいたい書き方はわかるはず。(詳細はAtom Flight Manualに。)

    特殊キーはcmdctrlaltshiftenterescapebackspacedeletetabhomeendpageuppagedownleftrightupdownが使える。

    同時に押すキーはハイフンでつなぎ、連続して押すキーはスペースで区切るので、上記ctrl-alt-d ctrl-alt-mは、Ctrl+Altを押しながらdmを連続して押す、という意味。

  5. package.json

    前回と同様の編集に加えて、今回は二つのnpmパッケージに依存するので、dependenciesを以下のように書く。

      "dependencies": {
        "velocity-animate": ">=1.2.0",
        "jquery": ">=2.0.0"
      }

    これを書いて、プロジェクトルートフォルダでapm installすると、ルート直下のnode_modulesフォルダに依存モジュールがインストールされる。

    node_modulesはPackage Generatorが生成する.gitignoreに入っているので、リポジトリには入らない。

  6. リリースなど

    前回と同様にリリースする。 めんどいのでテストは書かない。

    リリース後、ループしないgifアニメーション画像をdisturb-meに使った場合、そのアニメーションが再生されない場合があるバグに気付いた。 これについては別のエントリで書いた。