DockerでrbenvによるRubyのインストールが失敗する話

Dockerで立ち上げたコンテナでrbenvによるRubyのインストールが失敗することがあり、その原因を調べた。

概要

以下のように、インストール以前にソースのダウンロードに失敗していた。

$ rbenv install 2.3.0
Downloading ruby-2.3.0.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.0.tar.bz2
error: failed to download ruby-2.3.0.tar.bz2
...

試しにcurlでアクセスしてみたところ、以下のように証明書関係でエラーが出た。

$ curl https://cache.ruby-lang.org
curl: (60) SSL certificate problem: certificate is not yet valid
More details here: http://curl.haxx.se/docs/sslcerts.html

curl performs SSL certificate verification by default, using a "bundle"
 of Certificate Authority (CA) public keys (CA certs). If the default
 bundle file isn't adequate, you can specify an alternate file
 using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
 the bundle, the certificate verification probably failed due to a
 problem with the certificate (it might be expired, or the name might
 not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
 the -k (or --insecure) option.
$ 

原因

エラーの原因は、コンテナ内の時刻がずれていたことだった。
ntpdでも入れればよいのかと思ったが、Dockerの場合そもそもホスト側の時刻に合わせてコンテナが起動していたような気がしたので、ホスト側の時刻を合わせることにした。

Docker for Macを用いていたため、単純に再起動することでコンテナ内の時刻も正常に戻った。
どうやらDocker for Macは起動させたままにしておくと、少しずつ時刻がずれていくようだった。

まとめ

Docker for Macは定期的に再起動したほうが良さそう

ドロップダウンメニュー用のライブラリ smart-dropdown-menu を作った

ドロップダウンメニュー用のライブラリ smart-dropdown-menu を作成しました。

github.com

smart-dropdown-menu は、<script> タグでの読み込みと npm での管理の両方に対応しています。 どのように両対応したかの詳細については、以下の Qiita 記事を御覧ください。

qiita.com

smart-dropdown-menu

smart-dropdown-menu は以下の gif のように、サブメニューへの移動時にマウスカーソルの斜め移動を考慮したホバー判定を行う機能を持ったドロップダウンメニューを作成します(解説のため色がついています)。

smart-dropdown-menu demo

同様の機能を持つライブラリに jQuery-menu-aim がありますが、smart-dropdown-menu は mousemove イベントを用いずにホバー判定を行っている点が特徴です。

smart-dropdown-menu は以下のような html を記述することで生成します。

<nav class="smart-dropdown-menu">
  <div class="smart-dropdown-menu-button">
    <span></span>
  </div>
  <ul class="sdm-list">
    <li>
      <a href="#">menu01</a>
      <ul class="sdm-list">
        <li><a href="#">submenu1_1</a></li>
        <li><a href="#">submenu1_2</a></li>
        <li><a href="#">submenu1_3</a></li>
      </ul>
    </li>
    <li>
      <a href="#">menu02</a>
      <ul class="sdm-list">
        <li><a href="#">submenu2_1</a></li>
        <li><a href="#">submenu2_2</a></li>
        <li><a href="#">submenu2_3</a></li>
      </ul>
    </li>
  </ul>
</nav>

ホバー判定の仕組み

先程の gif で表示されていた部分は、三角形の上半分をサブメニューの li:before で生成し、下半分を li:after で生成しています。
li:before, li:after の疑似要素にマウスカーソルが乗った場合、<li> タグの hover となるため、斜め移動用の判定領域として利用できる仕組みとなっています。

三角形の作り方

DOM 要素は通常 width と height をもとに四角形の領域が確保されます。 smart-dropdown-menu は skewX を用いて DOM 要素を平行四辺形に変形しています。

li:before {
  transform: skewX(-31deg);
}
li:after {
  transform: skewX(14deg);
}

メニューの初期化時にサブメニューの高さをもとに li:before 用の仰角li:after 用の俯角を計算し、skewX による変形で作成した2つの平行四辺形を組み合わせることで、以下のように三角形のホバー判定領域を生成しています。

f:id:yami_beta:20161126021903g:plain

まとめ

li:before, li:after を skewX で変形することで、mousemove を用いずにカーソルの斜め移動を考慮したホバー判定を実現したライブラリ smart-dropdown-menu の紹介でした。