koba::blog

小林聡: プログラマです

CSS3で加槓を表現する

麻雀に加槓という行為がある。すでにポンした面子と同じ牌をツモってきた場合、ポンをカンにアップグレードすることができるわけだが、晒すときにはポンとしてすでに横向けにした牌に重ねるように牌を置く。この形をCSS3の transform を使って表現してみた。

transform の rotate() を使えば画像でも文字でも自由に回転させることができるのだが、加槓の表現のポイントは2つの牌をグループ化して回転させること。

まず、HTMLでの表現だが、これは以下のようにシンプルにしておく。*1

<div class="fulou">

<!-- 上家からのポンに加槓 -->
<span class="mianzi">
<span class="rotate">
  <img src="pai.png">
  <img src="pai.png">
</span>
<img src="pai.png">
<img src="pai.png">
</span>

<!-- 対面からのポンに加槓 -->
<span class="mianzi">
<img src="pai.png">
<span class="rotate">
  <img src="pai.png">
  <img src="pai.png">
</span>
<img src="pai.png">
</span>

<!-- 下家からのポンに加槓 -->
<span class="mianzi">
<img src="pai.png">
<img src="pai.png">
<span class="rotate">
  <img src="pai.png">
  <img src="pai.png">
</span>
</span>

</div>

副露牌を置くエリアは fulou、各面子は mianzi、回転させる牌は rotate で指定してある。*2

これを以下のCSSで回転させる。

.fulou img { height: 64px; }    /* 牌の高さをそろえる */
.fulou {
    margin-top: 64px;           /* 表示エリアは牌の高さの2倍に */
    text-align: right;          /* 副露牌なので右側に表示 */
}
.fulou .mianzi {
    padding-left: 10px;         /* 面子間には少し隙間を空ける */
}
.fulou .mianzi .rotate {
    display: inline-block;      /* 幅が指定できるよう inline-block にする */
    width: 64px;                /* 幅を牌の高さに合わせる */
    white-space: nowrap;        /* 回転エリア内では改行しない */
    text-align: left;           /* 回転エリア内では左寄せ */
    transform-origin: 0% 0%;    /* 左上を起点とする */
    transform: rotate(270deg) translate(-64px, 0px);
                                /* まず反時計回りに90度回転、
                                   それから「左」に牌の高さ分移動 */
    
    /* 以下はWebkit系ブラウザ(Safari, Chrome)用 */
    -webkit-transform-origin: 0% 0%;
    -webkit-transform: rotate(270deg) translate(-64px, 0px);
}

回転させた後、画面上では下に移動させたいのだが、translate の座標軸は回転前が基準のなので要注意。まあ最後に回転させた方が分かりやすいかもしれません。

出来上がりはこんな感じ。

これをさらに応用してグループ化する範囲を大きくすれば、こんな表現もできる。

*1:無用な隙間が発生しないよう、実際は各面子は1行で空白を入れずに記述した方がよい

*2:名称は中国語のピンイン表記にしてみた