UnityやCSSで使える9スライス画像を自動生成するWebアプリを作った

この記事は[個人開発 #2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/private-developmen2)の11日目です。

昨日は @yuji_saito さんの　「[ファンサイトの個人開発と、片手間運用のためのRPA](https://qiita.com/yuji_saito/items/133963abfc75de8aae77)」 でした。

## 作ったもの

### [9 SLICER](https://zprodev.github.io/9-slicer/demo/)
![9slicer.gif](https://qiita-image-store.s3.amazonaws.com/0/142643/6bed0d5f-c7ad-5aa7-e9e8-a9603c0d9ba3.gif)
https://zprodev.github.io/9-slicer/demo/

ドラッグ&ドロップで9スライス画像をサクッと生成できるWebアプリです。
全てフロントのJavaScriptで処理してます。裏で画像抜いたりしてないので安心してご利用ください。

生成した画像は、Unityなら**9SliceSprite**、Webサイトなら**border-image**、
HTML5ゲーム界隈ならPixiJSで**NineSlicePlane**として使用できます。



## 9 SLICER の使い方

↓の点線内に
![スクリーンショット 2018-12-10 20.30.32.png](https://qiita-image-store.s3.amazonaws.com/0/142643/266df443-199a-b1d3-71d2-d07f50280305.png)

こんなPNG画像をドロップすると
![sample3.png](https://qiita-image-store.s3.amazonaws.com/0/142643/b30ebcd3-3c06-4fa5-97f4-e5423fd22ad1.png)


スライス後の画像が下にプリッと出てきます
![スクリーンショット 2018-12-10 20.37.06.png](https://qiita-image-store.s3.amazonaws.com/0/142643/ee65c035-512d-6ecf-b347-9c53a8b8beda.png)



スライス結果として下記情報が画像上に表示されます。

 - reducation : 削減率（スライスできない画像だと0%表示です）
 - width : 元の画像の横幅
 - height : 元の画像の高さ
 - top/bottom/left/right : 境界

スライス後の画像は「DOWNLOAD」ボタン、情報は「COPY JSON」ボタンで取得できます。
右上のボタンから一括ダウンロードもできます。

## 9スライス画像の使い方

生成された画像とスライス情報の使い方を簡単に紹介します。

### 生成された画像とスライス情報
![sample.png](https://qiita-image-store.s3.amazonaws.com/0/142643/5ab46629-8a0c-4ca1-c79b-09752892d813.png)

```json
{"width":420,"height":240,"left":46,"right":45,"top":48,"bottom":48}
```

### Unityで使う場合

スライス後の画像をプロジェクトに取り込み、Sprite Editorで `top` `bottom` `left` `right`を設定します。
![スクリーンショット 2018-12-10 20.40.24.png](https://qiita-image-store.s3.amazonaws.com/0/142643/128959ee-7da5-9214-7b89-d785bd488de3.png)

GameObject > UI > Image で作成したオブジェクトに画像をアタッチして`width` `height`を設定します。
![スクリーンショット 2018-12-10 20.41.51.png](https://qiita-image-store.s3.amazonaws.com/0/142643/42ebc1f2-b16c-d516-1a90-e6d1e948bcea.png)

これでUnity上に元画像の表示が再現できます。
![スクリーンショット 2018-12-10 20.42.09.png](https://qiita-image-store.s3.amazonaws.com/0/142643/e50de783-fc37-aba4-ddb5-1cceee365029.png)

### CSSで使う場合

CSSで`width` `height` と `top` `right` `bottom` `left` を設定します。

```css
#sampleDiv {
  width: 420px;
  height: 240px;
  box-sizing: border-box; /* width height の内側にボーダーを納める設定 */
  border-style: solid; /* 指定しないとボーダーが表示されない */
  border-image: url(sample.png) 48 45 48 46 fill / 48px 45px 48px 46px; /* 数値は top right bottom left の順で書く */
}
```

CSSを適用する要素をHTMLに書きます

```haml
<body>
  <div id="sampleDiv"></div>
</body>
```

これでブラウザ上に元画像の表示が再現できます。
![スクリーンショット 2018-12-10 21.02.02.png](https://qiita-image-store.s3.amazonaws.com/0/142643/c1eb642b-c65c-d3c2-efb2-ff776351e174.png)

### PixiJSで使う場合

NineSlicePlaneに `width` `height` と `top` `right` `bottom` `left` を設定します。

```js
import * as PIXI from 'pixi.js';

const SCREEN_WIDTH = 500;
const SCREEN_HEIGHT = 500;

const app = new PIXI.Application(SCREEN_WIDTH, SCREEN_HEIGHT);
document.body.appendChild(app.view);

/* 数値は left top right bottom の順で書く */
const nineSlice = new PIXI.mesh.NineSlicePlane(PIXI.Texture.fromImage('sample.png'), 46, 48, 45, 48);
nineSlice.width = 420;
nineSlice.height = 240;
app.stage.addChild(nineSlice);
```

これでブラウザのWebGL上に元画像の表示が再現できます。
![スクリーンショット 2018-12-10 21.21.46.png](https://qiita-image-store.s3.amazonaws.com/0/142643/5b727856-4a67-cbdd-3522-f3535ccbb079.png)

## おわりに

このWebアプリにはnpmで公開したモジュール「[9-slicer](https://www.npmjs.com/package/9-slicer)」を使用しています。

9-slicerはNode.js環境でフロントエンド開発に使用することが本来の目的でしたが、せっかくJavaScriptで書くならブラウザでも軽量に動くものにしようと。
でもこのモジュールをブラウザで使ってくれるような人はまず現れないだろうなと。
ならせめてデモとして、ブラウザで動くようにした意味を持たせようということで、Webアプリ「[9 SLICER](https://zprodev.github.io/9-slicer/demo/)」は生まれました。

ぜひ使ってやってください！