omohayui blog

おも‐はゆ・い【面映ゆい】[形][文]おもはゆ・し[ク]《顔を合わせるとまばゆく感じられる意》きまりが悪い。てれくさい。

Google Fonts が @import で読み込まれないとき

Google Fonts とは

fonts.google.com

Googleさんが提供している。Webフォント。
サーバー上の各フォントデータを読み込むことで、オサレなフォントが使えるようになるわけです。 そして無料。

起きていた問題

はてなブログのデザインをちょっと変えようと思って、
[デザイン] > [カスタマイズ] > [デザインCSS] の一番上で “Share Tech Mono” を import してみたところ、
プレビュー画面には表示されるが、更新後のブログには Google Fonts が反映されない。

@import url('https://fonts.googleapis.com/css?family=Share+Tech+Mono');

原因

詳細までは調べられてないが devtool 等で確認したところ読み込みタイミングがよろしくなさそう。

回避策

[デザインCSS] で読み込むのをやめて、headで指定するように修正。
[設定] > [詳細設定] > [検索エンジン最適化] > [headに要素を追加] に下記を追加するだけ。

<link href="https://fonts.googleapis.com/css?family=Share+Tech+Mono" rel="stylesheet">

これでブログ上も反映されるようになった。

リサイズした画像がぼやける件

Image Resizing Algorithm

経緯

Retina対応等が進む中、大きい画像をWeb上で縮小表示し高解像度ディスプレイに対応するケースが多々あります。
がしかし、ブラウザ固有のリサイズのアルゴリズムや表示画像サイズによっては、レンダリングされた画像がぼやけることも。
そこで、リサイズのアルゴリズムを正しく理解した上で、適切な対応方法を検討したい、という話なのです。

縮小表示の例

表示サイズ width: 280px
(原寸)
width: 140px
(4px → 1px)
width: 145px
(3.86...px → 1px)
width: 145px
(3.86...px → 1px)
image-rendering auto auto auto pixelated
画像

(サンプル画像が古いことへの突っ込みは受け付けません。久しく絵と呼べるものを描いていないのです。)

Chromeで見た場合

  • width: 140px は実画像サイズの1/2なので、4ピクセルが1ピクセルに縮小される計算
    • ⇒ ボケない
  • width: 145px は実画像サイズから表示サイズに縮小する際にピクセル数が割り切れない少数になってしまう
    • ⇒ エッジがボケた感じになる
  • width: 145px に style属性で image-rendering: pixelated; を指定すると、縮小アルゴリズムが「最近傍 (Nearest Neighbor)」に指定される
    • ⇒ エッジがギザる

IEで見た場合

ChromeのリサイズアルゴリズムがBilinearやBicubicといったエッジを滑らかにするアルゴリズムであるのに対して、 IEは元々Nearest Neighborのような単純なアルゴリズムを使っているようで、width: 145px をIEで見てもボケるというよりギザる感じでした。 (※個人的な主観です)

拡大表示の例

表示サイズ width: 100px (原寸) width: 300px (3倍) width: 300px (3倍)
image-rendering auto auto pixelated
画像

拡大表示の方がアルゴリズムの違いがわかりやすいです。

  • 原寸の画像はあえてドットが分かりやすいようにしている 100x100pxの画像
  • そのままブラウザで3倍のサイズに指定して表示すると、ドットのギザギザはブラウザのレンダリングの仕様によってぼかされて表示される
  • style属性で image-rendering: pixelated; を指定すると、原寸のピクセルをそのまま拡大され、ドットがはっきり表示される

image-renderingの指定について

ブラウザ上のリサイズアルゴリズムを指定するのに使っていた image-rendering ですが、 まだ実験段階、開発途上といったところみたいです。

developer.mozilla.org

説明
auto
  • デフォルト値
  • バイリニア (Bilinear) リサンプリングなどの「滑らかな」色が許容されるアルゴリズムで拡大/縮小
  • 高品質
crisp-edges
  • 画像内のコントラストとエッジを保つアルゴリズムにより拡大/縮小
  • 画像の処理過程で滑らかな色やぼかし効果が現れない
  • ピクセルアートなどの画像を想定
pixelated
  • 画像拡大時に「最近傍 (Nearest Neighbor)」などのアルゴリズムが使用され、画像が大きなピクセルで構成されたように表示される
  • 縮小する時は、'auto' と同じになる
    • みたいな記述があるが実際に試してみると縮小表示でも「最近傍 (nearest neighbor)」が使われている模様

各ブラウザに対応させたい場合

.pixelated {
  -ms-interpolation-mode: nearest-neighbor;   /* IE8+ */
  image-rendering: -webkit-optimize-contrast; /* Safari (WebKit) */
  image-rendering: -moz-crisp-edges;          /* Firefox (Gecko) */
  image-rendering: -o-crisp-edges;            /* Opera 12.x */
  image-rendering: pixelated;                 /* Chrome 41+, Opera 29+ (CSS4) */
}

参照:http://memo.sdn-project.net/post/113148316679/pixelated

よく使われるリサイズアルゴリズム

滑らか度
名称
説明
NearestNeighbor
(最近傍補間)
  • 最も単純な拡大アルゴリズム
  • 参照する位置に最も近い位置にある画素の輝度値を参照する
  • 拡大縮小後の画素の実数を整数とみなしたときの誤差をそのまま表示すため、エッジにはジャギー(ギザギザ)が発生する
  • 処理速度が非常に高速
Bilinear
(バイリニア補間)
  • 単純な線形補間による拡大アルゴリズム
  • 補間対象となるピクセル周辺の2×2画素(4画素)を使って、輝度値を直線的に補間して輝度値を求める
Bicubic
(双三次補間)
高+Lanczos3
  • 動画や写真の縮小処理などで高品質で有名
  • 補間対象となるピクセル周辺の6×6画素(36画素)のピクセルを参照し、Bicubicとは異なる計算式で算出
  • 処理速度は最も遅い
  • 線画の縮小時にちらつきが見受けられたりする(経験談

参照:http://imagingsolution.blog107.fc2.com/blog-entry-142.html, http://www.geocities.jp/numada777/ip05.html, http://www.amedama.com/blog/20110220392.html

対応案とまとめ

縮小表示

  • 理想は表示サイズの2倍3倍といった整数値でピクセル表示ができる元画像サイズを用意する(とにかくこれ)
  • ユーザーに入稿してもらったものを表示する際や1つの画像を同一画面で使いまわす際、縮小時にエッジがボヤける(特に線画)と言った場合は、 CSSで image-rendering を指定するといった手法もあり(※あまりおすすめできない)

拡大表示

  • 通常の画像の場合は表示画像より大きいもの(Retina対応するのであれば4倍)を用意する
  • ドット絵等あえてジャギー(ギザギザ)を見せたいものは、CSSで image-rendering を指定する方法もあり

Goのresizeパッケージ、giftパッケージを使って画像ファイル自体のリサイズ処理も色々と試したので、その話も書いておきたい気持ちある。

Riot.js のタグファイル名を *.tag.html にする

なぜやるのか

[翻訳] Riotjs Style Guide - Qiita

こちらでも言われているように IDEの補助向上という理由が大きいです。
そして、ただ .html にしてしまうと Riot の tag ファイルだということが
分かりづらくなるということで .tag.html に。

手順

in-browser-compilation の場合

上述の記事にもあるように読み込むファイル名変更するだけ

Webpack tag loader の場合

上述の記事にもあるように loaderの設定を .tag.html に合わせる

pre-compilation の場合

それぞれの compiler に合わせて custom extension を設定する

browserify ( riotify ) でやってみた

gulp task の修正

  • riotify の compile-options に custom-extension で tag.html を指定します
    "browserify": {
        "transform": [
+            [ "riotify" ],
-            [ "riotify", {"ext": "tag.html"} ],
        ]
    }

tagファイルの一括 rename

# 適宜に環境に合わせて
% rename s/\.tag/\.tag\.html/ *

tagファイルを読み込んでいる箇所を一括置換

# 適宜に環境に合わせて 
find . -type f -name '*.js' | xargs perl -i -pe 's/\.tag/\.tag\.html/g'

これだけでIDEがいい感じに動くようになった :D

2017/04/03 追記

IDE側の設定で *.tag をhtmlとして認識させられるのであれば、この対応は不要です。
IntelliJ IDEA では Editor > File Types で変えられたので対応不要でした _(:3 」∠ )_

GAE で監視ファイルが多すぎて auto reload が走らない件

何が起きていたか?

・ローカル開発環境で go のテンプレートファイルを更新しても GAE の auto reload が走らない
*.go ファイルを更新したときは走る
・go version go1.6.2 (appengine-1.9.40) darwin/amd64

goapp 起動時の error log

/usr/local/Cellar/app-engine-go-64/1.9.40/share/app-engine-go-64/google/appengine/tools/devappserver2/mtime_file_watcher.py:115: UserWarning: There are too many files in your application for changes in all of them to be monitored. You may have to restart the development server to see some changes to your files.

原因

  • 監視ファイルが多くなった為、ファイル監視の閾値を超えてしまった
  • たぶん node module 系が含まれてしまっている

閾値と監視対象ファイルをどこで設定しているのか

ファイル数上限

github.com

_MAX_MONITORED_FILES = 10000

監視対象外ファイル

python-compat-runtime/watcher_common.py at ee5cffab9b62ba293c61228260735ad5c9a9395c · GoogleCloudPlatform/python-compat-runtime · GitHub

_IGNORED_FILE_SUFFIXES = (
    # Python temporaries
    '.pyc',
    '.pyo',
    # Backups
    '~',
    # Emacs
    '#',
    # Vim
    '.swp',
    '.swo',
)

とりあえずの対応

  • これらの設定は固定値で外から指定できなさそうなので一旦直接書き換えた・・

(その1)ファイル上限数を変更

vim /usr/local/Cellar/app-engine-go-64/1.9.40/share/app-engine-go-64/google/appengine/tools/devappserver2/mtime_file_watcher.py

下記のように書き換え

-- _MAX_MONITORED_FILES = 10000
++ _MAX_MONITORED_FILES = 100000

(その2)除外ファイルに追加

vim /usr/local/Cellar/app-engine-go-64/1.9.40/share/app-engine-go-64/google/appengine/tools/devappserver2/watcher_common.py

下記のように追記

_IGNORED_FILE_SUFFIXES = (
    # Python temporaries
    '.pyc',
    '.pyo',
    # Backups
    '~',
    # Emacs
    '#',
    # Vim
    '.swp',
    '.swo',
++    '.js',
)

デザイニング・インターフェース(1)

読書会向けの自分用のメモです。

1章 ユーザの行動

インターフェースデザインの格言

「汝のユーザを知れ ― 彼らはあなたとは別人なのだ!」

インターフェースデザインはユーザとマシン(モノ)の会話を仲介する手段

目的達成の手段

ユーザが本当に達成しようとしている目標が何なのか見極める

”なぜ” その機能やソリューションを求めているのか、十分に現状把握ができるまで質問を繰り返そう

(!) より魅力的で成功するアプリケーションをつくるためには、
 既存のメソッドにあてはめるだけでなく、数多くの「よりソフトなファクター」を考慮する必要があるよ

ユーザ調査の基礎

ユーザグループはそれぞれ固有の性質を持っている

秘訣は対象となるユーザーグループについて “おおむね” 該当する事実は何なのかを見極めること

そのメソッドとして挙げられたもの

ユーザの学習意欲

ユーザーは自分の作ったインターフェースを学習するためにどれくらいの努力をしてくれるのか考慮しよう

  • 中級〜上級のユーザ
    • 開発・管理ツールなど
  • 永遠の初心者
    • インストールウィザードなど

ユーザの学習意欲がインターフェースの随所に関係してくるよ

(!) いずれのユーザ層にも対応するデザインを作りたいという苦悩も発生してくる
⇒ それは2章のマルチレベルのヘルプでやるよ

パターンの解説

14個もあるので簡単に

1. 安全な探検

優れたソフトウェアでは、慣れていない操作をやってみてからもとに戻して、また別の操作を試してみる、ということがストレスなく実施できる

⇒ ユーザは探検することで多くを学び意欲的になる

2. 即座の喜び

アプリケーションを使い始めて即座に “成功体験” が得られる

⇒ プリケーションに対する信頼が強まると同時に、ユーザの自信も増していく

3. 最小限での充足

より良いモノや手段があると知っていても、多くの時間や労力がかかる場合、人は “最善” ではなく “必要十分” な結果を受け入れたがる

(!) 最小限での充足は、多くのユーザに中途半端な習慣を身につけてしまう要因でもある
 効率の良い新しい手順で改善される労力 と 古い習慣を打破して新しいことを身につける労力 のトレードオフ

4. 途中での方針変更

ユーザのゴールは操作途中に変化することがある

⇒ ユーザが方針変更できる機会を提供する必要がある

(!) ただし、方針変更させない妥当な理由が伴うケースは別だよ
 ⇒ それは2章、3章で

5. 回答の先送り

ユーザに対して、最初からあまり多くの先行的選択を迫らないこと

⇒ 「2. 即座の喜び」につながるよ

6. 少しずつの組み立て

ユーザの創造的活動は小さな変更の積み重ねによって少しずつ行われることが多い

⇒ 素早い変更と保存やプレビュー、フィードバックなどの機能で創造的活動をサポートしたほうがいいよ

7. 習慣化

習慣化はユーザがそのツールの上級者へと成長していくのに役立ち効率をアップさせる

(!) ただし、アプリケーション間での一貫性が重要だよ
 アプリケーションごとに習慣が違うと逆に混乱させるよ

8. 小刻みな休止

小刻みな休止に対応するポイントは、その機能を簡単に実行でき、すばやく呼び出せるものにすることだよ

9. 空間的な記憶

何かを探すときに人は空間的な記憶を用いることが多い

  • 既に配置されているコントロールの位置を変えることによる混乱
  • 「7. 習慣化」と同様にプラットフォーム間を跨いだときの一貫性の欠如

⇒ 3章ログインツール、4章反応的な追加表示 で詳しくやるよ…

10. 展望的な記憶

ユーザはこれから何かしようと計画するとき展望的な記憶を忘れないように手元に残す

⇒ 展望的な記憶を促すためのインターフェースを提供しよう

(!) 機能を提供することよりも、作成中のものを勝手に片付けたり、
 ユーザの要求なしに自動的に整列やソートするような "親切" 処理が行われてしまっていないか注意しよう

11. 繰り返しの効率化

ユーザはさまざまな種類のアプリケーションで、同じ操作を何度も繰り返し実行していることがある

  • よく使われる機能の繰り返し処理のサポート
  • 操作の記録と再生 ⇒ 6章のマクロで詳しくやるよ

12. キーボードのみ

身体上の困難によってマウスを使うことができない人々やキーボードに手を置きっぱなしで作業したい人がいるよ

13. 他者のアドバイス

他のユーザのアドバイスは直接的か間接的かに関わらず、何かきめるべきことがある時に我々の判断に影響を与える

そしてそれが良い結果につながるケースが多い(と言っているように聞こえる)

⇒ 他者のアドバイスを集める仕組みを考えてみよう 2章マルチレベルのヘルプ など

14. 個人的レコメンデーション

「13. 他者のアドバイス」をさらに有効にする個人的レコメンデーションを促す仕組みについても考えよう

まとめ

より効率良くユーザの目標達成を可能にするインターフェースのパターンや考え方を学ぼう!