Vue.jsでそれっぽい何かを作る2(改造)

株式会社イメージ・マジックの技術ブログ、今回の担当のsoenoです。 実務でいろいろ触ってはいるのですが。投稿しやすいコンテンツとなるとどうにも…。 というわけで以前の投稿に乗っかろうと思います。


何をするか

以前の投稿で作成したVueの機能を流用し、改造、改善していきます。

何を変えるか考える

前の機能の印象から変更点を考える

  1. webなのに白黒ってどうなのだろう。
    • 色を増やす
    • 色を増やせるように色の選択機能を追加 
  2. 見本と入力エリアが同じ大きさってどうなのだろう。(比較はしやすい?)
    • サイズを変える
  3. 升目少ない。
    • 増やす。
  4. どこ操作していいかわからない。
    • 入力エリアに枠を付けて目立たせる
  5. そろったかどうかどう確認するかわかりにくい(今は自動で勝手にチェックする)
    • チェックボタンを押すまでは比較しない
  6. 大人よりは子供向けのゲームになるだろうな。
    • ひらがなにする。

結果

できました!
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>vue</title>
    <style type="text/css">
      .wrapStyle{
          margin: 0 50px;
          display: block;
          position: relative;
          float: left;
      }
      .celAreaWrap{
        border: solid 2px #414141;
      }
      .celWrap{
          display: inline-block;
          box-sizing: content-box;
          margin:0;
          display: inline-block;
      }
      .cel{
          border:solid thin #eeeeee; 
          box-sizing: border-box;
          display: inline-block;
          margin:0;
          padding:0;
      }
      .colorCel{
        border: solid 2px #666666;
      }
      .btn{
        margin-top: 50px;
        border: solid 2px #666666;
        padding: 15px;
        min-width: 121px;
        text-align: center;
        background: #ffa500;
      }
      .cel_clr0{
          background-color:#ffffff;
      }
      .cel_clr1{
          background-color:#111111;
      }
      .cel_clr2{
          background-color:#ff0000;
      }
      .cel_clr3{
          background-color:#fc5000;
      }
      .cel_clr4{
          background-color:#f8ab04;
      }
      .cel_clr5{
          background-color:#48ff00;
      }
      .cel_clr6{
          background-color:#09f7ff;
      }
      .cel_clr7{
          background-color:#002fff;
      }
      .cel_clr8{
          background-color:#a304ff;
      }
    </style>
</head>
<body>
<div id="app">
  <div class="wrapStyle" v-bind:style="mihonBoxStyle">
    <p>みほん</p>
    <div v-for="(items, yoko) in resultList" v-bind:style="mihonCelWrap">
      <div v-for="(item, tate) in items" 
            v-bind:style="mihonCelStyle" class="cel" 
            v-bind:class="'cel_clr' + resultList[yoko][tate]">
      </div> 
    </div>
  </div>
  <div class="wrapStyle" v-bind:style="boxStyle">
    <p>みほんをまねしてね</p>
    <div class="celAreaWrap">
      <div v-for="(items, yoko) in userList" v-bind:style="celWrap">
        <div v-for="(item, tate) in items"
            v-on:click="changeCel(userList[yoko][tate])" :data-yoko="yoko" :data-tate="tate"
            v-bind:style="celStyle" class="cel"
            v-bind:class="'cel_clr' + userList[yoko][tate]">
        </div>
      </div>
    </div>
    <div>
      <p>いろをえらぼう</p>
      <div v-bind:style="celWrap">
        <div v-for="id in colorIdList" v-on:click="changeColor(id)" v-bind:style="celStyle" class="cel colorCel" v-bind:class="'cel_clr' + id">
        </div>
      </div>
    </div>
  </div>
  <div class="wrapStyle">
      <div v-on:click="check()" class="btn">そろったかな?</div>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script language="javascript">
new Vue({
  el: '#app',
  data: {
    cellSize:60,
    nowColor:1,
    resultList: [
      [0,0,1,1,1,1,1,0,0],
      [0,1,4,4,4,4,4,1,0],
      [1,4,4,1,4,1,4,4,1],
      [1,4,4,4,4,4,4,4,1],
      [1,4,1,4,4,4,1,4,1],
      [1,4,1,4,4,4,1,4,1],
      [1,4,4,1,1,1,4,4,1],
      [0,1,4,4,4,4,4,1,0],
      [0,0,1,1,1,1,1,0,0],
    ],
    userList: [
      [0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0],
      [0,0,0,0,0,0,0,0,0],
    ],
    
    colorIdList:[0,1,2,3,4,5,6,7,8],
    
    mihonBoxStyle:{
      width:0,
    },
    mihonCelWrap:{
      height:0,
    },
    mihonCelStyle:{
      width:0,
      height:0,
    },

    boxStyle:{
      width:0,
    },
    celWrap:{
      height:0,
    },
    celStyle:{
      width:0,
      height:0,
    },
  },
  created() {
    this.mihonCelStyle.width = this.cellSize/3+ 'px';
    this.mihonCelStyle.height = this.cellSize/3+ 'px';
    this.mihonCelWrap.height = this.cellSize/3+ 'px';
    this.mihonBoxStyle.width = this.mihonCelWrap * this.resultList[0].length + 'px';

    this.celStyle.width = this.cellSize+ 'px';
    this.celStyle.height = this.cellSize+ 'px';
    this.celWrap.height = this.cellSize+ 'px';
    this.boxStyle.width = this.cellSize * this.resultList[0].length + 4 + 'px';//4はボーダー
  },
  
  methods: {
    changeColor(id) {
      this.nowColor = id;
    },
    changeCel() {
      const yoko = parseInt(event.currentTarget.dataset.yoko);
      const tate = parseInt(event.currentTarget.dataset.tate);
      Vue.set(this.userList[yoko], tate, this.nowColor);
    },
    //確認ボタンが押されたら揃ったか確認する。
    check() {
      for(let i=0,len = this.resultList.length; i<len; i++){
        for(let ii=0,len2 = this.resultList[i].length; ii<len2; ii++){
          if(this.userList[i][ii] !== this.resultList[i][ii]){
            //不一致があったら処理を抜ける
            alert("まだそろってません。");
            return;
          }
        }
      }
      setTimeout(function () {
        alert("そろいました。おめでとうございます!");
      }, 100);
    },
  },
})
</script>
</body>
</html>