【Vue.js】カテゴリ一致の問題を作ってみる。

Vue.jsで画像をドラッグアンドドロップで同じカテゴリ同士になるようにする問題を作ってみました。

点数と点数に応じて文言も変わります。

 

サンプル

サンプルページ

 

 

HTML


<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" />
  <link rel="stylesheet" href="./css/narabikae_default.css" />
  <title>ドラッグ&ドロップ問題</title>
</head>
<body>
  <div id="app" class="container mt-5">
    <h1>{{ message }}</h1>
    <div class="d-flex justify-content-between bg-dark p-3">
      <div class="bg-secondary p-2 m-2 w-100" @drop="dropList($event, 'A')" @dragover.prevent @dragenter.prevent>
        <h2 class="text-light">くだもの</h2>
        <div class="bg-white m-2 p-2 choice" v-for="(list,index) in CategoryA" draggable
          @dragstart="dragList($event,list.id)">
          <img :src="list.image_link" />
          {{list.name}}
        </div>
      </div>
      <div class="bg-secondary p-2 m-2 w-100" @drop="dropList($event, 'B')" @dragover.prevent @dragenter.prevent>
        <h2 class="text-light">どうぶつ</h2>
        <div class="bg-white m-2 p-2 choice" v-for="(list,index) in CategoryB" draggable
          @dragstart="dragList($event,list.id)">
          <img :src="list.image_link" />
          {{list.name}}
        </div>
      </div>
      <div class="bg-secondary p-2 m-2 w-100 " @drop="dropList($event, 'C')" @dragover.prevent @dragenter.prevent>
        <h2 class="text-light">のりもの</h2>
        <div class="bg-white m-2 p-2 choice" v-for="(list,index) in CategoryC" draggable
          @dragstart="dragList($event,list.id)">
          <img :src="list.image_link" />
          {{list.name}}
        </div>
      </div>
      <div class="bg-secondary p-2 m-2 w-100" @drop="dropList($event, 'D')" @dragover.prevent @dragenter.prevent>
        <h2 class="text-light">ぜんぶつかってね!</h2>
        <div class="bg-white m-2 p-2 choice" v-for="(list,index) in CategoryD" draggable
          @dragstart="dragList($event,list.id)">
          <img :src="list.image_link" />
          {{list.name}}
        </div>
      </div>
    </div>
    <div class="answer" v-if="answer.length > 0">
      <div v-if="answer == '3'">
        すべて使ってください
      </div>
      <div v-else-if="this.percent_score == 100">
        素晴らしい
      </div>
      <div v-else-if="this.percent_score > 70">
        惜しい!
      </div>
      <div v-else-if="this.percent_score > 50">
        もう少し頑張って
      </div>
      <div v-else-if="this.percent_score > 10">
        YBAINE
      </div>
      <div v-else>
        ( ^ω^)・・・
      </div>
      <p v-if="answer != '3'">正答率は{{percent_score}}%</p>
    </div>
    <div class="endBtn">
      <input type="button" value="結果をみる" @click="kekka" />
    </div>
  </div>
  <script src="./js/narabikae_script.js"></script>
</body>
</html>

CSS


.answer {
    text-align: center;
    font-size: 36px;
    padding: 25px 0;
}
.endBtn {
    text-align: center;
    margin-top: 50px;
    margin-bottom: 50px;
}
.endBtn input {
    border: none;
    background: none;
    background-color: #808080;
    padding: 25px 30px;
    border-radius: 10px;
    color: #fff;
    box-shadow: 5px 5px rgba(0, 0, 0, 0.6);
    transition: 0.5s;
}
.endBtn input:hover {
    box-shadow: 4px 4px rgba(0, 0, 0, 0.6);
    transform: translate(1px, 1px);
    transition: 0.5s;
}
.endBtn input:active {
    box-shadow: none;
    transform: translate(5px, 5px);
    transition: 0.5s;
}
.choice {
    cursor: grab;
    /*文字などの選択禁止*/
    -moz-user-select: none;
    -webkit-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
.choice img {
    width: 30%;
}
.choice:active {
    cursor: grabbing;
}
/*Webkit系画像のドラッグ&ドロップの禁止*/
img {
    -webkit-user-drag: none;
}
img[draggable="true"] {
    -webkit-user-drag: auto;
}

JavaScript


window.onload = function () {
    const app = new Vue({
        el: "#app",
        data: {
            message: "おなじグループにわけよう!",
            list_ends: [],
            lists: [
                /*食べ物*/
                {
                    id: 1,
                    name: "黄色いリンゴ",
                    image_link: "./media/frut/fruit_apple_yellow.png",
                    category: "D",
                    answer: "A",
                },
                {
                    id: 2,
                    name: "メロン",
                    image_link: "./media/frut/fruit_prince_melon.png",
                    category: "D",
                    answer: "A",
                },
                {
                    id: 3,
                    name: "シークワーサー",
                    image_link: "./media/frut/fruit_shi-kuwa-sa_shikuwasa.png",
                    category: "D",
                    answer: "A",
                },
                {
                    id: 4,
                    name: "すいか",
                    image_link: "./media/frut/fruit_suika_kodama.png",
                    category: "D",
                    answer: "A",
                },
                /*乗り物*/
                {
                    id: 5,
                    name: "くるま",
                    image_link: "./media/norimono/car_go_kart_man.png",
                    category: "D",
                    answer: "C",
                },
                {
                    id: 6,
                    name: "ぎゅうしゃ",
                    image_link: "./media/norimono/hinamatsuri_gyuusya.png",
                    category: "D",
                    answer: "C",
                },
                {
                    id: 7,
                    name: "しんかんせん",
                    image_link: "./media/norimono/tube_train_hyperloop.png",
                    category: "D",
                    answer: "C",
                },
                {
                    id: 8,
                    name: "せんしゃ",
                    image_link: "./media/norimono/war_kettenkrad.png",
                    category: "D",
                    answer: "C",
                },
                /*どうぶつ*/
                {
                    id: 9,
                    name: "いぬさん",
                    image_link: "./media/animal/animal_mizugi_boy_inu.png",
                    category: "D",
                    answer: "B",
                },
                {
                    id: 10,
                    name: "くまさん",
                    image_link: "./media/animal/animal_mizugi_boy_kuma.png",
                    category: "D",
                    answer: "B",
                },
                {
                    id: 11,
                    name: "ねこさん",
                    image_link: "./media/animal/animal_mizugi_boy_neko.png",
                    category: "D",
                    answer: "B",
                },
                {
                    id: 12,
                    name: "うさぎさん",
                    image_link: "./media/animal/animal_mizugi_boy_usagi.png",
                    category: "D",
                    answer: "B",
                },
            ],
            answer: "",
            percent_score: "",
        },
        computed: {
            CategoryA() {
                return this.list_ends.filter((list) => list.category == "A");
            },
            CategoryB() {
                return this.list_ends.filter((list) => list.category == "B");
            },
            CategoryC() {
                return this.list_ends.filter((list) => list.category == "C");
            },
            CategoryD() {
                return this.list_ends.filter((list) => list.category == "D");
            },
        },
        mounted: function () {
            this.list_ends = this.shuffle(this.lists);
        },
        methods: {
            shuffle: function (array) {
                for (let i = array.length - 1; i > 0; i--) {
                    let r = Math.floor(Math.random() * (i + 1));
                    let tmp = array[i];
                    array[i] = array[r];
                    array[r] = tmp;
                }
                console.log(array);
                return array;
            },
            dragList(event, dragId) {
                event.dataTransfer.effectAllowed = "move";
                event.dataTransfer.dropEffect = "move";
                event.dataTransfer.setData("list-id", dragId);
            },
            dropList(event, dropCategory) {
                const dragId = event.dataTransfer.getData("list-id");
                const dragList = this.lists.find((list) => list.id == dragId);
                dragList.category = dropCategory;
            },
            kekka: function () {
                var edge = null;
                var atari = null;
                var Dcount = 0;
                var score = [];
                var total_score = 0;
                var total_count = this.lists.length;
                var percent_score = 0;
                for (i = 0; i < 3; i++) {
                    score[i] = 0;
                }
                this.lists.forEach((list) => {
                    if (list.category == "A") {
                        if (list.answer != "A") {
                            edge = true;
                        } else {
                            atari = true;
                            score[0]++;
                        }
                    }
                    if (list.category == "B") {
                        if (list.answer != "B") {
                            edge = true;
                        } else {
                            atari = true;
                            score[1]++;
                        }
                    }
                    if (list.category == "C") {
                        if (list.answer != "C") {
                            edge = true;
                        } else {
                            atari = true;
                            score[2]++;
                        }
                    }
                    if (list.category == "D") {
                        Dcount++;
                    }
                });
                if (Dcount == 0) {
                    if (edge == true) {
                        this.answer = "2";
                    } else if (atari == true) {
                        this.answer = "1";
                    }
                } else {
                    this.answer = "3";
                }
                score.forEach(function (sco) {
                    total_score += sco;
                });
                percent_score = Math.ceil((total_score / total_count) * 100);
                this.percent_score = percent_score;
            },
        },
    });
};
 

投稿者 PASOMEN

関連投稿

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です