ドット絵投稿Webサービス「あいこんくらぶ」「ぴこぴよ」

この記事は、ドット絵 Advent Calendar 2017 12/15の参加記事です。

きょうは、ドット絵関連ツールを開発している作者が、自分のつくったツールについてお話ししようかなと思っています。 (みなさん読み応えのある記事を投稿されているので、ちょいと緊張しています。。。)

はじめに

わたしは、ドット絵を投稿・公開したり、じぶんのドット絵リストをつくれるウェブサービスあいこんくらぶ」と、ドット絵をツイッターにきれいに投稿できる「ぴこぴよ」を開発、公開しています。これらのツールのよいところや、ざっくりとした使い方についてご紹介します。

ちなみに、筆者のドット絵スキルは、「なんとなく描いている」程度な感じです(下手の横好きというやつです)。私もAdvent Calendarの記事を参考にして、もっとうまく書けるようになりたいなーと思ったりしています。

ドット絵は限られた画素数で表現するという性質から、程よく制約があるおかげでとっつきやすく、そこに魅力を感じています。 そんな私がこれからのドット絵ライフを快適にすべく作ったのが以下のツールたちです。私のツールでみなさんのドット絵ライフが潤ったり、あたらしくドット絵に興味を持つ方々が増えればいいなぁ。

ドット絵ツイート支援サービス「ぴこぴよ」

これはなに?

ドット絵をツイッターに投稿されている方々は多いと思いますが、次のようなことを気にかけている方々は多いのではないでしょうか。

  • ドット絵がぼやけて投稿されてしまわないように加工する
  • ドット絵を拡大して、ドットがはっきりとわかるように投稿する

Twitterは画像を jpeg 保存する仕様になっているようで、この結果、投稿したドット絵のドットの境界がぼやけたり、色が意図しないものになったりすることがあります。 また、投稿画像が小さいと、閲覧する端末によってはぼやけて見えてしまうこともあります。 これらを考慮し、ツイッターへドット絵をきれいに投稿しやすくするツールが「ぴこぴよ」です。

ぴこぴよをつかうと、以下のようなことができます。

  • 原寸大のドット絵が1枚あれば、ドット絵を拡大して投稿できる
  • 画像に透過画素を仕込むことで、Twitterにきれいに投稿できる

f:id:piyorinpa:20171210195701p:plain
拡大率を調整したり、原寸大のドット絵を並べられます

jpegは透明色を扱えないので、透明色付き画像はpngで保存される」という性質を利用し、png画像としてTwitterに扱ってもらうことで、きれいなまま投稿することができます。 また、「拡大機能」によって、わざわざドット絵を公開するときに拡大画像を用意する必要がありません。 そのほかに、「原寸大ドット絵と並べて表示する機能」があり、原寸大のドット絵の魅力も同時に伝えることができます。

つかいかた

トップページの「ツイートする」を押して、ツイート画面に行きます。あとは画像をドラッグアンドドロップで追加し、お好みのサイズに調整します。

背景色を付けることもできます。ドット絵(に限らずだと思いますが)は大別して、画像に背景等を含む「一枚絵パターン」と、単一のもののみが描かれている「キャラクター・素材パターン」があると思いますが、後者の場合は背景色を付けてあげることで、よりじぶんのイメージに合った画像を投稿できると思います。

どうでもいいですが、「ぴこぴよ」という名前は「ぴこぴこしている絵(ドット絵)」を「ツイート(ぴよぴよ※1)する」という意味で名づけました。へー、と思っていただければうれしいです。

ぴこぴよで背景色と拡大率を設定する

(※1: ツイートはさえずるの意から)

ドット絵投稿・公開サービス「あいこんくらぶ」

これはなに?

あいこんくらぶはドット絵を投稿して公開できるサービスです。機能の一部を上げてみるとこんな感じ。

  • お手持ちのドット絵をアップロードして公開できます(おおきさ256px四方まで)
  • 原寸大のドット絵さえあれば、拡大はあとから行うことができます(関連記事
  • 公開したドット絵はツイートすることもできます
  • ドット絵エディタ(PC/スマートフォン対応)で絵が描けます
  • 公開されたドット絵は、パレット情報をみることができたり、自由に拡大率を変更して閲覧することができます
  • じぶんの作品リスト「マイページ」を公開することもできます(関連記事
  • ライセンス付きドット絵や、利用規約付きドット絵を配布することができます(関連記事

などなど。。。なんだかいろいろ機能があって、どのように使ったらいいのかわからない方々もいらっしゃるかもなぁ、と、最近思ったりしています。なので、今回はユースケースをいくつか考えてみました。

お手持ちのドット絵を投稿・公開するとき

(あいこんくらぶにはモバイル版もありますが、ドット絵のアップロードはPC版のほうが行いやすいので、今回はPC版のみの説明とさせていただきます)

あいこんくらぶは「ドット絵投稿・公開サービス」なので、みなさんにどんどん投稿して頂きたいぞ!ということで、まずは投稿方法から。

まずは会員登録 をします。おわったらトップページから「じぶんの作品の管理」ページに行くと、投稿画面が現れます。 あとはドラッグアンドドロップでひょいひょいと画像を追加していきます。

じぶんの作品の管理ページで画像を追加します

つぎに公開設定をします。あいこんくらぶでは、アップロード直後の作品は非公開状態となっており、公開設定を行うことではじめて公開されます。 いくつかの公開範囲を設定でき、たとえば「トップページには表示しない」「あいこんくらぶのタグ検索の結果には表示しないようにする」などの項目を設定できます。 公開範囲について、くわしくはヘルプをご覧ください。

作品の公開設定

ドット絵の表示拡大率を変更することもできます(拡大率の変更を行っても、元のドット絵ファイルには影響しないので安心して変更してください)。背景画像や背景色、サムネイルの見た目なども変更可能なので、いろいろと調整してみてください。

見た目はこんな感じに変えることができます

ツイッターに投稿するには、「じぶんの作品の管理」ページでドット絵を選択して右クリックし、「ツイートする」を押します。ぴこぴよと同様のシステムで投稿することができます。

ぴこぴよみたいにツイートもできます

余談ですが、「ぴこぴよ」は「あいこんくらぶ」に実装したツイートシステムを切り出してつくっています。 (ツールの作者的には、あいこんくらぶで投稿しつつ、ツイート機能でツイッターに投稿していただけるとうれしいなぁ、と思っています。)

また、じぶんの作品をリスト表示する「マイページ」機能があります。(ちなみに筆者のマイページはこちら) 公開済みの作品は自動的にマイページに表示されます。ページのヘッダ画像や背景画像は差し替えられるので、いい感じにしてみると良いです。

ちなみに、マイページのURLはhttps://iconclub.jp/user/ユーザー名 となっているので、各種ブログやSNSでリンクをシェアするのに便利です。

(PC版とモバイル版では見え方が異なるので、どちらもお持ちの場合は両方で確認してみるといいかもです。)

ドット絵を描いてみたい方

あいこんくらぶには簡易なドット絵エディタがあります。こんなかんじ。

エディタのようす

「ドット絵を試しに始めてみたいなぁ」とか「外でもスマートフォンでお絵かきしたいな」という方におすすめです。 (すでに使い慣れたエディタをお持ちの方だと、ちょっと物足りなさを感じるかもですが、ささっと描いて公開したいときなどには使えるかも。)

描いたドット絵は「じぶんの作品の管理(要ログイン)」ページに保存されます。保存しただけでは公開されないので、気の向くままに描いて、気に入ったものだけを公開することもできます。 (もちろんPC・モバイル版共にツイートすることもできます)

ざっくり紹介すると、こんな感じのことができます。

  • マウスや指(モバイル版)でお絵かきできます。
  • 256px四方のサイズまで、いつでもキャンバスをリサイズできます
  • 矩形、線分、円、切り取り、コピー、アンドゥなどの基本的な機能を有しています
  • パレットを作って保存でき、PC・モバイル機のどちらでも読み込めます。
  • PC版、モバイル版があり、それぞれのデバイスに合わせてつくっています

私はPCでドット絵を打つときはEdgeかGraphics Galeを愛用していますが、 モバイル版あいこんくらぶのドット絵エディタは、わたしも外出先でお絵かきするのによく使っています。比較的いろいろな機能があるので、ぜひつかってみてください。

モバイル版エディタの使い勝手は下の動画みたいな感じです。(だいぶ前に作った動画なので、画面の構成が一部違ったりしています。パレット周りはもうちょっと使いやすくなっていたりとか。。。)

ドット絵を閲覧したいかた

PCもしくはスマートフォンあいこんくらぶにアクセスしてください。(スマートフォン版の場合はログインが必要です。ごめんなさい)

PC版の場合は「検索ページ」、モバイル版の場合は「ログイン後のページ(要ログイン)」から、「ランダム表示」ボタンを押すと、投稿されたドット絵をランダムに表示できます。

作品をクリックするとドット絵ビューアが開きます。拡大率を変更してみたり、パレットを表示してみたり(PC版のみ)、原寸大の大きさを確認することができます。 ビューア内の「このひとの作品をみる(PC版)」もしくは「マイページ(モバイル版)」ボタンを押すと、作者のマイページにジャンプでき、ほかの投稿も閲覧できます。

拡大縮小やパレット表示、原寸時の寸法を見ることができます

さいごに

あいこんくらぶやぴこぴよには、ほかにもいろいろな機能があります。ぜひ実際に触ってみてくれるとうれしいです!

また、投稿系のウェブサイトで投稿する側になることは、わたしもあまり得意ではないのですが、ぜひお気軽にあいこんくらぶに投稿してみていただけるとうれしいです。

不具合報告や機能要望、感想などは、わたしのTwitterもしくは連絡フォームより、お気軽にどうぞ!

ではでは。

あいこんくらぶのおへや機能のレンダリング修正

最近さむくて日中のやる気スイッチが上がらないな。。。

あいこんくらぶには、ドット絵を自由に並べて&拡大してページがつくれるおへや機能というものがありますが、おへや機能をMacOSSierra)+Chromeで閲覧すると、画面が猛烈にちらつくという現象を確認しました。(スクショ取っておけばよかったな。。。)

f:id:piyorinpa:20171210020908g:plain
おへや機能はこんなかんじにドット絵を並べてページがつくれます

わたしの自宅にはMac機が無いので、気づくのが遅くなってしまってかなしみなのですが、ひとまず修正できたと思います。

修正内容としては、以下のことを行いました。

  • 余計なDOM要素を display: none することでレンダリングされないようにした
  • transform スタイルが過剰に当たっていた部分を修正した

自宅に環境がないと、おおよその目星をつけてとりあえず修正を行ってみて、Macが使える環境(おしごと環境とか)で検証しなければならないのでかなり面倒です。検証機としてMac欲しいけど、先立つもの的にちと厳しそうなので、特にMac機をお持ちの方、不具合などございましたら報告をいただけるととっても嬉しかったりします。

そうそう、わたしはAndroid機を愛用しているので、モバイル版あいこんくらぶにおいては、iOSまわりでの動作検証が不足しがちです。(古いiPod Touchは持っていますが、そろそろ限界が近づいていてつらみがあります)こちらもあわせて不具合などあれば Twitterあてにでもどうぞ。 (ただし、検証機が手元にないので不具合直せるかどうかはわかりませんが。。。)

ではでは!

JavaScriptで絞り込み検索の実装

大量のタグやキーワードの中から検索をかけるとき、最近はテキストに入力しながらリアルタイムで検索してくれる機能をよく見ますね。 私の趣味プログラミングでも、「めもりあん」のタグ検索機能でこのような処理を実装しています。

(こんなかんじ)

f:id:piyorinpa:20171203234600g:plain

単純に配列の値を入力値で検索させると、最悪、配列の要素数分の処理が必要になりそうです。リアルタイム入力の場合、刻々とテキストボックスの内容が変化するので、ちょっとしんどそうです。 そこで、連想配列を用いて検索させるようにしてみました。

(詳しい実装はソースコードを見てみてください)

(動作のサンプルはこちらから)

たとえば、「ひよこ」「ひよこまめ」「あひる」「ひもの」の4つの要素に対してリアルタイム検索しようとしたときに、以下のようにキー値を定めて辞書を作ります。

var indexes={};
indexes["あ"] = ["あひる"];
indexes["ひ"] = ["ひよこ", "ひよこまめ", "ひもの"];
indexes["ひよ"] = ["ひよこ", "ひよこまめ"];
indexes["ひよこ"] = ["ひよこ", "ひよこまめ"];
indexes["ひよこま"] = ["ひよこまめ"];

これなら、入力値が「ひ」のときは、indexes["ひ"]の中身をすべて拾ってあげればよいので、配列を全探索しなくてもよさそうです。

しかし、実際に検索したいアイテムはこんな感じのデータ構造だったりします。

var listData = [
    {data: { name: "ひよこ" } },
    {data: { name: "ひよこまめ" } },
    {data: { name: "あひる" } },
];

listData内のdata.nameに検索対象が存在しており、リアルタイム検索することで最終的にはlistDataの要素を取り出したいのです。

このようなデータ構造に加えて、先ほど説明した「辞書を作って検索する方針」に基づき処理を実装してみます。

(以下の解説を読んでいただく前に、ソースコードの全体を眺めたほうがいいかもです)

まずは、辞書作りから。

export default class arraySearcher{
    constructor(maxHashLength = 1){
        this._index = {};   //辞書データ
        this._arr = {};       //検索対象データ
        this._relation = null;   //(後で説明します)
        this.maxHashLength = maxHashLength;   // 辞書文字列の最大長さ
    }

こんな感じ宣言をします。今回の場合、検索対象データとはlistData.data.name のことです。

また、辞書データのキー値の最大長さを設定できるようにすることで、辞書データが大きくなりすぎないようにします。 (たとえば、maxHashLength=2のときに"かいだん" を登録すると、_index["か"] _index["かい"] が生成されるようにします)

つづいて、辞書を登録する処理をば。

setHash(objArray, valueKeys){
    this._relation = {};
    this._index = {};
    this._arr = [];
    objArray.forEach( item => {
        let value = item;
        valueKeys.forEach( valueKey => { value = value[valueKey] });
        this._relation[value] = { item: item, value: value };
        this._arr.push(value);
    });
    this._makeHash();
}

このようにすることで、たとえばsetHash(listData, ["data", "name"]); としてあげれば、_arr にはobjArrayからnameの値を取り出した配列["ひよこ", "ひよこまめ", "あひる"]が得られます。

また、_relationobjArrayの要素(つまりlistDataの要素)とnameの値の関連性を記述することで、あとで検索結果からlistDataの要素を返せるようにしておきます。 (このとき、_relationのキー値を検索対象値(nameの値)とすることがポイントになります)

_makeHash(){
    this._arr.forEach( item => {
        for( var i=1; i<=this.maxHashLength; i++){
            let hashstr = item.substr(0, i);            //文字を切り出す
            if( hashstr === "" ) break;                 //文字が空なら処理を終了
            if( this._index[hashstr] ){                 //既に辞書のキーが存在する場合は追加
                this._index[hashstr].push(item);
            }
            else{                                       //まだキーが存在しなければ登録
                this._index[hashstr] = [item];
            }
        }
    });
}

つぎに、上記の処理を実行することで、_indexに辞書データを作ります。これで先ほど説明した方針で、検索ができるようになりました。

_getObj(arrItems){
    if( !arrItems ) return [];
    return arrItems.map( arrItem => this._relation[arrItem] );
}

search(keyword){
    let results = [];
    if( keyword.length <= this.maxHashLength ){
        results = this._getObj(this._index[keyword]);
    }
    else{
        let keywordHash = keyword.substr(0, this.maxHashLength);
        let objs = this._getObj(this._index[keywordHash]);
         objs.forEach( obj => {
            if( obj.value.includes(keyword) ) results.push(obj)
        } );
    }
    return this._relation ? results.map( obj => obj.item ) : results;
}

var result = searcher.search('検索文字列');とすることで検索します。もし検索文字列の長さが辞書の最大キー値よりも小さければ、単に辞書リストを返せばよいので簡単です。

そうでない場合は、最もよく一致する辞書内のアイテムから、さらにString.includes()を使って絞り込みます。検索文字列が文字が含まれていれば検索結果として返すようにします。

ここで、さきほどの_relation の情報を使い、検索結果にヒットする name を持つdataを返すことができます。

こんな感じで実装してみて、いまのところは困っていませんが、大量のデータを用いて検索速度を検証したりしていないので、もしかしたら粗があるかもです。 (とりあえず、配列数に比例して検索が耐えられなくなる状況はある程度緩和できそうかな、という気持ちです。)

ではでは。

(みんなでつくるダンジョン開発)アニメーション編集画面

f:id:piyorinpa:20171129004939g:plain (こんなかんじに動きます)

このあいだお知らせしたみんなでつくるダンジョンっぽいウェブサービスの開発を、ひーひー言いながらすすめています。 だんだん完成するか心配になってくるやつだ。。。

(というのも、お恥ずかしながら自分の技量不足でなかなかいい感じの設計にならないのです。)

そうはいってもひとまず手を動かさなければ進まないので、とりあえずアニメーション製作画面をつくってみました。

ログインしてアニメーション製作画面を表示し、予めアップロードした画像を選択すると、任意の場所を切り出すことができ、アニメーションの1コマをつくることができます。

プレビュー表示で確認しながら作ることもできます。

もう少ししたら、マップにキャラクターや地面を配置する様子や、アバターをつくる様子をお見せできると思います。 最近、平日は帰宅後の疲労感が以前より高いなぁと感じるので、ゆるりと作業を進められたらなぁと思っています。

ではでは。

(おしらせ)ぴこぴよのURLが変わりました

f:id:piyorinpa:20171126172146p:plain:w350
(画像はぴこぴよのキャラクター「だっくん」です)

ぴこぴよのURLが、 https://iconclub.jp/picopiyo から https://picopiyo.iconclub.jp に変更されました。 ブックマークをされている方は、変更をお願いします。

(とは言いつつも、しばらくの間はリダイレクトをかけるので、旧URLでもアクセスできます)

URLを変えた経緯について少しお話をば。

もともとぴこぴよは、あいこんくらぶのツイート機能を切り出して、もっと気軽にドット絵をつぶやいていただけるように新設したサービスなので、 iconclub.jp 以下にぴこぴよを配置するようなURLとなっていました。

しかしながら、あいこんくらぶよりもぴこぴよへのアクセスが多いためか、googleなどの検索サイトにおいて、(「ドット絵」などの)関連ワードであいこんくらぶがヒットしなくなり、 ぴこぴよが前面に出る形となってしまいました。 せっかくあいこんくらぶにドット絵を投稿して頂いているのに、これはまずいなと思い、今回のURL変更に至りました。

ということですので、今後もぴこぴよをよろしくおねがいします。

また、「ぴこぴよ」のツイート機能は「あいこんくらぶ」でも同様に利用できます。 お手持ちのドット絵をあいこんくらぶに投稿しつつ、ぴこぴよと同様にきれいにドット絵をつぶやいたりすることができるので、ぜひあいこんくらぶも 利用してみてくださいね!

(あいこんくらぶの機能についてはドット絵投稿・公開サービス「あいこんくらぶ」でできることをご覧ください)

ではでは。

みんなでつくるダンジョンサービス?を作っているよ!報告

最近つくっているものをそろそろ紹介してもいいかな、と思ったので、報告をば。 「みんなでつくるダンジョンアクション?」みたいなウェブサービスをつくっています。

イメージはこんなかんじ。

f:id:piyorinpa:20171123001952p:plain

ユーザーがマップを作り、マップの四方をじぶんもしくは他のユーザーが作ったマップとつなぐことで、巨大なダンジョンゲームっぽいものをつくろう、というウェブサービスです。 まだ作り始めたばかりで、ほとんど仕様が固まっていないのですが、大枠はこんな感じで進められたらいいな、と思っています。

一見ゲーム制作ツールのようにも見えますが、制作の自由度はあまり上げずに、はじめは「マップが作れて、マップ間を行き来出来て、かつそこそこカスタマイズできる」くらいなものを目指しているので、本格的なゲームを作れるわけではありません。

一方、ちょっと実装をし始めてみて「長い道のりになりそうだ。。。!」という感じにもなっており、必ずしも完成するとは限らないということを一応宣言しておきます。 (なにぶん一人で全部作っているので、半年とか1年コースになりそうなやつだ。。。)

ちなみに、画面描画はPixi.js, 編集ツールはVue.js, サーバサイドの実装はRuby on Railsで進めてみようかなと思っています。 あいこんくらぶのときはPHPJavaScriptJavaScriptフレームワークは使わず)な開発環境なので、ちょっと気分を変えてみていたり。 制作過程での知見などもブログ記事にできたらいいですね。

ではでは。

bashの履歴の展開機能でちょっとだけあわあわしてしまった

苦労してようやくいい感じの実装ができて、さてコミットを付けようと思いまして。

[bash]
$ git commit -am "タイルモード描画を設定できた!!!!!"

うれしさのあまりエクスクラメーションマーク「!」を5つも書いてしまっているところに喜びを表したかったのですが、 コミットログがおかしくなってしまいました。

git commit -am "タイルモード描画を設定できたgit commit -am "スプライトつくる周りをリファクタリング"git commit -am "スプライトつくる周りをリファクタリング"!"
[master abcdef0] タイルモード描画を設定できたgit commit -am スプライトつくる周りをリファクタリングgit commit -am スプライトつくる周りをリファクタリング!

bash!! は「最後に実行したコマンドを参照する」と解釈されるために起こる現象みたい。

たとえば、

$ echo hoge
> hoge

としたあとに、echo hoge!! を実行してみると、

$ echo hoge!!
> echo hogeecho hoge
> hogeecho hoge

と表示されます。(つまり、!!echo hoge が入り、 echo hogeecho hoge を実行したことに相当する)

全角で を書くか、bash! を解釈しないようにコミットメッセージ部分をシングルクォート ' で囲んであげればよいということですね。

ちょっとまえに読んでいた「入門bash」の知識がさっそく役に立った場面だったのでした。 www.oreilly.co.jp

ではでは。