Chienomi

Mimir Yokohamaウェブサイトのリニューアル

開発::web

Mimir Yokohamaのウェブサイトの全面リニューアルを行った。

リニューアル作業はデザイン検討から数えると約2年、問題のある記事など今回の懸案の解消を含めると3年半もの期間がかかった。

基本デザイン

デザインに関してはHarukamy’s Chatshowがベースになっている。

中央にコンテンツボックスがある「古の」デザインだが、コンテンツボックスには本文しかない。 これは、リーダービューがそのような表示であることをリスペクトしている。

機能は従来とは異なり、JavaScriptを採用した。 Harukamy’s Chatshowでは(結構わかりづらい)星マークがメニューになっているのだが、本文以外の要素はこのドロワーに押し込めている。

Mimir Yokohamaではよりわかりやすいハンバーガーメニューになっており、ヘッダー固定になった。 これらは回帰要素が強く、結構な量を旧ウェブサイト(2018-2020のもの)から持ってきている。 例えば、ハンバーガーメニューのアニメーションなどだ。

また、Harukamy’s Chatshowと違い、ドロワーは2段構成になっている。 メニュードロワー自体もタブになっていて複雑だが、それとは別に右端にインフォメーションドロワーが用意されている。 スマートフォンなら気づきやすいが、PCで広い画面で見ている人だと言われないと気づかないかもしれない。 私としてはヘルプを読んでほしい。

従来同様、最低限の機能しかないウェブブラウザでも可読であるよう、JavaScriptなしでもすべてのページにナビゲートされる。

また、Harukamy’s Chatshowで採用したウェブフォントも同様に採用している。 「日本語フォントは漢字を除外しても十分に雰囲気や可読性に貢献する」という点を利用したものだが、コーディングフォントとして出しているHermitは5052バイト、本文フォントのクレーのサブセットは33464バイトに抑えられている。 クレーはフォントワークスによる硬筆フォントで、非常に美しく可読性が高い。SIL OFLで提供されている。

ウェブフォントの問題は容量であり、容量が圧迫されるのは日本語フォント固有の問題だと言っていいようなものなので、工夫すればフォントの多くの問題に悩まされずに済む有力な方法であると感じた。

トップのアニメーション

トップページのみ全く違うデザインになっているMimir Yokohamaのウェブサイトだが、アニメーションそのものはCSSのtransitionになっている。

基本的な仕組みとしては画像が読まれるごとにカウントアップしていき、5に至るとプロパティが変更されアニメーションとなる。

これはスマートフォンで横並びにできない場合の処理と共存している。

なるべくコンパクトにしようとがんばったのだが、結果としてうまく表示されるときとされないときがあった。 問題は読み込みタイミングである。

カウントアップはimg要素のonloadイベントを利用している。 従来、スクリプトはdeferつきで呼ばれていたので、スクリプトが読まれるより先に画像を読み終わると、onloadイベントハンドラがundefinedでエラーとなり、うまく動作しない。

であればdeferなしにすれば良いかというと、今度はそのスクリプトがDOM操作を行うため、DOMツリーが出来上がっておらず要素がundefinedになり、これまたエラーになる。

結局、スクリプトを2つに分離し、onloadイベントハンドラを含む部分はページ埋め込みにして、なおかつDOM操作はイベントハンドラ内で行う(遅延評価する)ことで解決した。

正直、本来なら設計からやり直すべきヤツであった。

総額表示問題

リニューアルの必要性を最も高めていたのが総額表示の義務化だ。 別に表示すること自体は構わないのだが、このようにせよという例示が極悪である。

というのも、単純に価格を値で示すことが許されなくなり、結果大幅に表示領域を取る。 最近はスマートフォンの想定でただでさえ画面幅が足りないというのに、そのように表示領域をとられると表にはできなくなってしまうのだ。

例を示そう。次は3つのプランを横並びに比較できるようにしたものだ。

項目 プランA プランB プランC
ABCDE 10000 20000 30000

対して総額表示のルールに従うと

項目 プランA プランB プランC
ABCDE 10000円 (税込価格11000円) 20000円 (税込価格22000円) 30000円 (税込価格33000円)

となり、破綻してしまう。

そもそもMimir Yokohamaは当初消費税8%のときに創業された。このときは税込みの表示もしていたのだ。 ところが、消費税が上がったので税込みの価格表示を消した。このままではお上の都合で変更されるたびにリニューアルを行わなければならない。それは相当な手間だ。

ところが今度は総額を表示せよという。今後も消費税を上げる腹づもりだと言うにも関わらずだ。

私はとても怒っている。 机上の空論で勝手が過ぎる。

しかし、従わないわけにもいかない。そこでやむなく、単に表示を変換するのではなく、プランごとに別表にするなど非常にみづらくなるのを承知の上で構成から変更し、さらにeRubyによってページは計算的に出されるようにした。 具体的にはこんな感じ。

|クラス|1コマ(2時間)の料金|1コマ追加1時間の料金|
|:----:|------------------:|--------------------:|
<% 4.times do |clev| %>
|<%= clev %>|<%= price[:tutor][:base][clev][0] %>|<%= price[:tutor][:base][clev][0] %>|
<% end %>

priceメソッドは組み込みクラスのインスタンスをラップするというテクいことをやっていて、正しく書けば機能するが、こういう非常に限られた用途でない限りやるべきでないようなものになっている。

class PriceTabler
  def initialize(val)
    @val = val
  end

  def [](k)
    PriceTabler.new(@val[k])
  end

  def to_s
    sprintf("%s円 (税込価格 %s円)", @val.to_s.reverse.scan(/\d{1,3}/).join(",").reverse, (@val * 1.1).to_i.to_s.reverse.scan(/\d{1,3}/).join(",").reverse)
  end
end

def price
  PriceTabler.new(PRICE_TABLE)
end

もう少し解説すると、まずPriceTablerというクラスは任意のオブジェクトをラップする。基本的には#[]でアクセスするからHashオブジェクトである。PRICE_TABLEHashオブジェクトであり、かなり深くネストしたものになっている。 PriceTabler#[]はラップしたオブジェクトの#[]に転送するが、その戻り値をPriceTablerでラップする。ちなみに、#[]は引数を1つしか取らないから、ここでも機能は制限される。

#to_sはeRubyで<%= %>の戻り値にすると自動で#to_sが呼ばれることを利用している。 そして、この場合ラップしているオブジェクトはNumericであることを期待しており、@val * 1.1があるためNumericでない場合例外が投げられるかもしれない。そうでなくとも意図したようにはならない。

用語集のバグ

Pandocが要素を複数行に分割して出力するように変更されたため、同一行内でタグをスキップしていた用語集の変換処理がバグっていた。

この修正として、タグがクローズされていない場合、クローズされるまでは処理しないように変更した。

用語集の変換はPureBuilder SimplyのPost Pluginsを使っている。

記事修正

テクニカルな話題ではないが、かなりの量の記事の削除や修正を行った。 デザインそのものは1年くらい前にできていたが、リリースまで随分かかったのはこのためだ。

一番手間をかけたのがLINEよりもっといいアプリを考えてみませんかの修正。 この記事、もともとは「書きかけの下書きの状態で間違ってビルドしてしまって公開してしまった」という記事で、しかもかなり読まれてしまったことから、2020年にとりあえず公開していて問題ない状態にするために手を入れた。

だが、それでも内容があまり正しくなかったり、適切でなかったり色々あったため、修正が必要であった。 今回はSignal, Session, Wireを加え、ほぼ全面的に書き直した。 不十分であることは承知しているが、修正のための検証・執筆に80時間以上を費やしており、さすがにこれ以上はちょっと…というところ。

余談だが、1年ほど前にデザインのリニューアルはできていて、それから延々記事修正をしていたため、新しいウェブサイトのデザインは私自身は見飽きてしまった。