CODE

ポケモンカラーのアイコンを作成できるWebアプリ『ポケモンパレット』を作りました

先日、自分の趣味を全開に作ったWebアプリを公開しました。
ポケモンパレット

ポケモンは昔から好きでアニメを見たりゲームで遊んだりしてるのですが、ポケモンのイラストも好きで、イラストとWebコーディングスキルを組み合わせて何か作れないかなーと思って作ったWebアプリです。

 

このWebアプリの仕組み

大枠をVueで組んでます。

仕組みで意識した部分は大まかに下記の通りです。

  • 色を取得するための画像を準備
  • javascriptライブラリで画像から色を取得する
  • 取得した色をアイコン風に描画
  • アイコンをクリックするとカラー変更できる
  • アイコンがダウンロードできる

 

色を取得するための画像を準備

まずは色抽出の要となるポケモンデータを管理してくれているパッケージを紹介します。

ポケモンのデータ関連の分野は競合がたくさんあるのですが、ぼくが見つけた中で一番良さそうだったのがこちらです。
GitHub – fanzeyi/Pokemon-DB: A Pokemon database in JSON format.

次のそれぞれの要素に対してのJSONがあります。

  • ポケモン
  • アイテム
  • ワザ
  • タイプ

 

今回のWebアプリで使いたい画像も取り揃えてくれていたので、このパッケージを選びました。
ルカリオの画像だとこんな感じです。

ポケモンパレット ルカリオ

 

javascriptライブラリで画像から色を取得する

動的に画像の色を取得して、アイコンに描画するような処理を使いたかったので、画像の色を取得するjavascriptライブラリを使いました。

画像の色を取得するjsライブラリはいくつかあるのですが、4つ以上使用しても取得する色に被りが出てきたので、今回は3つにしました。

今回使用したライブラリは下記の3つです。

Vibrant.js

公式サイト

サンプルコード

var img = document.createElement('img');
img.setAttribute('src', 'examples/octocat.png')

img.addEventListener('load', function() {
    var vibrant = new Vibrant(img);
    var swatches = vibrant.swatches()
    for (var swatch in swatches)
        if (swatches.hasOwnProperty(swatch) && swatches[swatch])
            console.log(swatch, swatches[swatch].getHex())

    /*
    swatches内に配列で以下のような値が返ります。
    Vibrantが特徴的な色でMutedが多く使わている色…でしょうか?
     * Results into:
     * Vibrant #7a4426
     * Muted #7b9eae
     * DarkVibrant #348945
     * DarkMuted #141414
     * LightVibrant #f3ccb4
     */
});

 

color-thief.js

公式サイト

サンプルコード

//colorはr,g,bそれぞれが配列として入ります。
var colorThief = new ColorThief();
var img = document.querySelector('#colorthief img');
var color = colorThief.getColor(img);
console.log(color);

 

rgbaster.js

Github

サンプルコード

var img = document.getElementById('image');
 
/*
    payload.dominant:メインカラー
    payload.secondary:サブカラー
    payload.palette:よく使われる色10色が入ります。
*/
RGBaster.colors(img, {
  success: function(payload) {
    // You now have the payload.
    console.log(payload.dominant);
    console.log(payload.secondary);
    console.log(payload.palette);
  }
});

 

取得した色をアイコン風に描画

今回作りたかったWebアプリは、ポケモンのイメージカラーをアイコンにしたかったので、メインカラー1色とサブカラー3色で構成されるアイコンにしました。

ポケモンパレット ニンフィア

 

解説

  • javascriptライブラリで、画像から取得したメインカラーとサブカラーの4色をiconColorsに格納
  • HTML側「v-bind:style=”{backgroundColor: iconColors.color0}”」で、iconColorsに格納された色を表示

 

HTML

<div class="result2" id="html-content-holder">
	<div id="iconimg" class="maincolor" v-show="img" v-bind:style="{backgroundColor: iconColors.color0}" v-on:click="changeColor">
	</div>
	<div class="subcolor">
		<div class="color1" v-show="img" v-bind:style="{backgroundColor: iconColors.color1}" v-on:click="changeColor1"></div>
		<div class="color2" v-show="img" v-bind:style="{backgroundColor: iconColors.color2}" v-on:click="changeColor2"></div>
		<div class="color3" v-show="img" v-bind:style="{backgroundColor: iconColors.color3}" v-on:click="changeColor3"></div>
	</div>
</div>

 

javascript

var input = new Vue({
    el: '#input',
    data: {
        img: '',
        iconColors: {
            color0: '',
            color1: '',
            color2: '',
            color3: '',
        },
        paletteColors: []
    }
});

 

アイコンをクリックするとカラー変更できる

アイコンに使用する色が4色に対して、取得できる色がたくさんあるので、好きな色に変更できるようにしました。

ポケモンパレット カプ・テテフ  ポケモンパレット カプ・テテフ

 

解説

  • javascriptライブラリで、画像から取得した全色をpaletteColorsに格納
  • アイコンをクリックすると「v-on:click=”changeColor”」が発火
  • paletteColorsに格納された色を順番にズラして、アイコンに表示する

 

HTML

<div id="iconimg" class="maincolor" v-show="img" v-bind:style="{backgroundColor: iconColors.color0}" v-on:click="changeColor">

 

javascript 1

var input = new Vue({
    el: '#input',
    data: {
        img: '',
        iconColors: {
            color0: '',
            color1: '',
            color2: '',
            color3: '',
        },
        paletteColors: []
    }
});

 

javascript 2

changeColor: function() {
    var vm = this;
    var colors = vm.paletteColors;
    var nowcolor = vm.iconColors.color0;
    for (let i = 0; i &lt; colors.length; i++) {
        if (colors[i] == nowcolor) {
            if (i == colors.length-1) {
                vm.iconColors.color0 = colors[0];
            } else {
                vm.iconColors.color0 = colors[i+1];
            }
        }
    }
}

 

 

アイコンがダウンロードできる

作成したアイコンを使用したいので、ダウンロードできるようにしました。

解説

  • ダウンロードボタンを押すと、「$(“#btn-Preview-Image”).on(‘click’, function () { });」が発火
  • HTMLのアイコン部分をcanvasを使って描画処理(cssで非表示に)
  • canvas上に描画したデータをダウンロードする

 

HTML

<div class="downloadBtn">
	<a href="#" id="btn-Preview-Image" class="circle_spread_btn">アイコンダウンロード</a>
	<a href="#" id="btn-Convert-Html2Image"></a>
	<div id="previewImage"></div>
</div>

 

javascript

// 指定したidを画像にしてダウンロード
$(document).ready(function(){
    var element = $("#html-content-holder"); // global variable
    var getCanvas; // global variable
 
    $("#btn-Preview-Image").on('click', function () {
        html2canvas(element, {
            onrendered: function (canvas) {
                $("#previewImage").append(canvas);
                getCanvas = canvas;
                $("#btn-Convert-Html2Image")[0].click();
            }
        });
    });

    $("#btn-Convert-Html2Image").on('click', function () {
        var imgageData = getCanvas.toDataURL("image/png");
        // Now browser starts downloading it instead of just showing it
        var newData = imgageData.replace(/^data:image\/png/, "data:application/octet-stream");
        $("#btn-Convert-Html2Image").attr("download", "icon.png").attr("href", newData);
    });

});

 

 

まとめ

イメージ通りの色が取得できなかったり、アイコンやパレット一覧を表示したり、クリック・タップで色を変更できるようにしたり、ダウンロードできるようにしたり。

あれこれ試行錯誤をしたりと本当にいろいろ細かい調整が大変だったのですが、好きなものだと頑張れるものですね。

とはいえ、読み込みが遅かったり、全色取得できていなかったりとまだまだ課題だらけですが。

このWebアプリがたくさんの方に見てもらえたり、使ってもらえたら嬉しいです。

 

ABOUT ME
りん
フロントエンドエンジニア / 趣味ブログ / 沖縄から東京に就職1年SE→ 1年フリーランスSE→ 沖縄移住2年Webデザイナー → 福岡移住1年目フロントエンドエンジニア / HTMLCSS大好物 / JS / PHP / Laravel / WordPress / VScodeでVim使う人