AsciiDoc使ってみた

こんにちわ。コロナウイルスの影響で電車がガラガラの日々が続いていましたが、GW明けから徐々に出勤している人が増えているみたいですね。
電車混まないでえええ!!ということで、テックブログ今週の担当はuraです。

ドキュメント作るのつらい

皆さんは仕様書やマニュアルなどのドキュメントを作りますか?
私は現在受注プロジェクトのPMをしており、頻繁にドキュメントを作る機会があります。
一般的に、ドキュメントはWordやExcel等で作成するかと思います。WordやExcelは見やすいですよね。好きですか?私は嫌いです。

  • Gitで履歴管理しても簡単に文章を検索できない。差分も見えない。
  • チームで同じファイルを同時に編集しづらい。(GoogleDocsを使えばなんとかなるけど)
  • 書式を整えるのが面倒。気づいたら一部だけフォントが異なるとかよくある。
  • 顧客用のドキュメントであれば、修正の度にファイルを送信する必要がある。
ではどうするか?Markdownで作成してGitで管理しよう。
いちいちファイルを送るのは面倒なので、GitにプッシュしたらHTMLに変換してWebページに公開しよう。

いや、でもMarkdownだとテーブルのセル結合すらできないから、ちょっと複雑なドキュメントになると表現力が足りない・・・。

そんなことを考えているときに見つけたのが、今回のテーマのAsciiDocです。

AsciiDocとは?

Asciidocは軽量マークアップ言語の一つです。Markdownの仲間ですね。
以下のような採用事例があります。

Markdownと比較すると以下のような点が優れています。

  • テーブルのセル結合ができる
  • 相互参照が使える
  • 外部ファイルを読み込める(ソースコードをそのまま読み込んで表示したり、分けて作成したドキュメントをマージしたり・・・)
  • PlantUMLを直接書ける

使ってみる

それではさっそく使ってみます。

セクション

「=」の数で表現します。
== セクション1
=== セクション1.1
==== セクション1.1.1
== セクション2
== セクション3

リスト

「*」の数で表現します。
* リスト1
* リスト2
** インデント
*** さらにインデント

テーブル

[cols="1a,1a,1a",options="autowidth"]
|===
|1A|1B|1C
2+|「数値+」で横結合|2C
.2+|「.数値+」で縦結合|3B|3C
|4B
|* 4C
* リストを
* 入れることも可能
|===

画像

image::https://techblog.imagemagic.jp/wp-content/uploads/2018/11/%E6%8E%A1%E7%94%A8%E3%83%90%E3%83%8A%E3%83%BC.png[alt=代替テキスト, width="200" align="center"]

アンカー

アンカーは二重の「[」で表現します。
[[hogehoge]]

リンク

link:https://imagemagic.jp/recruit/[イメージ・マジックではエンジニアを募集中です。]

<<hogehoge, アンカーへのリンクは二重の「<」で表現します。>>

外部ファイルの読み込み

include::hogehoge.adoc[]

まとめ

AsciiDocの特徴や簡単な使い方について紹介しました。
現在マニュアル作成で使っていますが、やはりWordよりはラクをさせてもらっています。

インストール方法や詳しいリファレンスについては公式サイトをご覧ください。

デザインに使える比率の話

皆さんこんにちは。イメージマジック三浦です。 新型コロナウイルスに対して、弊社でも在宅勤務等の感染予防対策が進んできて今までと違う状況が日常になりつつあります。一日も早い収束を願いつつも、日々自分にできることをやっていこうと思います。 今回は「デザインに使える比率の話」と題して、黄金比と白銀比を紹介します。

黄金比

1:(1+√5)/2≒1:1.6
(1+√5)/2は黄金数とも呼ばれ、フィボナッチ数列の一般項表記に出てくる数です。整数値で比率を表すと5:8となります。
Web画面を作る時、通常表示向けと強調表示向けのフォントサイズを5:8にすることがありますが、通常表示側が奇数になる場合は以下2つの内、1.6に近い方を使うようにしています。
  • 強調表示向け÷(通常表示向け+1)
  • 強調表示向け÷(通常表示向け-1)

白銀比

貴金属比による定義…1:(1+√2)≒1:2.4
直角二等辺三角形の斜辺と底辺の比…1:√2≒1:1.4
「1:√2」は紙の寸法に出てくる他、日本の建築物に多く取り入れられています。また、東京スカイツリーの「東京スカイツリー展望回廊」とタワー全体の高さが約1:1.41で、これも白銀比になっています。

少し数学的な話

第n貴金属比…1:{n+√(n^2)+4}/2
黄金比や白銀比を更に一般化した概念として、貴金属比というものがあります。第1貴金属比(n=1)が黄金比、第2貴金属比(n=2)が白銀比です。ちなみに第3貴金属比(n=3)…1:{3+√13}/2 には青銅比という別名がついています。
(この並び、昔のアニメを思い出します)

おまけ

貴金属比に属さないながら、貴金属の名前を持つ比として白金比というものがあります。
白金比…1:√3
これは、正三角形の底辺の中点と頂点を結んでできる直角三角形の、斜辺を除く辺の比として出てきます。斜辺は短い方の辺のちょうど2倍になっていて、これは三平方の定理からも分かります。

最後に

少し前の話になりますが、京都大学数理解析研究所の望月新一教授による「ABC予想」の証明が認められたと話題になりました。「ABC予想」を真とすると、「フェルマーの最終定理(ワイルズの定理)」をあっという間に証明できるという話があるので紹介します。詳しい説明をしているサイトが他にありますので、ここでは定理と証明の概略を紹介するに留めます。
【フェルマーの最終定理(ワイルズの定理)】
3以上の自然数nについて、(x^n)+(y^n)=(z^n) を満たす自然数の組(x, y, z)は存在しない。
【証明の概略】
・ABC予想を真とすると、n>=6で(x^n)+(y^n)=(z^n) を満たす自然数の組(x, y, z)は存在しないことが証明できる。
・n=3,4,5の場合は、先人達によって個別に証明されている。
・よって3以上の自然数について、(x^n)+(y^n)=(z^n) を満たす自然数の組(x, y, z)は存在しない。
証明に360年かかった命題を、ここまで簡単に証明してしまえるのは驚くばかりです。しかしながら全てではなく、先人達が残した実績との合体技で証明です(これも昔の某アニメを思い出す)。どんなに優れた知見が出ても、そこに至るまでの先人達の歩みを無視することはできないと感じます。
今回は、ここで終わりとします。

JavaScriptって括弧のお化け

はじめに

コロナウイルスに戦々恐々の廣田です。
皆様も体にはお気をつけて…

憂鬱な今日この頃ですが、最近の業務中の癒しはslackが未読を始末した時に励ましてくれることです。
癒されすぎてキャプチャを集めちゃいました。

さて、今回はJavaScriptが括弧の有無で挙動が全然違うので調べてみました。

コールバック関数の書き方

Vue.jsで画面上の検索ボタンを押したらモーダル画面が開いて一覧から検索を行えるような機能を作っていた時のこと。 つぎのようなコードで上手く動かなかったのですが、どこが問題でしょうか🤔
<!--HTML側--> 
<div id="js-mainArea">
<button type="button" @click="search">検索</button> 
</div>
//本体のVueインスタンス
new Vue({
   el: '#js-mainArea',
   data: {},
   methods: {
       search() {
           EventBus.$emit('open-search-modal');
       },
   },
});
//モーダルのVueインスタンス
new Vue({
   el: '#js-search-modal',
   data: {
       isOpen = false
   },
   created: function () {
       EventBus.$on('open-search-modal', this.open())
   },
   methods: {
       open() {
           console.log('open');
           this.isOpen = true;
       },
  },
});
すごく初歩的なところだと思うのですが、検索ボタンを押したときemitしたイベントを捕捉している以下の箇所が原因でした。
EventBus.$on('open-search-modal', this.open()) 
イベントハンドラとしてコールバック関数を指定したいので正しくはこうですよね。
EventBus.$on('open-search-modal', this.open)
はい。括弧を書いていたのが間違いでした。

うっかり括弧付きで書いてしまうことがあるのですが、どうして括弧付きで書くとダメなんでしょう。

「括弧をつけるとメソッドが即座に実行されてしまう」
「コールバック関数を書く時は括弧無しで書く」

コールバック関数として渡したいときは括弧書いちゃいけないんですね
わかりました~

…でもなんで?
納得できなかったので調べてみました🧐

具体的な例で考えてみる

わかりやすいようにSquare関数を用意します。
function Square(number) {
  return number*number;
}
これは以下と同等です。
const Square = function(number) {
  return number*number;
}
2つめのように表現すると関数も他の定数や数値のように受け渡しが可能なものだということがわかりやすくなりました。(こういうのを第一級オブジェクトというらしいです。)

括弧ありでの挙動

let number = 3;
let result = Square(number);
このときSquare関数が引数にnumberをとって実行され、変数resultには「9」がセットされます。

括弧なしでの挙動

let number = 3;
let result = Square;
このとき変数resultにはSquare関数そのものがセットされます。
つまりresult()とすることでSquare関数を実行できるということです。
let output = result(3); 
console.log(output); // equal to 9
これは以下と同等です。
let output = Square(3);
resultを呼びだすとき、実際にはSquare関数を参照しているんですね。


 

今回の事例に戻って

さて最初のVueの例に戻ります。
created: function () {
       EventBus.$on('open-search-modal', this.open())
   },
   methods: {
       open() {
           console.log('open');
           this.isOpen = true;
       },
  },
},
上記のように書いた時、createdの段階でopen関数が実行されてコンソールに”open”が表示されます。
open関数は変数isOpenをtrueにするのみの関数のなのでその実行結果がイベントハンドラとして渡されても、イベント捕捉時に何も実行されません。

open() { 
    console.log('open'); 
    this.isOpen = true; 
},
//これは以下と同じ
open = function() {
    console.log('open'); 
    this.isOpen = true;
}
 
なのでイベントハンドラにopen関数自体をコールバック関数として渡すためには括弧無しのthis.openと書かなければいけません。
納得できましたε-(‘∀`;)ホッ


とってとっても参考になりました。
https://stackoverflow.com/questions/3246928/in-javascript-does-it-make-a-difference-if-i-call-a-function-with-parentheses

アロー関数とかほんと括弧のお化け。arimasさんに同意します。
https://qiita.com/arimas/items/448f411e78d12f7d5208

Java14とJavaFXを使い普通のブロック崩しを作る

はじめに

安藤です。
世の中の情勢が厳しい昨今ですがいかがお過ごしでしょうか。私は元気です。
今回は3/17にリリースされたJava14を早速使ってみたという話です。

Java14について

全容はきしださんがまとめてくれています。いつもお世話になっています。
Java 14新機能まとめ
個人的に注目したいのが、ついに正式版になったPackaging Toolです。
およそ1年前にこちらの記事でも触れましたが、ようやく公式のパッケージャが登場しました。

今回作ったもの

本題です。
この記事のためだけにJavaFXを使ったシンプルなブロック崩しを作りました。
javafx-breakout
breakout.zip
実は前職で新卒研修時に暇だったので似たようなものを作ったことがあり、それを思い出しながら作っていたのですが、想像の3倍くらい大変でした。
新しい構文を使うことと、できるだけ内部状態の変更を起こさないことをコンセプトに作りました。

全体の構成

ProcessingのようにCanvasで画面を描画していきます。fxmlの記述はこれだけです。

<?xml version="1.0" encoding="UTF-8"?>


<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.Group?>
<Group xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1"
       fx:controller="jp.imagemagic.breakout.FieldController"
       onMouseMoved="#mouseMove" onMouseClicked="#mouseClick">
    <children>
        <Canvas fx:id="canvas" focusTraversable="true" width="400" height="600"/>
    </children>
</Group>

画面にはブロック、ボール、バーがありますが、統一的な計算のために以下を用意しました。
Recordはイミュータブルな推移をさせるためにうってつけです。

package jp.imagemagic.breakout;

import javafx.scene.paint.Color;

interface Drawable {
    Vector pos();

    Vector size();

    default DrawType drawType() {
        return DrawType.Rect;
    }

    default Color fill() {
        return Color.WHITE;
    }

    default Color stroke() {
        return Color.BLACK;
    }
}


package jp.imagemagic.breakout;

public record Vector(double x, double y) {
    public Vector move(double dx, double dy) {
        return new Vector(x + dx, y + dy);
    }

    public Vector move(Vector v) {
        return move(v.x, v.y);
    }

    public Vector scalar(double n) {
        return scalar(n, n);
    }

    public Vector scalar(double nx, double ny) {
        return new Vector(x * nx, y * ny);
    }
}

クラス構成の大枠は以下の通りです。これはtetrixの影響を受けた構成になっています。
  • 画面からの入力の処理と一定時間ごとに画面の推移を行うFieldController
  • 現在の状態を保持するState
  • Stateの推移ロジックをもつField
  • FieldControllerとStateを仲介するViewUnit

package jp.imagemagic.breakout;

import java.util.function.Consumer;
import java.util.function.UnaryOperator;

final class ViewUnit {
    private final Field field;
    private State state;

    ViewUnit(double w, double h) {
        field = new Field(new Vector(w, h));
        state = field.initState();
    }

    void trans(UnaryOperator<State> trans) {
        state = trans.apply(state);
    }

    UnaryOperator<State> moveBar(double x) {
        return field.moveBar(x);
    }

    UnaryOperator<State> moveBall() {
        return field.moveBall();
    }

    UnaryOperator<State> transStatus() {
        return field.transStatus();
    }

    void drawView(Consumer<Drawable> draw, Consumer<Status> statusDraw) {
        state.view().objects().forEach(draw);
        statusDraw.accept(state.status());
    }
}


// 一部抜粋
public class FieldController implements Initializable {
    @FXML
    private Canvas canvas;
    private GraphicsContext gc;
    private ViewUnit unit;

    public void mouseMove(MouseEvent e) {
        transAndDraw(unit.moveBar(e.getSceneX()));
    }

    public void mouseClick() {
        transAndDraw(unit.transStatus());
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        gc = canvas.getGraphicsContext2D();
        unit = new ViewUnit(canvas.getWidth(), canvas.getHeight());
        final var timeline = new Timeline(new KeyFrame(new Duration(10), e -> transAndDraw(unit.moveBall())));
        timeline.setCycleCount(Timeline.INDEFINITE);
        timeline.play();
        drawView();
    }
}

補記: jpackageによるパッケージング

予めjlinkでランタイムの大きさを削っておくのがお勧めです。
インストーラを伴わないものを作ろうと色々と試した結果、このようなコマンドになりました。
jpackage -t app-image -n breakout -d dist -i app --main-class jp.imagemagic.breakout.Main --main-jar jp.imagemagic.breakout.jar --runtime-image jregram.min\ --java-options "--add-exports javafx.base/com.sun.javafx.reflect=ALL-UNNAMED --add-reads javafx.base=ALL-UNNAMED --add-reads javafx.graphics=ALL-UNNAMED --enable-preview"
appにjarファイルがあり、distにbreakoutというディレクトリができます。
jarファイルにしていますが、オプションを変えればクラスファイルでも行けると思います。

UWPアプリからOpenCVしてみる(その1)

矢野です。

プロトタイプ的にWindows用のアプリケーションを新たに作成するにあたり、ちょっと考えました。Windows Formsなら自分もそれなり多少は経験もあるけど、新規でつくるのに今さらFormsというのもどうなのかしら? でもWPFやUWPも結局のところあまり普及してきている感じがしないし、枯れたFormsに比べれば、情報はかなり少ない。XAML Islands? 何それ?
このプロトタイプは、PCに接続したWebカメラで撮影した画像をOpenCVでちょちょいと弄れるだけでいいのですが、でもFormsからカメラなどメディア関連の制御をするのは結構大変です。DirectShowとかMedia Foundationなどを使ってC++でゴリゴリ書く気になれば色々細かいところまで自由になるけれど、プロトタイプなのにそのへんをめちゃくちゃ頑張る気にはなれないし、とはいっても入手が容易なC#向けのラッパーだとちょっと古かったり、ちょっと不便だったり……。
で、けっきょくUWPアプリをC#で書くことにしました。それでも周回遅れなのかもしれませんが、せっかくの機会ですから少しでも新しい仕組みに追いついておきたいということで。
  • UWPアプリ上でMediaCaptureを使ってWebカメラにアクセス
  • Webカメラから取り込んだ画像をOpenCVで処理
  • 処理した画像を表示
これらを実現する簡単なアプリをつくってみたいと思います。 Visual Studio 2019を起動し、C#/Windows/UWPの「空白のアプリ(ユニバーサルWindows)」を新しいプロジェクトとして作成。
ソリューションエクスプローラーからPackage.appxmanifestをダブルクリック→機能タブの[Webカメラ]と「マイク]にチェックを入れて保存。
MainPage上にツールボックスからCaptureElementを配置し、適当な名前(captureElement)を付ける。StretchプロパティをUniformToFillにしておく。 MainPageのOnNavigatedTo(NavigationEventArgs)メソッドをオーバーライドする(awaitな呼び出しを行うので、メソッドにasync修飾子を追加します)。
protected async override void OnNavigatedTo(NavigationEventArgs e)
{
    var capture = new MediaCapture();

    await capture.InitializeAsync();

    var props = capture.VideoDeviceController
        .GetMediaStreamProperties(MediaStreamType.VideoPreview) as VideoEncodingProperties;

    await capture.VideoDeviceController
        .SetMediaStreamPropertiesAsync(MediaStreamType.VideoPreview, props);

    captureElement.Source = capture;
    await capture.StartPreviewAsync();
}
プロジェクトをビルドして起動します。

アクセス許可を確認するダイアログが表示された場合は、許可します。
  • マイクへのアクセスを許可しますか?→[はい]
  • カメラにアクセスすることを許可しますか?→[はい]
たったこれだけで、リアルタイムにカメラの画像が表示されました! すごい! 泣きそうなりながらC++でMedia Foundationで書いた時とは大違い!(大げさ)
その2に続きます。

Illustratorスクリプト開発の便利ツール

はじめに

こんにちは、イメージ・マジックのもあいです。

前回ブログを書いたのが約一年前、時間が経つのがどんどん早く感じられてきている今日この頃です。
富士ゼロックススーパーカップも終わり、Jリーグもそろそろ開幕する時期になってきました。 今回は、2018年7月頃に公開したIllustratorスクリプトのあれこれを書いた後にIllustratorスクリプトを開発するに当たって便利なツールを見つけましたので、簡単な使い方を紹介します。

ExtendScript Debugger

見つけたツールは、Microsoft社が公開しているVisual Studio Code のExtensionである ExtendScript Debugger というものです。これはAdobeが公開している公式なツールになります。

インストール

手順は下記の通りです
  • Visual Studio Codeをインストール
  • Visual Studio Codeの拡張機能(Ctrl + Shift + X)で ExtendScriptで検索
  • ExtendScript Debugger をクリック
  • インストール

使い方

  • デバッグしたいIllustratorスクリプトをVisual Studio Codeで開きます
  • Visual Stuio Codeのステータスバーにあるターゲットアプリケーションを選択をクリックし、画面上部に現れるターゲットアプリケーションを選択というボックスに使用するアプリケーション(今回はAdobe Illustrator 2020)を選択します。この時点でIllustratorが起動していない場合はIllustratorを起動するかどうかを聞いてきますのではいを選択します。
  • F5キーを押下し、環境の選択でExtendScript Debugを選択すれば、デバッグを開始できます。
  • ブレークポイントを設定すれば、そこで止めることも可能です。
  • 変数、ウォッチ式、コールスタックと行った情報を見ることができます。
  • グローバルなオブジェクトの情報も見られます。
  • ローカル変数の情報も当然見られます。

最後に

以前は Extendscript Toolkit CC をインストールしていましたが、このツール自体がEOLなので、インストール手順が煩雑なのと、新規ドキュメントを作成する処理を実行できないという問題がありましたが、今回紹介しているツールはそんなことも無くデバッグできるので、開発がだいぶ楽になったと思っています。

年末にいろいろ振り返る

こんにちは株式会社イメージ・マジックのsoenoです 。
今週テックブログということでクリスマスっぽい何かを考えていましたが、
終わりましたね。クリスマス。
それでも何か季節感のある投稿をと思った結果、今回のテーマは振り返りです。
会社のブログなので入社以来で いろいろ振り返ってみようかと思います。
 

入社以来何が変わったか

変わったこと(いろいろありますが今回は3つ。)
  1. 黒い画面を怖がらなくなった。
  2. IntelliJ IDEA と少し仲良くなった。
  3. データが降ってくると思わなくなった。
詳細は以下の通りです。



変化の詳細

黒い画面を怖がらなくなった。

 コマンドプロンプトの入力機会が増え、
コマンドプロンプトで何かを操作することは特別で危険なものという意識から
環境を整えたり、エラーの確認に必要なものと理解しました。


IntelliJ IDEAと少し仲良くなった。

直近ではgitでやらかしたときの後始末でお世話になりました。
個人的には
  「CapsLock + Alt + 縦に選択」 での複数エリア編集からの
  「ctrl + w」 での単語選択、の後の入力がとても素敵だと思います。
   →構造の近い要素で単語の長さを気にせずにクラスを足すなどできます。



データが降ってくると思わなくなった。

 フロントのみ開発していると、 型やら数は最初に取り決め
サーバーから取り決めた形で降ってきたデータで色々する。(その後は知らない。)
 という認識が、サーバー側の処理も見える環境によって、 phpが渡すデータを作り、その大本にはデータベースがいて …… などという 一連のやり取りとしてみえるようになりました。(何ならDBが書き換わるところまで見えます。)

 よって、データは降ってくるものではなく、それ用に加工され渡されている。という理解になりました。


まとめ

 全体的に古めで人力な開発から、フレームワーク等を使った新しく、パワフルな開発環境へ変わった印象です。


おわりに

朝のエレベータで死ぬほどネストしたscssを思い出し、
さらにそれすら修正後(css→scssへ)のデータだったことを思い出し 。
いろいろ変わったものだとしみじみ思いました。

今後もいろいろな変化があると思いますが、
その変化が良いものであるといいと思います 。

それでは少し早いですが良き年末、良き新年を!

Symfony Form Type Options Guessing

こんにちは、岡野です。
Symfonyで 開発中のプロジェクトでvalidateのコードを減らしたく、Form Type Options Guessingを色々と試した結果を共有します( Symfony4.3 )。
参考:https://symfony.com/doc/4.3/forms.html#form-type-options-guessing
1.既存のコード
FormBuilder記述
  add('sort', TextType::class)
Entity記述
  @ORM\Column(type="integer")
生成HTML
  <input type="text" id="..." name="..." required="required">
  (以降、id/name/required属性は省略)
type=”text”の場合、EntityでsetSort(?int)などと型指定していると、数値でない”a”などをsubmitした際にPropertyAccessorでInvalidArgumentExceptionが発生してしまう。
2.クラスを省略
FormBuilder
  add('sort')
Entity
  @ORM\Column(type="integer")
HTML
  <input type="number">
type=”number”になった。
3.Rangeアノテーションを追加
FormBuilder
  add('sort')
Entity
  @ORM\Column(type="integer")
  @Assert\Range(min="0", max="99999")
HTML
  <input type="number" maxlength="5" pattern=".{1,}">
maxlength/pattern属性は増えたが、min, max属性は付けてくれない。 type=”number”の場合maxlength属性が効かない様で、123456の様な値でsubmitできてしまう(以降Chrome78で確認)。
4.add()の引数でmin/maxを指定
FormBuilder
  add('sort', null, ['attr' => ['min' => 0, 'max' => 99999]])
Entity
  @ORM\Column(type="integer")
  @Assert\Range(min="0", max="99999")
HTML
  <input type="number" maxlength="5" pattern=".{1,}" min="0" max="99999">
123456は入力できるがsubmitはできない。
5.add()の引数でpatternも指定
FormBuilder
  add('sort', null, ['attr' => ['min' => 0, 'max' => 99999, 'pattern' => '\d{1,5}']])
Entity
  @ORM\Column(type="integer")
  @Assert\Range(min="0", max="99999")
HTML
  <input type="number" maxlength="5" pattern="\d{1,5}" min="0" max="99999">
type=”number”の場合pattern属性が効かない様で、123456が入力できる。submitはできない。
結局、開発中のプロジェクトでは3.で進めることにしました。

使いやすいUIとは?

8月に入って暑い日が続いています。脱水には気を付けなければ・・・と思いつつコーヒーばかり飲んでいます。テックブログ、今週の担当は浦です。
最近は開発の上流工程を担当していたので、テックブログのテックってなんだっけ・・・と若干悩みつつ、今回は「使いやすいUI」とはなんぞや?というテーマで軽くまとめてみます。

ユーザーにとっての使いやすさ

使いやすいかどうか、直感的かどうかは、ユーザーによってそれぞれ異なります。
えーーーって思った方、すみません。ですが、業務アプリの設計過程で様々なお客さんとお話してきた経験上、今まで使っていたものに近いもの、見慣れたものを「使いやすい」とする人が大半でした。
どのようなUIに慣れているかは人によって異なるので、何を直感的と感じるかも人によって異なるわけです。
したがって、ここではユーザーの「慣れ」の要素は考慮せず、どのようなルールを持たせたUIがいいのか人間工学をもとに挙げてみます。
 

人間に合わせたUI設計のルール

1. 関連の高い要素は近づけて配置する

人間は、位置的に近くに配置されたものを関連のある情報として認識します。
例えば、画像とキャプションがその他の要素間より近くに配置されていれば、一目でどのキャプションがどの画像を説明しているのか判断できます。
逆に関連の低い要素間は、意識して余白を大きく取ることで区別しやすくなります。

2. 同じ要素・レイアウトを意識的に繰り返す

人間は、過去の体験から予測して行動します。
慣れたものは使いやすいと前述しましたが、それは1つのアプリ内でも同様のことがいえます。
ボタン配置等のレイアウトをどの画面でも統一すれば、何がどこにあるのかすぐわかるため、ユーザーは直感的に操作できます。

3. 重要な要素を左上から右下への対角線上に配置する

人間の視線は左上から右下へと移動します。「グーテンベルク・ダイアグラム」とも呼ばれますね。
例えば画面下部にボタンを配置している場合、重要な機能のボタンは右に置いた方が意識されやすいです。

4. 重要な要素は大きくする

何を当たり前のことを!と思われるかもしれませんが、人間の視線は大きいものから小さいものへ移動します。
情報の重要度によって表示する大きさを分けることは、シンプルですが効果が大きいと思います。

5. 関連の高い要素を同じ配色にする

人間の視線は同じ色のものへ移動します。
グルーピングできる要素同士や、重要度が同じ要素同士を同じ配色にすることで、関連要素を辿りやすくなります。

まとめ

人間工学的にどのようなUIが使いやすいか挙げてみました。
ちなみに、1.2. はデザインの4大原則の1つでもあります。
興味のある方は調べてみていただければと思います。

ImageMagickコマンドの注意点

こんにちは。イメージマジック三浦です。 2019年が後半に入りました。あっという間に半年過ぎたとも、まだ半年あるんだなとも思います。 今回は「ImageMagickコマンドの注意点」と題して書きます。
業務で、WindowsOSに導入することを念頭に ImageMagickコマンドを調査しましたが、その時に気づいたことを書いてみます。

ImageMagickとは

画像の変換や表示、内部情報などを見るソフトウェア群です。詳しい説明は他のサイトを参照してください。
 https://imagemagick.org/index.php 

インストールについて

ImageMagick開発元が、様々なOS向けにインストーラを提供しています。
特にWindowsOS用では、インストーラ方式のものと解凍して配置するだけのものがありますが、今回はWindowOS向けのポータブル版を使うことにしました。 ImageMagickコマンドの動作には、VC2013再頒布可能パッケージのインストールが必要とされています。最初のパッケージの後に、更新版が出ていますので、導入が必要だとすれば更新版の方がよいかと思います。
(VC2013再頒布可能パッケージ)
https://www.microsoft.com/ja-jp/download/details.aspx?id=40784
(VC2013再頒布可能パッケージの更新版)
https://support.microsoft.com/ja-jp/help/3138367/update-for-visual-c-2013-and-visual-c-redistributable-package
ただし、OSによっては同パッケージをインストールしなくても動いてしまうケースがあるので、実際の画像を使った動作確認は欠かせません。

動作確認をしてみて気づいたこと

WindowsOS向けのポータブル版ImageMagickを動作確認をする中で、ImageMagickコマンドの1つ「convert」が動かないという現象がありました。 以下のようなディレクトリ構成で、
E:\hoge
[D] ImageMagcik
[F] test.psd
PowerShellで、カレントディレクトリをImageMagick直下に移動してconvertコマンドを実行すると、以下のような結果が出ます。
(convertコマンドの詳細は割愛します)。
PS E:\test\ImageMagick&amp;gt; convert ../test.psd[0] ../test.png
無効なパラメーターです - /test.psd
PS E:\test\ImageMagick&amp;gt;
1つ上の階層のディレクトリに「test.png」というファイルができると期待したのですが、エラーになりました。
「convert /?」と入力するとWindowsOSのコマンドのヘルプが出てきたので、ImageMagickの「convert」コマンドを実行するつもりが、WindowsOSの「convert」コマンドを実行していたと考えられます。特に、コマンドプロンプトだと発生しないので、混乱しやすいところです。 PowerShellで期待した結果を得るには、以下のように指定する必要がありました。
PS E:\test\ImageMagick&amp;gt; ./convert ../test.psd[0] ../test.png
または
PS E:\test\ImageMagick&amp;gt; .\convert ../test.psd[0] ../test.png

同じような現象を回避するために

今回のような現象を回避するには、先頭に「.\」を付加してカレントディレクトリのコマンドであると明示する方法が無難だと感じました。「.\」が付いていれば、コマンドプロンプトでもPowerShellでも同じ動きをしてくれるためです。 他には「convert」コマンドが、最新バージョンの1つ前のImageMagick6系と互換性を維持するために提供されるものなので、最新バージョンの「magick」コマンドを使うことが考えられます。

最後に

これから暑くなるので、体調の管理には気を付けてください。
個人的には、睡眠時間の確保と毎日の食事でネバネバ食材を食べることに気を付けていますが、身体が軽くなったように感じているので、これからも続けていきたいと思います。