Обновление состояния формы Konva в компоненте Vue - PullRequest
1 голос
/ 22 марта 2020

После перетаскивания фигуры, я хочу, чтобы она привязывалась к позиции. Чтобы проверить это, я создаю фигуру на {x:100, y:100}, затем перетаскиваю ее, и она привязывается к 0,0, но только в первый раз, когда я тащу ее. В следующий раз он проигнорирует меня, установив x,y.

Возможно, я что-то упустил здесь? 1009 * здесь? Может быть, я не мутирую в магазине правильно. В приведенном ниже коде вы можете увидеть три попытки установить x и y в handleDragend.

<template>
  <div>
    <v-stage
      ref="stage"
      :config="configKonva"
      @dragstart="handleDragstart"
      @dragend="handleDragend"
    >
      <v-layer ref="layer">
        <v-regular-polygon
          v-for="item in list"
          :key="item.id"        
          :config="{  
            x: item.x,
            y: item.y,
            sides: 6,
            rotation: item.rotation,
            id: item.id,
            radius: 50,
            outerRadius: 50,
            fill: 'green',
            draggable: true,
          }"
        ></v-regular-polygon>
      </v-layer>
    </v-stage>
  </div>
</template>

<script>

const width = window.innerWidth;
const height = window.innerHeight;

export default {
  data() {
    return {
      list: [],
      dragItemId: null,
      configKonva: {
        width: width,
        height: height,       
      }
    };
  },
  methods: {
    handleDragstart(e) {
        //
    },
    handleDragend(e) {
        let item = this.list.find(i => i.id === e.target.id());

        let snapTo = { x: 0, y: 0}

        // Attempt 1
        Vue.set(this.list, 0, {
            ...item,
            x: snapTo.x,
            y: snapTo.y,
        })

        // Attempt 2    
        this.list = this.list.map(function(shape) {
            if(shape.id === item.id) {
                return {
                    ...item,
                    x: snapTo.x,
                    y: snapTo.y,
                }
            }
        })
    },
  },

  mounted() {
    this.list.push({
        id: 1,
        x: 100,
        y: 100,
    });
  }
};
</script>

1 Ответ

1 голос
/ 24 марта 2020

vue-konva обновляет узлы ТОЛЬКО при наличии изменений в шаблоне.

При первой привязке координаты в шаблоне (и хранилище) изменяются с {100, 100} на {0, 0}.

Когда вы перетаскиваете узел во второй раз, хранилище все еще сохраняет {0, 0} в памяти. Таким образом, никакие изменения не инициируются и узел не перемещается назад.

Существует два способа решения проблемы:

(1) Обновление положения узла Konva вручную

handleDragend(e) {
      let item = this.list.find(i => i.id === e.target.id());

      let snapTo = { x: 0, y: 0 };
      e.target.position(snapTo);
      e.target.getLayer().batchDraw();
      Vue.set(this.list, 0, {
        ...item,
        x: snapTo.x,
        y: snapTo.y
      });
}

(2) Поддерживайте синхронизацию магазина c с позицией узла

Вам может потребоваться зарегистрировать все изменения позиции в магазине:

handleDragMove(e) {
      // do this on every "dragmove"
      let item = this.list.find(i => i.id === e.target.id());

      Vue.set(this.list, 0, {
        ...item,
        x: e.target.x(),
        y: e.target.y()
      });
}

Демонстрация: https://codesandbox.io/s/nifty-northcutt-v52ue

...