JavaScript
Go
golang
riot

RiotとGo言語でデジモンのドット絵打つだけのサイト作った

More than 1 year has passed since last update.

16*16の2色のドット絵を打って投稿するサイトです。

突発的に思いついて5時間近く費やして作りました。

「Digital Pixel Monster」 http://digimon.laineus.com/

Digital Pixel Monster、略してデジモンです。

digimon_ss2.png

何気にGoで作ったapiを公開サーバーで実際に運用するの初めてだったりします。


使い方

左のキャンバスはピクセルをクリックすると着色できます。

着色済みのピクセルをクリックすると無色に戻ります。

右側ではサイトに投稿された作品一覧を閲覧できます。

何でも自由に投稿して大丈夫ですが、僕の独断で整理(削除)する場合があります。

riotとcssで描画しているだけなので画像データになったりはしません。


ソース

以下、RiotとGoのソース(一部)です。

ご指摘・アドバイス大歓迎です。


Riot ソース

描画と編集を行うコンポーネントです。

動作に最低限必要なところだけ抜き出してます。


app-canvas.tag

<app-canvas>

<ul class="dots">
<li each="{row, y in dots}">
<ul class="row">
<li class="{active: val==1}" each="{val, x in row}" onclick="{paint.bind(this, x, y)}"></li>
</ul>
</li>
</ul>

<style scoped>
:scope {
display: flex;
flex-direction: column;
min-height: 300px;
align-items: center;
justify-content: center;
}
:scope .dots {
display: inline-flex;
flex-direction: column;
border-top: 1px solid rgba(0,0,0,0.15);
border-left: 1px solid rgba(0,0,0,0.15);
}
:scope .dots .row {
display: flex;
flex-direction: row;
}
:scope .dots li {
list-style: none;
}
:scope .dots .row li {
width: 7px;
height: 7px;
border-right: 1px solid rgba(0,0,0,0.15);
border-bottom: 1px solid rgba(0,0,0,0.15);
}
:scope .dots .row li:hover {
background: #ccc;
}
:scope .dots .row li.active {
background: #333;
}
:scope .dots .row li.active:hover {
background: #666;
}
</style>

<script>
var self = this;
self.digimons = [];
self.dots = [
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0],
[0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0],
[0,0,1,1,1,0,0,0,0,1,1,0,0,1,0,0],
[0,1,0,0,0,0,0,0,0,0,1,1,0,1,0,0],
[0,1,0,0,0,0,0,0,0,1,1,1,0,1,0,0],
[0,1,0,0,0,0,1,1,0,0,0,0,0,1,0,0],
[0,0,1,1,1,1,0,0,0,0,0,0,0,1,0,0],
[0,0,1,0,0,0,0,0,1,1,0,0,1,0,0,0],
[0,0,0,1,1,1,1,1,0,1,1,0,1,0,0,0],
[0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0],
[0,0,1,1,1,1,0,0,1,1,1,1,0,1,0,0],
[0,0,0,0,0,1,1,0,0,0,0,1,0,0,1,0],
[0,0,0,1,1,0,0,1,1,1,1,0,0,0,1,0],
[0,0,1,0,1,0,0,1,0,1,0,1,0,1,0,1],
[0,0,1,1,1,1,1,1,0,1,1,1,1,1,1,1],
];
self.paint = function(x, y, e) {
self.dots[y][x] = (self.dots[y][x] == 1) ? 0 : 1;
self.update();
}
</script>
</app-canvas>


16*16の長さの配列を[][]int型で用意して、それをキャンバスとして扱っています。

テンプレートでは、この配列をループして、0なら白、1なら黒になるようclass名を付与しています。

各ドットをクリックした際のイベントでは、白なら黒、黒なら白に切り替える処理をしています。

[{x:2,y:3},{x:6,y:4}]みたいな感じで、塗った部分の座標を保持する形でもできましたかね。


実際のソース

ソース

index.html
view-source:http://digimon.laineus.com/index.html

editor component
view-source:http://digimon.laineus.com/app-editor.html

viewer component
view-source:http://digimon.laineus.com/app-viewer.html


Go ソース

コントローラー部分のみ抜粋

package controller

import (
"../models"
"github.com/gin-gonic/gin"
"strconv"
)

// GetDigimon デジモン取得api
func GetDigimon(c *gin.Context) {
digimonID, e := strconv.Atoi(c.Query("id"))
repo := model.NewDigimonRepository()
if e == nil {
digimon := repo.GetByID(digimonID)
c.JSON(200, digimon)
} else {
digimons := repo.GetAll()
c.JSON(200, digimons)
}
}

// Request リクエスト形式を定義する構造体
type Request struct {
Name string `json:"name"`
Data [][]int `json:"data"`
}

// PostDigimon デジモン投稿api
func PostDigimon(c *gin.Context) {
var request Request
c.BindJSON(&request)
chk := checkSize(&request.Data, 16, 16)
if chk {
if request.Name == "" {
request.Name = "no name"
}
repo := model.NewDigimonRepository()
repo.SetNewDigimon(request.Name, &request.Data)
digimons := repo.GetAll()
c.JSON(200, digimons)
} else {
c.JSON(200, false)
}
}

// n*nの[][]intであるかチェック
func checkSize(dots *[][]int, width, height int) bool {
chk := true
if len(*dots) != height {
chk = false
} else {
for _, row := range *dots {
if len(row) != width {
chk = false
break
}
}
}
return chk
}

DBには、[][]intのデータをそのままjson型で突っ込んでます。