刷新Vue组件中的Konva形状状态
Refreshing Konva shape state in Vue component
拖放一个形状后,我希望它能捕捉到一个接近的位置。为了对此进行测试,我在 {x:100, y:100}
处创建了一个形状,然后拖动它,它确实捕捉到 0,0
,但只是我第一次拖动它。下次它会忽略我设置 x,y
.
我可能遗漏了一些基本的东西?也许我没有以正确的方式改变商店。在下面的代码中,您可以看到在 handleDragend
.
中设置 x 和 y 的三次尝试
<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>
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) 保持store与节点位置同步
您可能需要将所有位置更改注册到商店中:
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()
});
}
拖放一个形状后,我希望它能捕捉到一个接近的位置。为了对此进行测试,我在 {x:100, y:100}
处创建了一个形状,然后拖动它,它确实捕捉到 0,0
,但只是我第一次拖动它。下次它会忽略我设置 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>
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) 保持store与节点位置同步
您可能需要将所有位置更改注册到商店中:
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()
});
}