Skip to content

Commit edc87d0

Browse files
momo2019Qiu-Jun
authored andcommitted
feat(core): workspace加入蒙层功能,已考虑layer,resize和loadjson的适配
1 parent 519f6d7 commit edc87d0

File tree

4 files changed

+89
-16
lines changed

4 files changed

+89
-16
lines changed

packages/core/plugin/LayerPlugin.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,24 @@ class LayerPlugin implements IPluginTempl {
1616
constructor(public canvas: fabric.Canvas, public editor: IEditor) {}
1717

1818
_getWorkspace() {
19-
return this.canvas.getObjects().find((item) => item.id === 'workspace');
19+
const result: Record<'workspace' | 'coverMask', fabric.Object | null> = {
20+
workspace: null,
21+
coverMask: null,
22+
};
23+
this.canvas.getObjects().forEach((item) => {
24+
if (item.id === 'workspace') {
25+
result.workspace = item;
26+
} else if (item.id === 'coverMask') {
27+
result.coverMask = item;
28+
}
29+
});
30+
return result;
2031
}
2132

2233
_workspaceSendToBack() {
2334
const workspace = this._getWorkspace();
24-
workspace && workspace.sendToBack();
35+
workspace.workspace && workspace.workspace.sendToBack();
36+
workspace.coverMask && workspace.coverMask.bringToFront();
2537
}
2638

2739
up() {

packages/core/plugin/ResizePlugin.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { fabric } from 'fabric';
1010
import Editor from '../Editor';
1111
import { throttle } from 'lodash-es';
1212
import '../styles/resizePlugin.css';
13+
import WorkspacePlugin from './WorkspacePlugin';
1314

1415
type IEditor = Editor;
1516

@@ -203,10 +204,8 @@ class ResizePlugin implements IPluginTempl {
203204
}
204205

205206
this.editor.setCenterFromObject(workspace);
206-
workspace.clone((cloned: fabric.Rect) => {
207-
this.canvas.clipPath = cloned;
208-
this.canvas.requestRenderAll();
209-
});
207+
(this.editor.getPlugin('WorkspacePlugin') as WorkspacePlugin).setCoverMask(true);
208+
(this.editor.getPlugin('WorkspacePlugin') as WorkspacePlugin).clipPath();
210209
if (['left', 'right'].includes(type)) {
211210
this.canvas.defaultCursor = 'ew-resize';
212211
} else {

packages/core/plugin/WorkspacePlugin.ts

Lines changed: 71 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class WorkspacePlugin implements IPluginTempl {
2727
workspaceEl!: HTMLElement;
2828
workspace: null | fabric.Rect;
2929
resizeObserver!: ResizeObserver;
30+
coverMask: null | fabric.Rect = null;
3031
option: any;
3132
zoomRatio: number;
3233
constructor(public canvas: fabric.Canvas, public editor: IEditor) {
@@ -148,6 +149,69 @@ class WorkspacePlugin implements IPluginTempl {
148149
this.auto();
149150
}
150151

152+
setCoverMask(hack = false) {
153+
if (!this.coverMask || !this.workspace) {
154+
return;
155+
}
156+
const center = this.canvas.getCenter();
157+
const zoom = this.canvas.getZoom();
158+
this.canvas.zoomToPoint(
159+
new fabric.Point(center.left, center.top),
160+
hack ? zoom - 0.0000001 : zoom // 比较hack的方法,判断为fabric内部的数据更新问题
161+
);
162+
if (zoom) {
163+
const { workspaceEl } = this;
164+
const width = workspaceEl.offsetWidth;
165+
const height = workspaceEl.offsetHeight;
166+
const cWidth = width / zoom;
167+
const cHeight = height / zoom;
168+
this.coverMask.width = cWidth;
169+
this.coverMask.height = cHeight;
170+
this.coverMask.left = (this.workspace.left || 0) + (this.workspace.width! - cWidth) / 2;
171+
this.coverMask.top = (this.workspace.top || 0) + (this.workspace.height! - cHeight) / 2;
172+
this.workspace.clone((clone: fabric.Rect) => {
173+
clone.left = -clone.width! / 2;
174+
clone.top = -clone.height! / 2;
175+
clone.inverted = true;
176+
this.coverMask!.objectCaching = false;
177+
this.coverMask!.clipPath = clone;
178+
this.canvas.requestRenderAll();
179+
});
180+
}
181+
}
182+
183+
clipPath() {
184+
if (this.coverMask) {
185+
return;
186+
}
187+
// 超出画布不展示
188+
this.workspace?.clone((cloned: fabric.Rect) => {
189+
this.canvas.clipPath = cloned;
190+
this.canvas.requestRenderAll();
191+
});
192+
}
193+
194+
maskEnable(needBindLoadJSON = true) {
195+
const coverMask = new fabric.Rect({
196+
fill: 'rgba(0,0,0,0.7)',
197+
id: 'coverMask',
198+
strokeWidth: 0,
199+
});
200+
coverMask.set('selectable', false);
201+
coverMask.set('hasControls', false);
202+
coverMask.set('evented', false);
203+
coverMask.hoverCursor = 'default';
204+
this.canvas.on('object:added', () => {
205+
coverMask.bringToFront();
206+
});
207+
this.canvas.clipPath = undefined;
208+
this.canvas.add(coverMask);
209+
this.coverMask = coverMask;
210+
this.setCoverMask();
211+
// 适配模板和psd的loadjson,在加载完成后再入mask
212+
needBindLoadJSON && this.editor.on('loadJson', () => this.maskEnable(false));
213+
}
214+
151215
setZoomAuto(scale: number, cb?: (left?: number, top?: number) => void) {
152216
const { workspaceEl } = this;
153217
const width = workspaceEl.offsetWidth;
@@ -159,12 +223,8 @@ class WorkspacePlugin implements IPluginTempl {
159223
this.canvas.zoomToPoint(new fabric.Point(center.left, center.top), scale);
160224
if (!this.workspace) return;
161225
this.setCenterFromObject(this.workspace);
162-
163-
// 超出画布不展示
164-
this.workspace.clone((cloned: fabric.Rect) => {
165-
this.canvas.clipPath = cloned;
166-
this.canvas.requestRenderAll();
167-
});
226+
this.setCoverMask();
227+
this.clipPath();
168228
if (cb) cb(this.workspace.left, this.workspace.top);
169229
}
170230

@@ -212,14 +272,15 @@ class WorkspacePlugin implements IPluginTempl {
212272
}
213273

214274
_bindWheel() {
215-
this.canvas.on('mouse:wheel', function (this: fabric.Canvas, opt) {
275+
this.canvas.on('mouse:wheel', (opt) => {
216276
const delta = opt.e.deltaY;
217-
let zoom = this.getZoom();
277+
let zoom = this.canvas.getZoom();
218278
zoom *= 0.999 ** delta;
219279
if (zoom > 20) zoom = 20;
220280
if (zoom < 0.01) zoom = 0.01;
221-
const center = this.getCenter();
222-
this.zoomToPoint(new fabric.Point(center.left, center.top), zoom);
281+
const center = this.canvas.getCenter();
282+
this.canvas.zoomToPoint(new fabric.Point(center.left, center.top), zoom);
283+
this.setCoverMask();
223284
opt.e.preventDefault();
224285
opt.e.stopPropagation();
225286
});

src/views/home/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,7 @@ onMounted(() => {
391391
canvasEditor.use(ResizePlugin);
392392
canvasEditor.use(LockPlugin);
393393
canvasEditor.use(AddBaseTypePlugin);
394+
canvasEditor.getPlugin('WorkspacePlugin').maskEnable();
394395
395396
state.show = true;
396397
// 默认打开标尺

0 commit comments

Comments
 (0)