Skip to content

Commit b3f0aad

Browse files
authored
Merge pull request salgum1114#200 from salgum1114/feature/refactor
Feature/refactor
2 parents cedb4e6 + f8f5191 commit b3f0aad

31 files changed

+1634
-1344
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-design-editor",
3-
"version": "0.0.32",
3+
"version": "0.0.33",
44
"description": "Design Editor Tools with React.js + ant.design + fabric.js",
55
"main": "dist/react-design-editor.min.js",
66
"typings": "lib/index.d.ts",

src/components/canvas/Canvas.tsx

Lines changed: 40 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -2,86 +2,19 @@ import React, { Component } from 'react';
22
import { fabric } from 'fabric';
33
import { v4 } from 'uuid';
44
import ResizeObserver from 'resize-observer-polyfill';
5-
import union from 'lodash/union';
65

76
import Handler, { HandlerOptions } from './handlers/Handler';
8-
import { FabricCanvas, WorkareaObject, FabricObjectOption } from './utils';
7+
import { FabricCanvas } from './utils';
8+
import { defaults } from './constants';
99

1010
import '../../styles/core/canvas.less';
1111
import '../../styles/core/tooltip.less';
1212
import '../../styles/core/contextmenu.less';
1313
import '../../styles/fabricjs/fabricjs.less';
1414

15-
const defaultCanvasOption = {
16-
preserveObjectStacking: true,
17-
width: 300,
18-
height: 150,
19-
selection: true,
20-
defaultCursor: 'default',
21-
backgroundColor: '#f3f3f3',
22-
};
23-
24-
const defaultKeyboardEvent = {
25-
move: true,
26-
all: true,
27-
copy: true,
28-
paste: true,
29-
esc: true,
30-
del: true,
31-
clipboard: false,
32-
transaction: true,
33-
zoom: true,
34-
cut: true,
35-
};
36-
37-
const defaultGripOption = {
38-
enabled: false,
39-
grid: 10,
40-
snapToGrid: false,
41-
lineColor: '#ebebeb',
42-
borderColor: '#cccccc',
43-
};
44-
45-
const defaultWorkareaOption: Partial<WorkareaObject> = {
46-
width: 600,
47-
height: 400,
48-
workareaWidth: 600,
49-
workareaHeight: 400,
50-
lockScalingX: true,
51-
lockScalingY: true,
52-
scaleX: 1,
53-
scaleY: 1,
54-
backgroundColor: '#fff',
55-
hasBorders: false,
56-
hasControls: false,
57-
selectable: false,
58-
lockMovementX: true,
59-
lockMovementY: true,
60-
hoverCursor: 'default',
61-
name: '',
62-
id: 'workarea',
63-
type: 'image',
64-
layout: 'fixed', // fixed, responsive, fullscreen
65-
link: {},
66-
tooltip: {
67-
enabled: false,
68-
},
69-
isElement: false,
70-
};
71-
72-
const defaultObjectOption: Partial<FabricObjectOption> = {
73-
rotation: 0,
74-
centeredRotation: true,
75-
strokeUniform: true,
76-
};
77-
78-
const defaultPropertiesToInclude = ['id', 'name', 'locke', 'editable'];
79-
8015
export type CanvasProps = HandlerOptions & {
8116
responsive?: boolean;
8217
style?: React.CSSProperties;
83-
// TODO...
84-
// Ref
8518
ref?: React.RefAttributes<Handler>;
8619
};
8720

@@ -98,24 +31,9 @@ class Canvas extends Component<CanvasProps, IState> {
9831
static defaultProps: CanvasProps = {
9932
id: v4(),
10033
editable: true,
101-
canvasOption: {
102-
selection: true,
103-
},
104-
defaultOption: defaultObjectOption,
105-
activeSelection: {
106-
hasControls: true,
107-
},
108-
tooltip: null,
10934
zoomEnabled: true,
11035
minZoom: 30,
11136
maxZoom: 300,
112-
propertiesToInclude: defaultPropertiesToInclude,
113-
workareaOption: defaultWorkareaOption,
114-
gridOption: defaultGripOption,
115-
guidelineOption: {
116-
enabled: true,
117-
},
118-
keyEvent: {},
11937
responsive: true,
12038
width: 0,
12139
height: 0,
@@ -127,23 +45,9 @@ class Canvas extends Component<CanvasProps, IState> {
12745
};
12846

12947
componentDidMount() {
130-
const {
131-
editable,
132-
canvasOption,
133-
width,
134-
height,
135-
keyEvent,
136-
guidelineOption,
137-
defaultOption,
138-
responsive,
139-
propertiesToInclude,
140-
gridOption,
141-
workareaOption,
142-
...other
143-
} = this.props;
48+
const { editable, canvasOption, width, height, responsive, ...other } = this.props;
14449
const { id } = this.state;
145-
const mergedPropertiesToInclude = union(propertiesToInclude, defaultPropertiesToInclude);
146-
const mergedCanvasOption = Object.assign({}, defaultCanvasOption, canvasOption, {
50+
const mergedCanvasOption = Object.assign({}, defaults.canvasOption, canvasOption, {
14751
width,
14852
height,
14953
selection: editable,
@@ -153,18 +57,12 @@ class Canvas extends Component<CanvasProps, IState> {
15357
this.canvas.renderAll();
15458
this.handler = new Handler({
15559
id,
60+
width,
61+
height,
62+
editable,
15663
canvas: this.canvas,
15764
container: this.container.current,
158-
keyEvent: Object.assign({}, defaultKeyboardEvent, keyEvent),
15965
canvasOption: mergedCanvasOption,
160-
guidelineOption,
161-
editable,
162-
defaultOption: Object.assign({}, defaultObjectOption, defaultOption),
163-
propertiesToInclude: mergedPropertiesToInclude,
164-
gridOption: Object.assign({}, defaultGripOption, gridOption),
165-
width,
166-
height,
167-
workareaOption: Object.assign({}, defaultWorkareaOption, workareaOption),
16866
...other,
16967
});
17068
if (this.props.responsive) {
@@ -175,69 +73,52 @@ class Canvas extends Component<CanvasProps, IState> {
17573
}
17674

17775
componentDidUpdate(prevProps: CanvasProps) {
178-
if (JSON.stringify(this.props.canvasOption) !== JSON.stringify(prevProps.canvasOption)) {
179-
this.handler.canvasOption = this.props.canvasOption;
180-
this.handler.canvas.setBackgroundColor(
181-
this.props.canvasOption.backgroundColor,
182-
this.canvas.renderAll.bind(this.handler.canvas),
183-
);
184-
const {
185-
canvasOption: { width: currentWidth, height: currentHeight },
186-
} = this.props;
187-
const {
188-
canvasOption: { width: prevWidth, height: prevHeight },
189-
} = prevProps;
190-
if (!this.props.responsive && (currentWidth !== prevWidth || currentHeight !== prevHeight)) {
191-
this.handler.eventHandler.resize(currentWidth, currentHeight);
192-
}
193-
if (typeof this.props.canvasOption.selection === 'undefined') {
194-
this.canvas.selection = true;
76+
if (this.props.width !== prevProps.width || this.props.height !== prevProps.height) {
77+
this.handler.eventHandler.resize(this.props.width, this.props.height);
78+
}
79+
if (this.props.editable !== prevProps.editable) {
80+
this.handler.editable = this.props.editable;
81+
}
82+
if (this.props.responsive !== prevProps.responsive) {
83+
if (!this.props.responsive) {
84+
this.destroyObserver();
19585
} else {
196-
this.canvas.selection = this.props.canvasOption.selection;
86+
this.destroyObserver();
87+
this.createObserver();
19788
}
19889
}
199-
if (
200-
!this.props.responsive &&
201-
(this.props.width !== prevProps.width || this.props.height !== prevProps.height)
202-
) {
203-
this.handler.eventHandler.resize(this.props.width, this.props.height);
90+
if (JSON.stringify(this.props.canvasOption) !== JSON.stringify(prevProps.canvasOption)) {
91+
this.handler.setCanvasOption(this.props.canvasOption);
20492
}
20593
if (JSON.stringify(this.props.keyEvent) !== JSON.stringify(prevProps.keyEvent)) {
206-
this.handler.keyEvent = Object.assign({}, defaultKeyboardEvent, this.props.keyEvent);
94+
this.handler.setKeyEvent(this.props.keyEvent);
20795
}
20896
if (JSON.stringify(this.props.fabricObjects) !== JSON.stringify(prevProps.fabricObjects)) {
209-
this.handler.fabricObjects = Object.assign({}, this.handler.fabricObjects, this.props.fabricObjects);
97+
this.handler.setFabricObjects(this.props.fabricObjects);
21098
}
21199
if (JSON.stringify(this.props.workareaOption) !== JSON.stringify(prevProps.workareaOption)) {
212-
this.handler.workarea.set({
213-
...this.props.workareaOption,
214-
});
100+
this.handler.setWorkareaOption(this.props.workareaOption);
215101
}
216102
if (JSON.stringify(this.props.guidelineOption) !== JSON.stringify(prevProps.guidelineOption)) {
217-
if (this.props.guidelineOption.enabled) {
218-
this.canvas.on({
219-
'before:render': this.handler.eventHandler.beforeRender,
220-
'after:render': this.handler.eventHandler.afterRender,
221-
});
222-
} else {
223-
this.canvas.off({
224-
'before:render': this.handler.eventHandler.beforeRender,
225-
'after:render': this.handler.eventHandler.afterRender,
226-
});
227-
}
103+
this.handler.setGuidelineOption(this.props.guidelineOption);
104+
}
105+
if (JSON.stringify(this.props.objectOption) !== JSON.stringify(prevProps.objectOption)) {
106+
this.handler.setObjectOption(this.props.objectOption);
107+
}
108+
if (JSON.stringify(this.props.gridOption) !== JSON.stringify(prevProps.gridOption)) {
109+
this.handler.setGridOption(this.props.gridOption);
110+
}
111+
if (JSON.stringify(this.props.propertiesToInclude) !== JSON.stringify(prevProps.propertiesToInclude)) {
112+
this.handler.setPropertiesToInclude(this.props.propertiesToInclude);
113+
}
114+
if (JSON.stringify(this.props.activeSelectionOption) !== JSON.stringify(prevProps.activeSelectionOption)) {
115+
this.handler.setActiveSelectionOption(this.props.activeSelectionOption);
228116
}
229117
}
230118

231119
componentWillUnmount() {
232-
this.handler.eventHandler.detachEventListener();
233-
this.cancelObserver();
234-
this.handler.clear(true);
235-
if (this.handler.tooltipHandler.tooltipEl) {
236-
document.body.removeChild(this.handler.tooltipHandler.tooltipEl);
237-
}
238-
if (this.handler.contextmenuHandler.contextmenuEl) {
239-
document.body.removeChild(this.handler.contextmenuHandler.contextmenuEl);
240-
}
120+
this.destroyObserver();
121+
this.handler.destroy();
241122
}
242123

243124
createObserver = () => {
@@ -251,9 +132,10 @@ class Canvas extends Component<CanvasProps, IState> {
251132
this.resizeObserver.observe(this.container.current);
252133
};
253134

254-
cancelObserver = () => {
135+
destroyObserver = () => {
255136
if (this.resizeObserver) {
256137
this.resizeObserver.disconnect();
138+
this.resizeObserver = null;
257139
}
258140
};
259141

src/components/canvas/CanvasObject.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
} from './objects';
1717
import { FabricObject } from './utils';
1818
import { Code } from './objects/Element';
19+
import Svg, { SvgOption } from './objects/Svg';
1920

2021
export interface ObjectSchema {
2122
create: (...option: any) => fabric.Object;
@@ -116,6 +117,9 @@ const CanvasObject: CanvasObjectSchema = {
116117
create: (fromNode, fromPort, toNode, toPort, option) =>
117118
new OrthogonalLink(fromNode, fromPort, toNode, toPort, option),
118119
},
120+
svg: {
121+
create: (option: SvgOption) => new Svg(option),
122+
},
119123
};
120124

121125
export default CanvasObject;
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { WorkareaObject, FabricObjectOption } from '../utils';
2+
3+
export const canvasOption = {
4+
preserveObjectStacking: true,
5+
width: 300,
6+
height: 150,
7+
selection: true,
8+
defaultCursor: 'default',
9+
backgroundColor: '#f3f3f3',
10+
};
11+
12+
export const keyEvent = {
13+
move: true,
14+
all: true,
15+
copy: true,
16+
paste: true,
17+
esc: true,
18+
del: true,
19+
clipboard: false,
20+
transaction: true,
21+
zoom: true,
22+
cut: true,
23+
};
24+
25+
export const gridOption = {
26+
enabled: false,
27+
grid: 10,
28+
snapToGrid: false,
29+
lineColor: '#ebebeb',
30+
borderColor: '#cccccc',
31+
};
32+
33+
export const workareaOption: Partial<WorkareaObject> = {
34+
width: 600,
35+
height: 400,
36+
workareaWidth: 600,
37+
workareaHeight: 400,
38+
lockScalingX: true,
39+
lockScalingY: true,
40+
scaleX: 1,
41+
scaleY: 1,
42+
backgroundColor: '#fff',
43+
hasBorders: false,
44+
hasControls: false,
45+
selectable: false,
46+
lockMovementX: true,
47+
lockMovementY: true,
48+
hoverCursor: 'default',
49+
name: '',
50+
id: 'workarea',
51+
type: 'image',
52+
layout: 'fixed', // fixed, responsive, fullscreen
53+
link: {},
54+
tooltip: {
55+
enabled: false,
56+
},
57+
isElement: false,
58+
};
59+
60+
export const objectOption: Partial<FabricObjectOption> = {
61+
rotation: 0,
62+
centeredRotation: true,
63+
strokeUniform: true,
64+
};
65+
66+
export const guidelineOption = {
67+
enabled: true,
68+
};
69+
70+
export const activeSelectionOption = {
71+
hasControls: true,
72+
};
73+
74+
export const propertiesToInclude = ['id', 'name', 'locked', 'editable'];
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import * as defaults from './defaults';
2+
3+
export { defaults };

src/components/canvas/global.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ declare module 'fabric/fabric-impl' {
1818
class CurvedLink {}
1919
class OrthogonalLink {}
2020
class Cube {}
21+
// SVG
22+
class Svg {}
2123
}
2224

2325
declare global {

0 commit comments

Comments
 (0)