Skip to content
Snippets Groups Projects
DragContainer.vue 2.51 KiB
Newer Older
<template>
    @dragstart="handleDragStart"
    @dragmove="handleDragMove"
    :draggable="!isDisabled"
    id="wrapper"
    ref="wrapper"
    @dragend="handleDragEnd"
    :data-transfer="dataTransferString"
</template>

<script>
export default {
  name: "DragContainer",
  methods: {
    handleDragStart(event) {
Julian's avatar
Julian committed
      if (this.isDisabled) return;
      let rect = event.target.getBoundingClientRect();
      this.dataTransfer = {
        key: this.dragID,
        x: this.x,
        y: this.y,
        w: this.w,
        h: this.h,
        data: this.data,
        context: this.context,
        originGridId: this.gridId,
        mouseX: event.clientX - rect.x - rect.width / (2 * this.w), // relative to center of the top left square
        mouseY: event.clientY - rect.y - rect.height / (2 * this.h),
      };
Julian's avatar
Julian committed
    },
    handleDragEnd() {
      this.offsetX = 0;
      this.offsetY = 0;
    },
    handleDragMove(event) {
      this.offsetX += event.dx;
      this.offsetY += event.dy;
Julian's avatar
Julian committed
  },
  props: {
Julian's avatar
Julian committed
    dragID: {
      type: String,
      required: true,
    },
    x: {
      type: Number,
      required: true,
    },
    y: {
      type: Number,
      required: true,
    },
    w: {
      type: Number,
      required: true,
    },
    h: {
      type: Number,
      required: true,
    },
    data: {
      type: Object,
      required: false,
      default: () => ({}),
    },
    context: {
      type: String,
      required: true,
    },
    gridId: {
      type: String,
      required: true,
    },
Julian's avatar
Julian committed
    disabled: Boolean,
  },
  computed: {
    isInGrid() {
      return this.x >= 0 && this.y >= 0;
    },
    isNotInGrid() {
      return this.x === -1 || this.y === -1;
    },
    getX() {
      return this.x === 0 ? "auto" : this.x;
    },
    getY() {
      return this.y === 0 ? "auto" : this.y;
    },
    getDisplay() {
      return this.isInGrid ? "block" : "none";
    },
    isDisabled() {
      return this.disabled || this.isNotInGrid;
    },
    cursor() {
      return this.disabled ? "auto" : "grab";
    },
    dataTransferString() {
      return JSON.stringify(this.dataTransfer);
    },
  },
  data() {
    return {
      dataTransfer: {},
      offsetX: 0,
      offsetY: 0,
    };
</script>

<style scoped>
Julian's avatar
Julian committed
#wrapper {
Julian's avatar
Julian committed
  grid-column: v-bind(getX) / span v-bind(w);
  grid-row: v-bind(getY) / span v-bind(h);
  display: v-bind(getDisplay);
  cursor: v-bind(cursor);
  transform: translate(
    calc(1px * v-bind(offsetX)),
    calc(1px * v-bind(offsetY))
  );
Julian's avatar
Julian committed
</style>