HTML+CSSだけでMinecraftのスキンから頭だけを切り出して表示する方法

HTML+CSSだけでMinecraftのスキンから頭だけを切り出して表示する方法

1, スキンを取得

スキンを取得するのは一見難しそうだが、実は、

http://skins.minecraft.net/MinecraftSkins/<プレイヤー名>.png

にアクセスするだけでスキンが取得できる。

ユーザー名がyuta0801なら、こうなる。

http://skins.minecraft.net/MinecraftSkins/yuta0801.png

スキン

これで上のようなスキンが取得できる。

2, 拡大

CSSでwidthheightを変更するだけだと、下のようにぼやけてしまう。

拡大したスキン

実はブラウザの画像レンダリングエンジンが少しでも自然に見えるようにエッジをぼやかしているのが原因。

これだけはどうすることもできないと思っていたのだが、先日、image-renderingというプロパティを見つけることができた。

このプロパティで画像のレンダリング方法を指定してエッジをぼやけさせなくすることができる。

現在のところ、このプロパティはCSSで正式に採用されたものではないので、ブラウザによって値が違う。

Can I useを見るとEdge以外の主要ブラウザは使える。

Edgeなのに、きれいなEdgeを表せない。

以下のコードを適応させると、IE、Firefox、Chrome、Safariで綺麗に表示できる。

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

image-renderingを適応したスキン

上のスタイルを適応させるとこうなる。

4, 切り抜き

画像の切り抜きはCSSのclipを使用して

.clipped {
  position: absolute;
  clip: rect(   );
}

のように書くことができます。

拡大する前のスキンの頭の位置は、

スキンの頭の位置

左上から8px, 8pxからの8pxの正方形なので、拡大前は、

.clipped {
  position: absolute;
  clip: rect(8px 16px 16px 8px);
}

と書ける。あとはそれぞれの値に拡大倍率を掛けるだけ。

スキンの大きさは、64 x 32 (1.8以降は 64 x 64) なのでwidth: 512;を指定した場合は

512 / 64 = 8なのでそれぞれの値に8を掛けて、以下のようになる。

.clipped {
  position: absolute;
  clip: rect(64px 128px 128px 64px);
}

ここまででこのような頭が切り出せた。

切り出した頭

5, 空白を取り除く

4まででスキンを取得し拡大して頭をくり抜けたのだが、実は頭以外の部分を消したわけではなく見えなくしただけなので、元の画像の大きさの空白ができてしまう。

そこで、マイナスの余白を付けて余分な空白を打ち消す。

先程の例の場合だと、頭の縦横をそれぞれマイナスのマージンとして与える。

.clipped {
  position: absolute;
  clip: rect(64px 128px 128px 64px);
  margin-left: -128px;
  margin-top: -64px;
}

これで、左上の位置が揃うが、右下はまだ残っているので、一つ上の要素に頭の大きさを指定する。

.box {
  height: 64px;
  width: 64px;
}

まとめ

ここまで書いたことを踏まえて実際に256pxの頭を表示するソースを書いてみる。

<span class="box">
  <img src="http://skins.minecraft.net/MinecraftSkins/yuta0801.png">
</span>
.box {
   display: inline-block;
   position: relative;
   width: 64px;
   height: 64px;
}
.box img {
  width: 512px;
  image-rendering: pixelated;
  image-rendering: -webkit-crisp-edges;
  image-rendering: -moz-crisp-edges;
  -ms-interpolation-mode: nearest-neighbor;
  position: absolute;
  clip: rect(64px 128px 128px 64px);
  margin-left: -64px;
  margin-top: -64px;
}

参考記事

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.