ikuaitu / vue-fabric-editor

快图设计-基于fabric.js和Vue的开源图片编辑器,可自定义字体、素材、设计模板。fabric.js and Vue based image editor, can customize fonts, materials, design templates.
https://ikuaitu.github.io/doc/#/
MIT License
5.4k stars 983 forks source link

workspace外加上蒙层,而不是直接剪裁掉 #468

Closed momo2019 closed 3 months ago

momo2019 commented 3 months ago

功能已经实现了,做一个和canvas一样大的rect,然后clone一个workspace inverted然后剪裁,并且保证mask永远在最上层,且无法选中,点击事件可以透传。

但是在适配ResizePlugin的时候,蒙层无法更新,可以执行到更新函数,且里面使用到了的workspace相关的数据也是最新的,但是好像无法渲染出正确结果。

有什么排查思路吗,看了下ResizePlugin里的代码也没什么特殊的,workspace节点的数据也更新了

WX20240711-160620@2x WX20240711-160639@2x WX20240711-160659@2x

momo2019 commented 3 months ago

已经解决掉问题了。 做了个开关。主仓库需要这个功能吗

nihaojob commented 3 months ago

已经解决掉问题了。 做了个开关。主仓库需要这个功能吗 效果特别赞,大佬是怎么解决的 可以分享一下吗?

momo2019 commented 3 months ago

方法比较粗暴,分享下排查过程吧。 裁剪部分主要依赖了workspace的width,height,left和top,操作ResizePlugin的时候日志里workspace的这几个属性都是更新的,并且clone出来的,和mask的clipPath的这四个属性都是一致的,只是效果上是没有更新,但是mask的是绘制确实是更新了,相当于只有mask的clipPath部分没有更新。

然后setZoom和mouse:wheel的时候,日志是相同的,mask的clipPath的更新也是正确的。 只能排查这三个操作的差异。 定位到

const center = this.canvas.getCenter();
this.canvas.zoomToPoint(new fabric.Point(center.left, center.top), zoom);

在更新函数里加上这段,也没有什么意义。这时候基本定位到应该是fabric内部的某个情况下,导致的clipPath的数据更新不执行,判断为和zoom有关。所以直接加了个判断,如果是ResizePlugin执行中直接更新的话,就变化一下zoom。

const zoom = this.canvas.getZoom();
this.canvas.zoomToPoint(
  new fabric.Point(center.left, center.top),
  hack ? zoom - 0.0000001 : zoom // 比较hack的方法,判断为fabric内部的数据更新问题
);

然后就生效了

Qiu-Jun commented 3 months ago

方法比较粗暴,分享下排查过程吧。 裁剪部分主要依赖了workspace的width,height,left和top,操作ResizePlugin的时候日志里workspace的这几个属性都是更新的,并且clone出来的,和mask的clipPath的这四个属性都是一致的,只是效果上是没有更新,但是mask的是绘制确实是更新了,相当于只有mask的clipPath部分没有更新。

然后setZoom和mouse:wheel的时候,日志是相同的,mask的clipPath的更新也是正确的。 只能排查这三个操作的差异。 定位到

const center = this.canvas.getCenter();
this.canvas.zoomToPoint(new fabric.Point(center.left, center.top), zoom);

在更新函数里加上这段,也没有什么意义。这时候基本定位到应该是fabric内部的某个情况下,导致的clipPath的数据更新不执行,判断为和zoom有关。所以直接加了个判断,如果是ResizePlugin执行中直接更新的话,就变化一下zoom。

const zoom = this.canvas.getZoom();
this.canvas.zoomToPoint(
  new fabric.Point(center.left, center.top),
  hack ? zoom - 0.0000001 : zoom // 比较hack的方法,判断为fabric内部的数据更新问题
);

然后就生效了

大佬你好,代码我回退解耦成单独插件再合并过来下哈