先日、自分の趣味を全開に作った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
サンプルコード
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 < 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アプリがたくさんの方に見てもらえたり、使ってもらえたら嬉しいです。