
※そもそも、MGO2
とはメタルギアオンラインというゲームです。
ソースとサイト
作成方法の参考サイト(Windows向け)
なぜ作るか
- Mac向けの参考サイトがない
- 各ツールを駆使して作れなくもないが面倒。
- →ツール作るか。webで。
なにで作るか
-
parcel
+babel
+node-scss
- parcelを使ってみたかった
実装について
やることは大きく分けて4つ
- 画像を
32*32
にリサイズ- MGOのエンブレムサイズが
32*32
- MGOのエンブレムサイズが
- 16色に減色
- MGOのエンブレムで使用できる色が16色
- 選択色ごとにハイライト表示
- 最終的にはゲーム画面でぽちぽち手打ちする必要があるため、同色がどこに使われているかわかりやすくする
- カラーコードの表示を
8.21
で割る- MGOでエンブレムを作成する際のカラーピッカーが
0〜31
のため
- MGOでエンブレムを作成する際のカラーピッカーが
画像選択
- ドラッグアンドドロップまたは、選択されたファイルを
FileReader API
で読み込み - ファイル選択は
change
、ドラッグアンドドロップはdrop
イベントでデータを取得 - 読み込んだファイルデータをcanvasに書き出し
// イベント設定
uploadArea.addEventListener('change', (e) => {
this.changeHandler(e);
});
uploadArea.addEventListener('dragenter', (e) => { e.preventDefault(); });
uploadArea.addEventListener('dragover', (e) => { e.preventDefault(); });
uploadArea.addEventListener('dragleave', (e) => { e.preventDefault(); });
uploadArea.addEventListener('drop', (e) => {
e.preventDefault();
this.changeHandler(e, e.dataTransfer.files[0]);
});
/**
* 画像アップロード時のcallback
*/
changeHandler(e, data) {
// drag and dropの場合は e.dataTransfer.files[0] を使用
let file = data === undefined ? e.target.files[0] : data;
let image = new Image();
let fileReader = new FileReader();
fileReader.onload = (e) => {
let base64 = e.target.result;
image.onload = () => {
this.canvasCropper.width = image.width;
this.canvasCropper.height = image.height;
let originalCtx = this.canvasCropper.getContext('2d');
// s:sourceImage, d:destinationCanvas
// ctx.drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh)
originalCtx.drawImage(image, 0, 0, image.width, image.height, 0, 0, image.width, image.height);
};
image.src = base64;
};
fileReader.readAsDataURL(file);
}
クロッピング
- Cropper.jsを使用
- エンブレムは正方形なので
aspectRatio
は1
に指定 - crop時のイベント引数からクロップ時のサイズ・位置が取得できるので
crop範囲だけ別の32*32
サイズのcanvasに描画
this.cropper = new Cropper(canvas, {
aspectRatio: 1,
preview: '.cropper-preview__img',
crop: (e) => {
ctx.drawImage(canvas,
e.detail.x,
e.detail.y,
e.detail.width,
e.detail.height,
0,
0,
CANVAS_SIZE,
CANVAS_SIZE
);
}
});
メディアンカット(中央値分割法)による減色
node-kmeans
を使用-
mediancut
を使用 - クロッピング時に作成した
32*32
サイズのcanvasのピクセルデータを取得して減色を行う
let imagedata = ctx.getImageData(0, 0, CANVAS_SIZE, CANVAS_SIZE);
// reduced color (減色)
let medianCut = new MedianCut(imagedata);
medianCut.run(16);
減色後の表示
- クラスタリング後のデータで16色に減色されたカラーコードを取得して、canvasに描画して終わり
最後に
- MGO2全盛期の7〜8年前に作れていれば。。。
- TODOもたくさん。。。