Skip to content

Commit 565c7f7

Browse files
committed
[#164] Code refactoring
1 parent 2f6269f commit 565c7f7

22 files changed

+1002
-852
lines changed

package.json

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-design-editor",
3-
"version": "0.0.31",
3+
"version": "0.0.32",
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",
@@ -43,9 +43,7 @@
4343
"fabric": "^3.4.0",
4444
"react": "^16.4.1",
4545
"react-dom": "^16.4.1",
46-
"react-dom-factories": "^1.0.2",
47-
"@types/fabric": "^3.0.1",
48-
"@types/animejs": "^3.1.0"
46+
"react-dom-factories": "^1.0.2"
4947
},
5048
"dependencies": {
5149
"animejs": "^3.0.0",
@@ -55,6 +53,7 @@
5553
"echarts": "^4.7.0",
5654
"fabric": "^3.6.3",
5755
"gifler": "^0.1.0",
56+
"honeycomb-grid": "^3.1.7",
5857
"i18next": "^19.0.0",
5958
"i18next-browser-languagedetector": "^2.2.4",
6059
"lodash": "^4.17.10",

src/components/canvas/Canvas.tsx

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import ResizeObserver from 'resize-observer-polyfill';
55
import union from 'lodash/union';
66

77
import Handler, { HandlerOptions } from './handlers/Handler';
8-
import { FabricCanvas } from './utils';
8+
import { FabricCanvas, WorkareaObject } from './utils';
99

1010
import '../../styles/core/canvas.less';
1111
import '../../styles/core/tooltip.less';
@@ -42,6 +42,33 @@ const defaultGripOption = {
4242
borderColor: '#cccccc',
4343
};
4444

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+
4572
const defaultPropertiesToInclude = ['id', 'name', 'locke', 'editable'];
4673

4774
export type CanvasProps = HandlerOptions & {
@@ -52,7 +79,12 @@ export type CanvasProps = HandlerOptions & {
5279
ref?: React.RefAttributes<Handler>;
5380
};
5481

55-
class Canvas extends Component<CanvasProps> {
82+
interface IState {
83+
id: string;
84+
loaded: boolean;
85+
}
86+
87+
class Canvas extends Component<CanvasProps, IState> {
5688
public handler: Handler;
5789
public canvas: FabricCanvas;
5890
public container = React.createRef<HTMLDivElement>();
@@ -72,17 +104,20 @@ class Canvas extends Component<CanvasProps> {
72104
minZoom: 30,
73105
maxZoom: 300,
74106
propertiesToInclude: defaultPropertiesToInclude,
75-
workareaOption: {},
107+
workareaOption: defaultWorkareaOption,
76108
gridOption: defaultGripOption,
77109
guidelineOption: {
78110
enabled: true,
79111
},
80112
keyEvent: {},
81113
responsive: true,
114+
width: 0,
115+
height: 0,
82116
};
83117

84-
state = {
118+
state: IState = {
85119
id: v4(),
120+
loaded: false,
86121
};
87122

88123
componentDidMount() {
@@ -97,12 +132,10 @@ class Canvas extends Component<CanvasProps> {
97132
responsive,
98133
propertiesToInclude,
99134
gridOption,
135+
workareaOption,
100136
...other
101137
} = this.props;
102138
const { id } = this.state;
103-
if (responsive) {
104-
this.createObserver();
105-
}
106139
const mergedPropertiesToInclude = union(propertiesToInclude, defaultPropertiesToInclude);
107140
const mergedCanvasOption = Object.assign({}, defaultCanvasOption, canvasOption, {
108141
width,
@@ -123,17 +156,16 @@ class Canvas extends Component<CanvasProps> {
123156
defaultOption,
124157
propertiesToInclude: mergedPropertiesToInclude,
125158
gridOption: Object.assign({}, defaultGripOption, gridOption),
159+
width,
160+
height,
161+
workareaOption: Object.assign({}, defaultWorkareaOption, workareaOption),
126162
...other,
127163
});
128-
this.handler.gridHandler.init();
129-
if (editable) {
130-
this.handler.transactionHandler.init();
131-
this.handler.interactionHandler.selection();
132-
if (guidelineOption.enabled) {
133-
this.handler.guidelineHandler.init();
134-
}
164+
if (this.props.responsive) {
165+
this.createObserver();
166+
} else {
167+
this.handleLoad();
135168
}
136-
this.handler.eventHandler.attachEventListener();
137169
}
138170

139171
componentDidUpdate(prevProps: CanvasProps) {
@@ -206,6 +238,9 @@ class Canvas extends Component<CanvasProps> {
206238
this.resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {
207239
const { width = 0, height = 0 } = (entries[0] && entries[0].contentRect) || {};
208240
this.handler.eventHandler.resize(width, height);
241+
if (!this.state.loaded) {
242+
this.handleLoad();
243+
}
209244
});
210245
this.resizeObserver.observe(this.container.current);
211246
};
@@ -216,6 +251,15 @@ class Canvas extends Component<CanvasProps> {
216251
}
217252
};
218253

254+
handleLoad = () => {
255+
if (this.props.onLoad) {
256+
this.props.onLoad(this.handler, this.canvas);
257+
}
258+
this.setState({
259+
loaded: true,
260+
});
261+
};
262+
219263
render() {
220264
const { style } = this.props;
221265
const { id } = this.state;

src/components/canvas/handlers/EventHandler.ts

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ class EventHandler {
1515
handler: Handler;
1616
keyCode: number;
1717
panning: boolean;
18+
1819
constructor(handler: Handler) {
1920
this.handler = handler;
21+
this.attachEventListener();
2022
}
2123

2224
/**
@@ -600,8 +602,8 @@ class EventHandler {
600602
if (this.handler.gridOption.enabled) {
601603
return;
602604
}
603-
this.handler.canvas.getObjects().forEach((obj: any, index) => {
604-
if (index !== 0) {
605+
this.handler.canvas.getObjects().forEach((obj: FabricObject) => {
606+
if (obj.id !== 'workarea') {
605607
const left = obj.left + diffWidth;
606608
const top = obj.top + diffHeight;
607609
obj.set({
@@ -617,29 +619,19 @@ class EventHandler {
617619
}
618620
}
619621
});
620-
this.handler.canvas.renderAll();
622+
this.handler.canvas.requestRenderAll();
621623
return;
622624
}
623-
let scaleX = nextWidth / this.handler.workarea.width;
624-
const scaleY = nextHeight / this.handler.workarea.height;
625625
if (this.handler.workarea.layout === 'responsive') {
626-
if (this.handler.workarea.height > this.handler.workarea.width) {
627-
scaleX = scaleY;
628-
if (nextWidth < this.handler.workarea.width * scaleX) {
629-
scaleX = scaleX * (nextWidth / (this.handler.workarea.width * scaleX));
630-
}
631-
} else {
632-
if (nextHeight < this.handler.workarea.height * scaleX) {
633-
scaleX = scaleX * (nextHeight / (this.handler.workarea.height * scaleX));
634-
}
635-
}
626+
const { scaleX } = this.handler.workareaHandler.calculateScale();
627+
const center = this.handler.canvas.getCenter();
636628
const deltaPoint = new fabric.Point(diffWidth, diffHeight);
637629
this.handler.canvas.relativePan(deltaPoint);
638-
const center = this.handler.canvas.getCenter();
639630
this.handler.zoomHandler.zoomToPoint(new fabric.Point(center.left, center.top), scaleX);
640-
this.handler.canvas.renderAll();
641631
return;
642632
}
633+
const scaleX = nextWidth / this.handler.workarea.width;
634+
const scaleY = nextHeight / this.handler.workarea.height;
643635
const diffScaleX = nextWidth / (this.handler.workarea.width * this.handler.workarea.scaleX);
644636
const diffScaleY = nextHeight / (this.handler.workarea.height * this.handler.workarea.scaleY);
645637
this.handler.workarea.set({

src/components/canvas/handlers/GridHandler.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ class GridHandler {
99

1010
constructor(handler: Handler) {
1111
this.handler = handler;
12+
this.init();
1213
}
1314

1415
/**

src/components/canvas/handlers/GuidelineHandler.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ class GuidelineHandler {
1818

1919
constructor(handler: Handler) {
2020
this.handler = handler;
21+
if (this.handler.editable && this.handler.guidelineOption.enabled) {
22+
this.init();
23+
}
2124
}
2225

2326
init = () => {

src/components/canvas/handlers/Handler.ts

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -292,9 +292,6 @@ class Handler implements HandlerOptions {
292292
this.init(options);
293293
this.initCallback(options);
294294
this.initHandler(options);
295-
if (this.onLoad) {
296-
this.onLoad(this, this.canvas);
297-
}
298295
}
299296

300297
/**
@@ -348,6 +345,7 @@ class Handler implements HandlerOptions {
348345
* @param {HandlerOptions} options
349346
*/
350347
public initHandler = (_options: HandlerOptions) => {
348+
this.workareaHandler = new WorkareaHandler(this);
351349
this.imageHandler = new ImageHandler(this);
352350
this.chartHandler = new ChartHandler(this);
353351
this.elementHandler = new ElementHandler(this);
@@ -356,7 +354,6 @@ class Handler implements HandlerOptions {
356354
this.contextmenuHandler = new ContextmenuHandler(this);
357355
this.tooltipHandler = new TooltipHandler(this);
358356
this.zoomHandler = new ZoomHandler(this);
359-
this.workareaHandler = new WorkareaHandler(this);
360357
this.interactionHandler = new InteractionHandler(this);
361358
this.transactionHandler = new TransactionHandler(this);
362359
this.gridHandler = new GridHandler(this);
@@ -580,7 +577,7 @@ class Handler implements HandlerOptions {
580577
* @param {(File | string)} [source]
581578
* @returns
582579
*/
583-
public setImage = (obj: FabricImage, source?: File | string) => {
580+
public setImage = (obj: FabricImage, source?: File | string) => {
584581
if (!source) {
585582
this.loadImage(obj, null);
586583
obj.set('file', null);
@@ -707,7 +704,9 @@ class Handler implements HandlerOptions {
707704
if (obj.type === 'image') {
708705
createdObj = this.addImage(newOption);
709706
} else if (obj.type === 'group') {
710-
const objects = this.addGroup(newOption, centered, loaded);
707+
// TODO...
708+
// Group add function needs to be fixed
709+
const objects = this.addGroup(newOption, centered, loaded, transaction);
711710
const groupOption = Object.assign({}, newOption, { objects, name: 'New Group' });
712711
createdObj = this.fabricObjects[obj.type].create(groupOption);
713712
} else {
@@ -762,9 +761,9 @@ class Handler implements HandlerOptions {
762761
* @param {boolean} [loaded=false]
763762
* @returns
764763
*/
765-
public addGroup = (obj: FabricGroup, centered = true, loaded = false) => {
764+
public addGroup = (obj: FabricGroup, centered = true, loaded = false, transaction = true) => {
766765
return obj.objects.map(child => {
767-
return this.add(child, centered, loaded);
766+
return this.add(child, centered, loaded, transaction);
768767
});
769768
};
770769

@@ -1535,7 +1534,7 @@ class Handler implements HandlerOptions {
15351534
* @param {*} json
15361535
* @param {(canvas: FabricCanvas) => void} [callback]
15371536
*/
1538-
public importJSON = (json: any, callback?: (canvas: FabricCanvas) => void) => {
1537+
public importJSON = async (json: any, callback?: (canvas: FabricCanvas) => void) => {
15391538
if (typeof json === 'string') {
15401539
json = JSON.parse(json);
15411540
}
@@ -1556,42 +1555,39 @@ class Handler implements HandlerOptions {
15561555
prevLeft = workarea.left;
15571556
prevTop = workarea.top;
15581557
this.workarea.set(workarea);
1559-
this.canvas.centerObject(this.workarea);
1560-
this.workareaHandler.setImage(workarea.src, true);
1558+
await this.workareaHandler.setImage(workarea.src, true);
15611559
this.workarea.setCoords();
15621560
}
1563-
setTimeout(() => {
1564-
json.forEach((obj: FabricObjectOption) => {
1565-
if (obj.id === 'workarea') {
1566-
return;
1567-
}
1568-
const canvasWidth = this.canvas.getWidth();
1569-
const canvasHeight = this.canvas.getHeight();
1570-
const { width, height, scaleX, scaleY, layout, left, top } = this.workarea;
1571-
if (layout === 'fullscreen') {
1572-
const leftRatio = canvasWidth / (width * scaleX);
1573-
const topRatio = canvasHeight / (height * scaleY);
1574-
obj.left *= leftRatio;
1575-
obj.top *= topRatio;
1576-
obj.scaleX *= leftRatio;
1577-
obj.scaleY *= topRatio;
1578-
} else {
1579-
const diffLeft = left - prevLeft;
1580-
const diffTop = top - prevTop;
1581-
obj.left += diffLeft;
1582-
obj.top += diffTop;
1583-
}
1584-
if (obj.superType === 'element') {
1585-
obj.id = v4();
1586-
}
1587-
this.add(obj, false, true, false);
1588-
this.canvas.renderAll();
1589-
});
1590-
if (callback) {
1591-
callback(this.canvas);
1561+
json.forEach((obj: FabricObjectOption) => {
1562+
if (obj.id === 'workarea') {
1563+
return;
1564+
}
1565+
const canvasWidth = this.canvas.getWidth();
1566+
const canvasHeight = this.canvas.getHeight();
1567+
const { width, height, scaleX, scaleY, layout, left, top } = this.workarea;
1568+
if (layout === 'fullscreen') {
1569+
const leftRatio = canvasWidth / (width * scaleX);
1570+
const topRatio = canvasHeight / (height * scaleY);
1571+
obj.left *= leftRatio;
1572+
obj.top *= topRatio;
1573+
obj.scaleX *= leftRatio;
1574+
obj.scaleY *= topRatio;
1575+
} else {
1576+
const diffLeft = left - prevLeft;
1577+
const diffTop = top - prevTop;
1578+
obj.left += diffLeft;
1579+
obj.top += diffTop;
1580+
}
1581+
if (obj.superType === 'element') {
1582+
obj.id = v4();
15921583
}
1593-
}, 300);
1594-
this.canvas.setZoom(1);
1584+
this.add(obj, false, true, false);
1585+
this.canvas.renderAll();
1586+
});
1587+
if (callback) {
1588+
callback(this.canvas);
1589+
}
1590+
return Promise.resolve(this.canvas);
15951591
};
15961592

15971593
/**

src/components/canvas/handlers/InteractionHandler.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ class InteractionHandler {
99
handler: Handler;
1010
constructor(handler: Handler) {
1111
this.handler = handler;
12+
if (this.handler.editable) {
13+
this.selection();
14+
}
1215
}
1316

1417
/**

0 commit comments

Comments
 (0)