JavaScript

I created a web application called “Pokémon Palette” that allows you to generate Pokémon-themed color icons

I recently launched a web app that fully reflects my personal hobby — Pokémon Palette.

I’ve loved Pokémon since childhood, whether watching the anime or playing the games. I also enjoy Pokémon illustrations, so I thought it would be fun to combine that love with my web coding skills to create something unique. The result is this web app.

How This Web App Works

The framework is primarily built with Vue.
Here’s the overall flow of how the app works:

  1. Prepare images to extract colors from
  2. Use JavaScript libraries to obtain colors from the images
  3. Render extracted colors into icon-style designs
  4. Allow color changes by clicking icons
  5. Enable icon downloads

 

Preparing Images for Color Extraction

First, let me introduce the package that manages the essential Pokémon data used for color extraction.

Among the many competing options in the Pokémon data space, the one I found most reliable is this:
GitHub – fanzeyi/Pokemon-DB: A Pokémon database in JSON format.

It provides JSON data for:

  • Pokémon
  • Items
  • Moves
  • Types

This package also included the Pokémon images I wanted to use for this app.
Here’s an example with Lucario:

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

 

Extracting Colors from Images with JavaScript Libraries

Since I wanted to dynamically extract colors from images and render them as icons, I used a few JavaScript libraries specialized for this.

I tried more than four, but the results often overlapped. So, I narrowed it down to three:

Vibrant.js

Official Site

サンプルコード

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

Official Site

サンプルコード

//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);
  }
});

 

Rendering Extracted Colors into Icons

The concept was to create Pokémon-themed color icons.
Each icon is composed of 1 main color + 3 sub-colors, derived from the image.

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

 

The process works like this:

  • Colors extracted via JS libraries are stored in iconColors
  • Vue dynamically binds these colors to the icon background (v-bind:style)

 

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: []
    }
});

 

Changing Colors by Clicking Icons

Since there are many colors available but only four displayed in the icon, I added the ability to switch colors by clicking.

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

 

How it works:

  • All extracted colors are stored in paletteColors
  • Clicking an icon triggers a Vue method (v-on:click="changeColor")
  • The method cycles through available colors and updates the icon display

 

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];
            }
        }
    }
}

 

 

Downloading Icons

Finally, I wanted users to be able to download the icons they created.

How it works:

  • Clicking the download button triggers jQuery event handling
  • The app renders the icon area into a canvas using html2canvas
  • The canvas is converted into a downloadable PNG file

 

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);
    });

});

 

 

Conclusion

This project required lots of trial and error:

  • Extracting colors that didn’t always match expectations
  • Displaying palettes and icons
  • Implementing click/tap-based color switching
  • Adding download functionality

Although there are still challenges like slow loading and incomplete color extraction, the process was rewarding because it’s based on something I love.

I’d be happy if many people could see and use this web app.