英文:
Resizing and clipping grouped element in Vue KonvaJS
问题
我正在尝试在Vue库上使用KonvaJS构建一个应用程序。
我有一个分组图层,在这个分组中绘制了一个圆并放置了图像。
<v-group
v-for="item in listGroup_Logo"
:key="item.name"
:ref="item.name"
:config="item"
@dblclick="check"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
>
<v-circle
v-for="item in listCircle_Logo"
:key="item.name"
:ref="item.name"
:config="item"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
></v-circle>
<v-image
v-for="item in listLogo"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
:ref="item.name"
:key="item.name"
:config="item"
:keyup.delete="deleteItemFromKey"
></v-image>
</v-group>
目标是根据圆/分组区域裁剪图像。此外,最终用户可以集体调整组元素的大小。正如你在下面看到的,调整组会影响圆的轮廓。
为了实现这一点,我定义了基本的配置数据集 listGroup_Logo
,将其传递到分组图层内,以便在初始渲染时呈现此配置数据。
listGroup_Logo: [
{
clipFunc: (ctx) => {
ctx.arc(50, 50, 30, 0, Math.PI * 2, false);
},
draggable: true,
x: 50,
y: 50,
name: "Group1676367620342",
type: "group",
},
],
为了添加拖放功能,我在v-stage
组件上跟踪@mousedown
和@touchstart
事件,并定义了一个方法handleMousedown
来进行进一步的修改。
我试图获取x和y位置以及scaleX
和scaleY
值,并尝试更新圆的配置:
this.listCircle_Logo[objIndex] = e.target.attrs;
let scaleX =
typeof e.target.attrs.scaleX === "undefined"
? 1
: e.target.attrs.scaleX;
let scaleY =
typeof e.target.attrs.scaleY === "undefined"
? 1
: e.target.attrs.scaleY;
let obj = {
clipFunc: (ctx) => {
ctx.arc(
50 * scaleX,
50 * scaleY,
30 * scaleX,
0,
Math.PI * 2,
false
);
},
};
this.listGroup_Logo[0].clipFunc = obj.clipFunc;
但圆没有更新其值。请参见下面的图像:
我已经为我的代码创建了一个沙箱。你可以在这里找到它: https://codesandbox.io/s/bold-fog-ivccnt?file=/src/App.vue
请就如何调整整个组而不干扰线条或圆给予建议。
英文:
I'm trying to build an application on KonvaJS with the Vue library.
I've got a group layer where I'm drawing a circle and placing images inside this group.
<v-group
v-for="item in listGroup_Logo"
:key="item.name"
:ref="item.name"
:config="item"
@dblclick="check"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
>
<v-circle
v-for="item in listCircle_Logo"
:key="item.name"
:ref="item.name"
:config="item"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
/>
<v-image
v-for="item in listLogo"
@dragstart="handleDragStart"
@dragend="handleDragEnd"
:ref="item.name"
:key="item.name"
:config="item"
:keyup.delete="deleteItemFromKey"
/>
</v-group>
The goal is to clip the images as per the circle/group area. Also, the end user can resize the group element collectively. As you can see below, resizing the group effects the circle strokes.
To achieve this I defined the basic configuration dataset listGroup_Logo
to be passed inside the group layer, so this config data renders at the initial rendering.
listGroup_Logo: [
{
clipFunc: (ctx) => {
ctx.arc(50, 50, 30, 0, Math.PI * 2, false);
},
draggable: true,
x: 50,
y: 50,
name: "Group1676367620342",
type: "group",
},
],
To add drag and drop functionality I'm tracking @mousedown
and @touchstart
events at v-stage
component and defined a method handleMousedown
to do the further modifications.
I'm trying to fetch the x and y positions along with the scaleX
and scaleY
values and trying to update the circle configs:
this.listCircle_Logo[objIndex] = e.target.attrs;
let scaleX =
typeof e.target.attrs.scaleX === "undefined"
? 1
: e.target.attrs.scaleX;
let scaleY =
typeof e.target.attrs.scaleY === "undefined"
? 1
: e.target.attrs.scaleY;
let obj = {
clipFunc: (ctx) => {
ctx.arc(
50 * scaleX,
50 * scaleY,
30 * scaleX,
0,
Math.PI * 2,
false
);
},
};
this.listGroup_Logo[0].clipFunc = obj.clipFunc;
But the circle is not updating its values. See the image below:
I've made a sandbox for my code. You can find it here: https://codesandbox.io/s/bold-fog-ivccnt?file=/src/App.vue
Please advise on how to resize the entire group without disturbing the strokes or circles.
答案1
得分: 1
// 每次转换圆形时,您可能需要更改组的裁剪:
handleTransform(e) {
this.listGroup_Logo[0].clipFunc = (ctx) => {
ctx.save();
ctx.scale(e.target.scaleX(), e.target.scaleY())
ctx.arc(
e.target.x() / e.target.scaleX(),
e.target.y() / e.target.scaleY(),
30,
0,
Math.PI * 2,
false
);
ctx.restore();
};
},
您可以在此链接中查看示例:codesandbox.io/s/dreamy-hugle-8zqcci?file=/src/App.vue
此外,为了获得更好的视图,我向圆形添加了 strokeScaleEnabled: false
,并向变换器添加了 ignoreStroke: true
。
英文:
You may need to change the clipping of your group every time you transform circle:
handleTransform(e) {
this.listGroup_Logo[0].clipFunc = (ctx) => {
ctx.save();
ctx.scale(e.target.scaleX(), e.target.scaleY())
ctx.arc(
e.target.x() / e.target.scaleX(),
e.target.y() / e.target.scaleY(),
30,
0,
Math.PI * 2,
false
);
ctx.restore();
};
},
https://codesandbox.io/s/dreamy-hugle-8zqcci?file=/src/App.vue
Also for a bit better view I added strokeScaleEnabled: false
to circle and ignoreStroke: true
to transformer.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论