177
171

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Electron】画像を保存するだけで満足してしまうオタクのために最高の画像ビューアをつくった

Last updated at Posted at 2016-03-02

みなさん、いかがオタクライフお過ごしでしょうか?
オタクの生活には萌え画像が欠かせませんね。
日々twitterを眺めてはTLに流れてくる画像をふぁぼり、pixivでお気に入りの絵師の画像を眺め、tumblrでアニメgifをリブログ、そして自分のPCのお宝フォルダに保存して完了。
だいたい、こんな感じでしょうか。
ですが、肝心なことを忘れてないでしょうか?

保存するだけ保存してそれで満足って、それ、画像を楽しんでないんじゃないの?

手に入れた画像をどう楽しんでますか?
デスクトップの壁紙やターミナルの背景にする?
いいですね。ですが、それで満足してますか?

背景ではなく最前面に表示されていたら?
静止画だけじゃなくgif画像も表示されたら?

そこで、作業用画像ビューアです。

作業中ずっと好きな画像が表示され続けば...

  1. 最高な画像が表示される!
  2. テンションアップ!
  3. 作業効率アップ!
  4. 最高!
  5. 1に戻る

という最高のスパイラルが体験できることでしょう。
そんな最高の体験を可能にするための作業用画像ビューア yamada をつくりました。

スクリーンショット

gif

特徴

  • 常に最前面
  • タイトルバーなし(邪魔だよね)
  • 閉じるボタンなし(邪魔だよね)
  • 起動するだけで使える
  • どこをドラッグしても移動可能
  • 簡単にリサイズ
  • ディレクトリを監視し起動後に追加した画像も表示
  • ⌘+oでファイルダイアログを開く
  • コンテキストメニュー
  • png,jpg,gifに対応
  • コマンドラインからの起動可能

ダウンロード

ダウンロードはここから。

zipを展開して起動できます。
mac対応のみ(windows環境ではコンテキストメニューに不具合があります)

CLI

$ yamada .
$ yamada ~/Picture

技術的なこと

Electronを使いました。1つのjsとhtmlだけでも簡単なデスクトップアプリケーションがつくれるので手軽で楽しいです。

今回はメインプロセス側にmain.js、レンダラープロセス側にindex.jsをルートディレクトリにぽいっと配置したお手軽構成にしました。viewライブラリは使ってないです。(レンダラープロセス側はimgを書き換えてるだけなので)

browserify

つくってるときはbrowserify必要なくねと思っていましたが、リリース用にパッケージ化したらサイズが大きくなったので、node_modulesを削るためにbrowserifyを使いました。

以下の記事のコメントでも言及されています。

kobito for windows では開発環境下でのnode_modules以下が120MBあるのですが、これをbrowserifyで不要なファイルを除去することで3.2MBまで絞れました。ある程度以上のサイズがある環境なら必須だと思ってます。
ぼくのかんがえたさいきょうのElectron - Qiita

electronでbrowserifyを使う時の注意点として、mainプロセス側をブラウザリるとrequire('electron')が迷子になる等の問題が起きるのでオプションをつけてあげる必要があります。

browserify main.js --im --no-detect-globals --node -o ./dist/main.js

--imはrequireが解決できなかったときにrequireを無視します。
--no-detect-globals__dirnameなどがビルド環境のパスに置き換えられるのを防ぎます。
このオプションはbrowserifyのREADMEにのってないので調査にちょっと手こずりました。

browserifyは依存するnpmモジュールのpackage.jsonがbrowserフィールドを持っているとそちらを見に行ってしまいます。しかしmainプロセスはnode向けに動作してほしいため--nodeオプションを有効にします。
また、レンダラープロセスにおいてもelectronをrequireする必要があれば--imを有効にする必要があります。

npm scripts

gulpなどのタスクランナーは使わずnpm scriptsを使いました。

"scripts": {
  "start": "electron .",
  "clean": "rimraf dist",
  "copy": "cpx '{*.html,package.json,*.png}' dist",
  "build": "npm-run-all -s clean copy build:renderer build:main",
  "build:renderer": "browserify index.js --im -o ./dist/index.js",
  "build:main": "browserify main.js --im --no-detect-globals --node -o ./dist/main.js",
  "release:osx": "electron-packager ./dist yamada --out=./release --platform=darwin --arch=x64 --version=0.36.9 --overwrite --asar --icon=./res/yamada.icns",
  "release:win": "electron-packager ./dist yamada --out=./release --platform=win32 --arch=x64 --version=0.36.9 --overwrite --asar --icon=./res/yamada.icon",
  "release": "npm-run-all -s build release:*"
},

es6

process.versionsを確認してみたところElectronのnodeのバージョンは5.1.1なので、アロー関数やクラス等のes6の機能が使え環境も固定されているので、とりあえずアロー関数さえあればいいよという人はバベる必要もないかなと思います。(なお今回使用したelectron-prebuiltのバージョンは0.36.9です)

{ 
  http_parser: '2.6.0',
  node: '5.1.1',
  v8: '4.7.80.27',
  uv: '1.7.5',
  zlib: '1.2.8',
  ares: '1.10.1-DEV',
  modules: '47',
  openssl: '1.0.2e',
  electron: '0.36.9',
  'atom-shell': '0.36.9',
  chrome: '47.0.2526.110'
}

ファイル監視

基本的には、メインプロセスでchokidarを使いディレクトリを監視し、5秒ごとにランダムで画像をipc通信でレンダラープロセスに送って画像を表示しています。chokidarはgulpやbrowserifyでも使われてるファイル監視ライブラリです。

Menuとキーイベント

はじめキーイベントはレンダラープロセスで呼び出していましたが、menuにacceleratorを書けばclickに定義した関数がキーイベントが発生すると呼び出せるようです。レンダラープロセスにもキーイベントのリスナを設定しておくと重複して呼び出されてしまうので注意が必要です。(あとからメニューを追加したらファイルダイアログが2連続で出るようになりハマりました)

フレームレスウインドウとドラック移動

公式のドキュメントに全部書いてあります。

  • [electron/frameless-window.md at master · atom/electron](https://github.com
    /atom/electron/blob/master/docs/api/frameless-window.md)

フレームレスウインドウはBrowserWindowのオプションのframeをfalseにするだけです。

const BrowserWindow = require('electron').BrowserWindow;
var win = new BrowserWindow({ width: 800, height: 600, frame: false });

ドラック移動を可能にするには、cssで以下を設定します。

body {
  -webkit-app-region: drag;
}

alwaysOnTop

フレームレスウインドウと同様にBrowserWindowのオプションでalwaysOnTopを有効にするだけで、常に最前面に表示させることができます。

var win = new BrowserWindow({ width: 800, height: 600, alwaysOnTop: true });

しかし、ダイアログを開くと最前面でなくなることがあります。そこで、ダイアログを開いたあとなどにsetAlwaysOnTopを実行し最前面に設定しなおす対策をしています。何かよい方法があれば教えて下さい。

mainWindow.setAlwaysOnTop(true);

おわりに

これを書きながらも常に画面右下にかわいい画像をスライドショーさせています。
思ったより邪魔になりませんしいい気分でこれを書いてます。

バグや機能追加等あればイシューやプルリクエストお願いします。
github - akameco/yamada

それでは、よいオタクライフを!

追記

browserifyではなく、webpackを使ったelectronアプリケーションの記事を書きました。
他にもreact+flowtypeを使っています。機会があれば見てください。

Electron+react+flowtypeでtweetdeckライクなpixivクライアントPixivDeckをつくった - Qiita

177
171
1

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
177
171

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?