Skip to content
Snippets Groups Projects
App.vue 9.17 KiB
Newer Older
Julian's avatar
Julian committed
<script setup>
Julian's avatar
Julian committed
import DragGrid from "../../src/DragGrid.vue";
Julian's avatar
Julian committed
import CircularCard from "./components/CircularCard.vue";
Julian's avatar
Julian committed
import NumberCounter from "./components/NumberCounter.vue";
Julian's avatar
Julian committed
</script>

<template>
  <div id="app">
Julian's avatar
Julian committed
    <DragGrid :rows="8" :cols="5" :pos-validation="blockField" v-model="items">
      <div id="blocker">
        This field is blocked because it's filled, the next one programmatically
      </div>
      <template #item="item">
        <div class="container">{{ item }}</div>
      </template>
Julian's avatar
Julian committed
    </DragGrid>
    <div class="ttt-container">
      <DragGrid
        :rows="3"
        :cols="3"
        v-model="ticTacToe1"
        class="tic-tac-toe"
        context="ticTacToe"
Julian's avatar
Julian committed
        :validate-element="randomKey"
      >
        <template #item="item">
          <CircularCard>
Julian's avatar
Julian committed
            {{ item.key.startsWith("a") ? "X" : "O" }}
          </CircularCard>
        </template>
      </DragGrid>
Julian's avatar
Julian committed
      <div>
Julian's avatar
Julian committed
        <p>
          These two are two different grids but we can drag from right to left!
        </p>
Julian's avatar
Julian committed
        <p>Drag items from the container on the right to play on the left.</p>
      </div>
      <DragGrid
Julian's avatar
Julian committed
        :rows="1"
        :cols="2"
        v-model="ticTacToe2"
        class="tic-tac-toe"
        context="ticTacToe"
Julian's avatar
Julian committed
        :pos-validation="blockAllMoving"
      >
        <template #item="item">
          <CircularCard>
Julian's avatar
Julian committed
            {{ item.data.text }}
          </CircularCard>
        </template>
      </DragGrid>
    </div>
Julian's avatar
Julian committed
    <div class="ttt-container">
      <drag-grid
        v-model="counters"
        :cols="3"
        :rows="2"
        id="c-grid"
        @input="logInput"
        context="counter"
      >
        <template #item="item">
          <number-counter v-model="item.data.num"></number-counter>
        </template>
Julian's avatar
Julian committed
        <template #highlight>
Julian's avatar
Julian committed
          <div ref="highlight" class="custom-highlight">
            Das hier ist das Highlight
          </div>
Julian's avatar
Julian committed
        </template>
Julian's avatar
Julian committed
      </drag-grid>
      <span>← Drag here please →</span>
      <drag-grid v-model="counters2" :cols="3" :rows="2" context="counter">
        <template #item="item">
          <number-counter v-model="item.data.num"></number-counter>
        </template>
      </drag-grid>
    </div>
    <div class="ttt-container">
      <div>
        <label>
          Lesson 1 has length: {{ lesson1Length }}
          <input
            type="range"
            v-model="lesson1Length"
            min="1"
            max="5"
            step="1"
          />
        </label>
        <input type="text" v-model="lessonData.lesson1" />
      </div>
      <div>
        <label>
          Lesson grid has width: {{ lesson1Cols }}
          <input type="range" v-model="lesson1Cols" min="2" max="5" step="1" />
        </label>
        <input type="text" v-model="lessonData.lesson2" />
      </div>
      <div>
        <label>
          Lesson grid has height: {{ lesson1Rows }}
          <input type="range" v-model="lesson1Rows" min="6" max="10" step="1" />
          <input type="text" v-model="lessonData.lesson3.inside" />
          <input type="text" v-model="lessonData.lesson3.outside" />
        </label>
      </div>

      <drag-grid
        :value="lessons1"
        :cols="parseInt(lesson1Cols)"
        :rows="parseInt(lesson1Rows)"
        class="bordered"
        context="lesson"
Julian's avatar
Julian committed
        grid-id="lesson-plan"
        @itemChanged="handleLessonMoved"
      >
        <template #item="item">
          <div class="container">{{ item }}</div>
        </template>
      </drag-grid>
Julian's avatar
Julian committed
      <drag-grid
        :value="lessons1"
        :cols="1"
        :rows="10"
        context="lesson"
        grid-id="lesson-storage"
        @itemChanged="handleLessonDropInContainer"
      >
        <template #item="item">
          <div class="container">{{ item }}</div>
        </template>
      </drag-grid>
    </div>
Julian's avatar
Julian committed
  </div>
</template>

<script>
export default {
  name: "App",
  methods: {
    blockField(x, y, key) {
Julian's avatar
Julian committed
      // We won't move fields with ID 'obj8' and nothing into (3, 3) and (4, 3)
      if (x === 3 && y === 3) return false;
      if (x === 4 && y === 3) return false;
      return key !== "obj8";
    },
Julian's avatar
Julian committed
    blockAllMoving() {
      return false;
    },
    randomKey(element) {
Julian's avatar
Julian committed
      if (element.key.length !== 1) return;
Julian's avatar
Julian committed
      element.key += Math.random().toString(36).replace("0.", "");
    },
    logInput(input) {
      console.log("New movement detected:", input);
    handleLessonMoved(lesson) {
      this.logInput(lesson);
      switch (lesson.key) {
        case "lesson1":
          this.lesson1X = lesson.x;
          this.lesson1Y = lesson.y;
          break;
        case "lesson2":
          this.lesson2X = lesson.x;
          this.lesson2Y = lesson.y;
          break;
Julian's avatar
Julian committed
        case "lesson3":
          this.lesson3X = lesson.x;
          this.lesson3Y = lesson.y;
          this.lesson3inPlan = true;
          break;
        default:
          console.error("Something is wrong here!");
      }
    },
Julian's avatar
Julian committed
    handleLessonDropInContainer(lesson) {
      if (lesson.key === "lesson3") this.lesson3inPlan = false;
    },
  data() {
    return {
      items: [
        { x: 1, y: 3, w: 1, h: 1, key: "obj1", data: {} },
        { x: 2, y: 1, w: 1, h: 1, key: "obj2", data: {} },
        { x: 3, y: 1, w: 2, h: 2, key: "obj3", data: {} },
        { x: 5, y: 2, w: 1, h: 1, key: "obj4", data: {} },
        { x: 1, y: 1, w: 1, h: 2, key: "obj5", data: {} },
        { x: 5, y: 1, w: 1, h: 1, key: "obj6", data: {} },
        { x: 2, y: 2, w: 1, h: 3, key: "obj7", data: {} },
        {
          x: 1,
          y: 4,
          w: 1,
          h: 1,
          key: "obj8",
          data: { title: "I'm blocked from moving!" },
        },
        { x: 5, y: 3, w: 1, h: 1, key: "obj9", data: {} },
      ],
      ticTacToe1: [
Julian's avatar
Julian committed
        { x: 1, y: 1, w: 1, h: 1, key: "a1", data: { text: "X" } },
        { x: 3, y: 3, w: 1, h: 1, key: "b1", data: { text: "O" } },
Julian's avatar
Julian committed
      ],
Julian's avatar
Julian committed
      ticTacToe2: [
Julian's avatar
Julian committed
        { x: 1, y: 1, w: 1, h: 1, key: "a", data: { text: "X" } },
        { x: 2, y: 1, w: 1, h: 1, key: "b", data: { text: "O" } },
      ],
      counters: [
        { x: 1, y: 1, w: 1, h: 1, key: "a", data: { num: 1 } },
        { x: 2, y: 1, w: 1, h: 1, key: "b", data: { num: 4 } },
        { x: 3, y: 2, w: 1, h: 1, key: "c", data: { num: -1 } },
      ],
      counters2: [
        { x: 1, y: 2, w: 1, h: 1, key: "d", data: { num: 30 } },
        { x: 3, y: 1, w: 1, h: 1, key: "e", data: { num: 3 } },
      lesson1Length: 1,
      lesson1Cols: 4,
      lesson1Rows: 6,
      lesson1X: 1,
      lesson1Y: 1,
      lesson2X: 2,
      lesson2Y: 1,
Julian's avatar
Julian committed
      lesson3X: -1,
      lesson3Y: -1,
      lesson3inPlan: false,
      lessonData: {
        lesson1: "Nothing",
        lesson2: "Hallo",
        lesson3: {
          inside: "This is lesson 3 inside the plan",
          outside: "This is lesson3 outside of the plan",
        },
      },
  computed: {
    lessons1() {
      return [
        {
Julian's avatar
Julian committed
          x: (grid) => {
            return grid.gridId === "lesson-plan" ? this.lesson1X : 0;
          },
          y: (grid) => {
            return grid.gridId === "lesson-plan" ? this.lesson1Y : 0;
          },
          w: 1,
          h: this.lesson1Length,
          key: "lesson1",
          data: {
            text: this.lessonData.lesson1,
          },
        },
        {
          x: (grid) => {
Julian's avatar
Julian committed
            return grid.gridId === "lesson-plan" ? this.lesson2X : 0;
          },
          y: (grid) => {
            return grid.gridId === "lesson-plan" ? this.lesson2Y : 0;
          },
          w: 1,
          h: parseInt(this.lesson1Length) + 1,
          key: "lesson2",
          data: {
            text: this.lessonData.lesson2,
          },
Julian's avatar
Julian committed
        {
          x: (grid) => {
            if (this.lesson3inPlan) {
              return grid.gridId === "lesson-plan" ? this.lesson3X : -1;
            }
            return grid.gridId === "lesson-plan" ? -1 : 0;
          },
          y: (grid) => {
            if (this.lesson3inPlan) {
              return grid.gridId === "lesson-plan" ? this.lesson3Y : -1;
            }
            return grid.gridId === "lesson-plan" ? -1 : 0;
          },
          w: 1,
          h: parseInt(this.lesson1Length) + 1,
          key: "lesson3",
          data: (grid) => {
            return {
              text:
                grid.gridId === "lesson-storage"
                  ? this.lessonData.lesson3.outside
                  : this.lessonData.lesson3.inside,
            };
          },
Julian's avatar
Julian committed
        },
};
</script>

<style scoped>
#blocker {
  grid-row: 3 / span 1;
  grid-column: 3 / span 1;
  background-image: linear-gradient(
    45deg,
    #edd85f 25%,
    #0f2b3d 25%,
    #0f2b3d 50%,
    #edd85f 50%,
    #edd85f 75%,
    #0f2b3d 75%,
    #0f2b3d 100%
  );
  background-size: 56.57px 56.57px;
  color: white;
  font-size: large;
  font-weight: bold;
  text-shadow: 4px 4px 4px #2c3e50;
}

.container {
  background: lightcoral;
  width: 100%;
  height: 100%;
}
Julian's avatar
Julian committed

.tic-tac-toe {
  max-width: 400px;
}

.ttt-container {
  display: flex;
  justify-content: space-between;
}
Julian's avatar
Julian committed
.custom-highlight {
  display: flex;
  align-items: center;
  justify-content: center;
  background: aquamarine;
  width: 100%;
  height: 100%;
}

.bordered {
  border: 2px solid grey;
}
</style>