From 62cd098bdda1921e4527c2df4bd03237f89be15c Mon Sep 17 00:00:00 2001
From: ival <610568032@qq.com>
Date: Wed, 31 Mar 2021 18:13:58 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/iscs_new/config/defaultState.js | 3 +
src/iscs_new/controller.js | 8 ++-
src/iscs_new/core/abstractShape.js | 9 ++-
src/iscs_new/core/form/form2Base.js | 3 +
src/iscs_new/core/form/formBuilder.js | 2 +-
src/iscs_new/draggable/Image.js | 4 +-
src/iscs_new/factory/compose.js | 42 ++++++++++----
src/iscs_new/factory/element.js | 25 +++++++-
src/iscs_new/factory/index.js | 82 ++++++++++++++-------------
src/iscs_new/map.js | 64 ++++++++++-----------
src/iscs_new/painter.js | 20 +++----
src/iscs_new/selectHandle.js | 20 ++-----
src/iscs_new/selectingHandle.js | 14 +++--
src/iscs_new/utils/orders.js | 7 +++
src/views/test/index.vue | 22 ++++++-
15 files changed, 202 insertions(+), 123 deletions(-)
create mode 100644 src/iscs_new/config/defaultState.js
create mode 100644 src/iscs_new/utils/orders.js
diff --git a/src/iscs_new/config/defaultState.js b/src/iscs_new/config/defaultState.js
new file mode 100644
index 000000000..03048022a
--- /dev/null
+++ b/src/iscs_new/config/defaultState.js
@@ -0,0 +1,3 @@
+export default {
+
+}
diff --git a/src/iscs_new/controller.js b/src/iscs_new/controller.js
index 788200e12..66fdedb23 100644
--- a/src/iscs_new/controller.js
+++ b/src/iscs_new/controller.js
@@ -253,7 +253,7 @@ export default class Controller extends Eventful {
this.setCursorStyle('auto');
}
- // this._locking = false; 设置false时,拖动完成后,需要重新激活
+ // this.setLocking(false); 设置false时,拖动完成后,需要重新激活
this._target = null;
}
@@ -286,7 +286,7 @@ export default class Controller extends Eventful {
click(e) {
const event = new MouseEvent(e);
if (event.code) {
- this._locking = true;
+ this.setLocking(true)
} else {
this.selectHandle.clear();
this.selectingHandle.clear();
@@ -340,6 +340,10 @@ export default class Controller extends Eventful {
this._locking = false;
}
+ setLocking(lock=false) {
+ this._locking = lock;
+ }
+
destroy () {
this.dispose();
}
diff --git a/src/iscs_new/core/abstractShape.js b/src/iscs_new/core/abstractShape.js
index de0c1afcb..77b0f4a5b 100644
--- a/src/iscs_new/core/abstractShape.js
+++ b/src/iscs_new/core/abstractShape.js
@@ -2,10 +2,9 @@ import shapeType from '../constant/shapeType';
// 图形抽象层
class AbstractShape {
- constructor({model, defaultStyle, option, shapeFactory}) {
+ constructor({model, option, shapeFactory}) {
this.model = model;
this.option = option;
- this.defaultStyle = defaultStyle;
this.shapeFactory = shapeFactory;
}
@@ -30,6 +29,12 @@ class AbstractShape {
// 销毁图形
destroy() {}
+
+ // 获取包围框
+ getBoundingRect() {}
+
+ // 获取依赖图形
+ getDepShapes() {}
}
export default AbstractShape;
diff --git a/src/iscs_new/core/form/form2Base.js b/src/iscs_new/core/form/form2Base.js
index d19b1d533..404c257b2 100644
--- a/src/iscs_new/core/form/form2Base.js
+++ b/src/iscs_new/core/form/form2Base.js
@@ -6,6 +6,9 @@ export default {
// number 0 控制图形的前后顺序。z2 值小的图形会被 z2 值大的图形覆盖。z2 相比 z1 优先级更低,而且不会创建新的 Canvas。
z2: {
prop: 'z', label: '层级 z2', type: 'select', defValue: 10,
+ },
+ name: {
+
},
// boolean false 是否进行裁剪。
culling: {
diff --git a/src/iscs_new/core/form/formBuilder.js b/src/iscs_new/core/form/formBuilder.js
index 1aff3c1f1..7b9da0b1c 100644
--- a/src/iscs_new/core/form/formBuilder.js
+++ b/src/iscs_new/core/form/formBuilder.js
@@ -34,4 +34,4 @@ class FormBuilder {
}
}
-export default formBuilder;
+export default FormBuilder;
diff --git a/src/iscs_new/draggable/Image.js b/src/iscs_new/draggable/Image.js
index e917c3cce..840e4cfd8 100644
--- a/src/iscs_new/draggable/Image.js
+++ b/src/iscs_new/draggable/Image.js
@@ -96,7 +96,7 @@ export default class ImageDraggable extends graphic.Group {
this.handle.e.target &&
this.offset) {
if (!eventTool.isMiddleOrRightButtonOnMouseUpDown(e)) {
- const type = this.handle.e.target.model._type;
+ const type = this.handle.e.target.model.type;
const dx = Math.round(e.offsetX-this.offset.x);
const dy = Math.round(e.offsetY-this.offset.y);
@@ -112,7 +112,7 @@ export default class ImageDraggable extends graphic.Group {
if (this.target &&
this.handle.e.target &&
this.offset) {
- const type = this.handle.e.target.model._type;
+ const type = this.handle.e.target.model.type;
const dx = Math.round(e.offsetX-this.offset.x);
const dy = Math.round(e.offsetY-this.offset.y);
this.setShape(...this.handle.normalizedDiff(dx, dy));
diff --git a/src/iscs_new/factory/compose.js b/src/iscs_new/factory/compose.js
index bb7cb0a1e..8f97e054a 100644
--- a/src/iscs_new/factory/compose.js
+++ b/src/iscs_new/factory/compose.js
@@ -19,15 +19,7 @@ class Compose extends AbstractShape {
// 设置高亮
active() {
- let unionRect = null;
- this.model.elementCodes.forEach(code => {
- const element = this.shapeFactory.getShapeByCode(code)
- if (element && element.instance && !element.instance.invisible) {
- const rect = element.instance.getBoundingRect().clone();
- unionRect ? unionRect.union(rect): (unionRect = rect);
- }
- })
-
+ const unionRect = this.getBoundingRect();
if (unionRect) {
this.shapeFactory.trigger(shapeEvent.ShowHightLight, unionRect);
}
@@ -35,7 +27,7 @@ class Compose extends AbstractShape {
// 取消高亮
inactive() {
- this.shapeFactory.trigger(shapeEvent.HideHightLight, new BoundingRect(0,0,0,0));
+ this.shapeFactory.trigger(shapeEvent.HideHightLight);
}
// 设置获取焦点
@@ -50,7 +42,35 @@ class Compose extends AbstractShape {
setState(state) {}
// 销毁图形
- destroy() {}
+ destroy() {
+ this.model.elementCodes.forEach(code => {
+ const element = this.shapeFactory.getShapeByCode(code);
+ if (element &&
+ element.model) {
+ element.model.composeCode = '';
+ element.instance.attr(element.model)
+ }
+ })
+ this.model.elementCodes = [];
+ }
+
+ // 获取依赖图形
+ getDepShapes() {
+ return this.model.elementCodes.map(code => this.shapeFactory.getShapeByCode(code)).filter(el => el)
+ }
+
+ // 获取包围框
+ getBoundingRect() {
+ let unionRect = null;
+ this.model.elementCodes.forEach(code => {
+ const element = this.shapeFactory.getShapeByCode(code)
+ if (element && element.instance && !element.instance.invisible) {
+ const rect = element.instance.getBoundingRect().clone();
+ unionRect ? unionRect.union(rect): (unionRect = rect);
+ }
+ })
+ return unionRect;
+ }
}
export default Compose;
diff --git a/src/iscs_new/factory/element.js b/src/iscs_new/factory/element.js
index d915a7bb8..235016eeb 100644
--- a/src/iscs_new/factory/element.js
+++ b/src/iscs_new/factory/element.js
@@ -82,7 +82,7 @@ class Element extends AbstractShape {
// 取消高亮
inactive() {
- this.shapeFactory.trigger(shapeEvent.HideHightLight, this.instance.getBoundingRect());
+ this.shapeFactory.trigger(shapeEvent.HideHightLight);
}
// 设置获取焦点
@@ -97,7 +97,28 @@ class Element extends AbstractShape {
setState(state) {}
// 销毁图形
- destroy() {}
+ destroy() {
+ const compose = this.shapeFactory.getShapeByCode(this.model.composeCode);
+ if (compose &&
+ compose.model &&
+ compose.model.elementCodes) {
+ const index = compose.model.elementCodes.findIndex(this.model.code);
+ if (index >= 0) {
+ compose.model.elementCodes.splice(index, 1);
+ }
+ }
+ }
+
+ // 获取依赖图形
+ getDepShapes() {
+ return []
+ }
+
+
+ // 获取包围框
+ getBoundingRect() {
+ return this.instance.getBoundingRect();
+ }
}
export default Element;
diff --git a/src/iscs_new/factory/index.js b/src/iscs_new/factory/index.js
index c0cbefaa4..e015f6407 100644
--- a/src/iscs_new/factory/index.js
+++ b/src/iscs_new/factory/index.js
@@ -7,6 +7,7 @@ import Element from './element';
import shapeType from '../constant/shapeType';
import shapeRender from '../constant/shapeRender';
import shapeEvent from '../constant/shapeEvent';
+import orders from '../utils/orders';
const None = e => null;
const shapeBuilderMap = {
@@ -14,6 +15,28 @@ const shapeBuilderMap = {
[shapeType.Compose]: Compose
}
+function update2List(source, model, action, name='') {
+ const list = source[name];
+
+ if (!list) { source[name] = []; }
+
+ let updateModel = model;
+ const i = list.findIndex(elem => { return elem.code == model.code; })
+ switch(action.order) {
+ case orders.ADD:
+ list.push(model);
+ break;
+ case orders.UNBINDING:
+ case orders.DELETE:
+ i >= 0 && list.splice(i, 1);
+ break;
+ case orders.UPDATE:
+ Object.assign(list[i]||{}, model)
+ break;
+ }
+
+ return updateModel;
+}
class ShapeFactory extends Eventful {
constructor(map) {
super();
@@ -53,30 +76,21 @@ class ShapeFactory extends Eventful {
return this;
}
- parse(source={}, defaultStyle={}, walk=None) {
+ parse(source={}, walk=None) {
try {
this.source = source;
- zrUtil.each(source.elementList ||[], el => {
- walk(this.storageShape(this.createShape(el, defaultStyle, {...shapeRender, _type: shapeType.Element})));
+ zrUtil.each(source.elementList ||[], model => {
+ walk(this.storageShape(this.createShape(model, {...shapeRender, shapeType: shapeType.Element})));
}, this);
- zrUtil.each(source.composeList ||[], el => {
- this.storageShape(this.createShape(el, defaultStyle, {...shapeRender, _type: shapeType.Compose}));
+ zrUtil.each(source.composeList ||[], model => {
+ this.storageShape(this.createShape(model, {...shapeRender, shapeType: shapeType.Compose}));
}, this);
} catch (error) {
console.error('[ERROR] ', error);
}
}
- createShape(model={}, defaultStyle={}, option={}) {
- let shape = null;
- const shapeBuilder = shapeBuilderMap[option._type];
- if (shapeBuilder) {
- shape = new shapeBuilder({model, defaultStyle, option, shapeFactory: this});
- }
- return shape;
- }
-
storageShape(shape) {
if (shape && shape.model) {
this.mapShape[shape.model.code] = shape;
@@ -84,42 +98,32 @@ class ShapeFactory extends Eventful {
return shape;
}
+ createShape(model={}, option={}) {
+ let shape = null;
+ const shapeBuilder = shapeBuilderMap[option.shapeType];
+ if (shapeBuilder) {
+ shape = new shapeBuilder({model, option, shapeFactory: this});
+ }
+ return shape;
+ }
+
removeShape(shape) {
if (shape && shape.model) {
+ this.trigger(shapeEvent.HideHightLight);
+ shape.destroy();
delete this.mapShape[shape.model.code];
}
return shape;
}
- updateSource(model={}) {
- switch (model._type) {
- case shapeType.Compose: return { model: update2List(model, 'composeList'), option: {...shapeRender, _type: shapeType.Compose}};
- case shapeType.Element: return { model: update2List(model, 'elementList'), option: {...shapeRender, _type: shapeType.Element}};
+ updateSource(model={}, action={}) {
+ switch (action.shapeType) {
+ case shapeType.Compose: return update2List(this.source, model, action, 'composeList');
+ case shapeType.Element: return update2List(this.source, model, action, 'elementList');
}
return null;
}
- update2List(model={}, name='') {
- const list = this.source[name];
- const dispose = model._dispose;
- const entries = Object.entries(model).filter(el => !['_type', '_dispose'].includes(el[0]));
- const cleanModel = Object.fromEntries(entries);
- let retModel = cleanModel;
-
- if (list && list instanceof Array) {
- const i = list.findIndex(elem => { return elem.code == model.code; });
- if (i < 0) {
- list.push(cleanModel)
- } else {
- retModel = dispose ? list.splice(i, 1) : Object.assign(list[i], cleanModel);
- }
- } else {
- source[name] = [cleanModel];
- }
-
- return retModel;
- }
-
getSource() {
return this.source;
}
diff --git a/src/iscs_new/map.js b/src/iscs_new/map.js
index 0d105ee73..6908c3d38 100644
--- a/src/iscs_new/map.js
+++ b/src/iscs_new/map.js
@@ -8,7 +8,9 @@ import Option from './option';
import Controller from './controller';
import StateHandle from './stateHandle';
import ShapeFactory from './factory';
-import defaultStyle from './config/defaultStyle';
+import orders from './utils/orders';
+import shapeRender from './constant/shapeRender';
+import shapeType from './constant/shapeType';
const renderer = 'canvas';
const devicePixelRatio = 1;
@@ -31,12 +33,6 @@ class JMap {
__Keydown: '__keydown__'
};
- // 默认状态
- this.defaultState = this.loadDefaultState();
-
- // 默认皮肤
- this.defaultStyle = this.loadDefaultStyle();
-
// 初始化Map实例
this.initMapInstance(opts);
}
@@ -75,14 +71,6 @@ class JMap {
};
}
- loadDefaultState(state) {
- return {};
- }
-
- loadDefaultStyle(style) {
- return defaultStyle;
- }
-
setMap(templates=[], source={}, eventOpts={}) {
// 绑定事件
this.$controller.enable(eventOpts);
@@ -154,7 +142,7 @@ class JMap {
repaint(source={}) {
this.$shapeFactory.clear();
this.$painter.clear();
- this.$shapeFactory.parse(source, this.defaultStyle, shape => {
+ this.$shapeFactory.parse(source, shape => {
if (shape) {
this.$painter.add(shape);
}
@@ -162,19 +150,35 @@ class JMap {
}
render(list=[]) {
- list.forEach(el => {
- const dispose = el._dispose;
- const oldShape = this.$shapeFactory.getShapeByCode(el.code);
- const block = this.$shapeFactory.updateSource(el);
+ list.forEach(({model, action}) => {
+ const updateModel = this.$shapeFactory.updateSource(model, action);
+ const shape = this.$shapeFactory.getShapeByCode(updateModel.code);
+ const deps = shape.getDepShapes();
+ const oldShape = this.$shapeFactory.removeShape(shape);
+ const newShape = this.$shapeFactory.createShape(updateModel, {...shapeRender, ...action});
- if (dispose) {
- this.$painter.remove(oldShape);
- this.$shapeFactory.removeShape(oldShape);
- } else if (block) {
- const createShape = this.$shapeFactory.createShape(block.model, block.option);
- this.$painter.remove(oldShape);
- this.$shapeFactory.storageShape(createShape)
- this.$painter.add(createShape);
+ if (updateModel) {
+ switch(action.order) {
+ case orders.ADD:
+ this.$shapeFactory.storageShape(newShape)
+ this.$painter.add(newShape);
+ break;
+ case orders.DELETE:
+ this.$painter.remove(oldShape);
+ deps.forEach(shape => {
+ this.$shapeFactory.updateSource(shape.model, {...action, shapeType: shapeType.Element});
+ this.$painter.remove(shape);
+ });
+ break;
+ case orders.UPDATE:
+ this.$painter.remove(oldShape);
+ this.$shapeFactory.storageShape(newShape)
+ this.$painter.add(newShape);
+ break;
+ case orders.UNBINDING:
+ this.$painter.remove(oldShape);
+ break;
+ }
}
});
@@ -228,10 +232,6 @@ class JMap {
return this.defaultState;
}
- getDefaultStyle() {
- return this.defaultStyle;
- }
-
getShapeByCode(code) {
return this.$shapeFactory.getShapeByCode(code);
}
diff --git a/src/iscs_new/painter.js b/src/iscs_new/painter.js
index 09e2e03eb..ac067a625 100644
--- a/src/iscs_new/painter.js
+++ b/src/iscs_new/painter.js
@@ -47,28 +47,26 @@ class Painter extends Group {
}
add(shape) {
- try {
+ if (shape && shape.model) {
const shapeLevel = this.mapShapeLevel[shape.model.type];
- shapeLevel.add(shape.instance);
- } catch (err) {
- console.error(err);
+ if (shapeLevel && shape.instance) {
+ shapeLevel.add(shape.instance);
+ }
}
}
remove(shape) {
- try {
+ if (shape && shape.model) {
const shapeLevel = this.mapShapeLevel[shape.model.type];
- shapeLevel.remove(shape.instance);
- } catch (err) {
- console.error(err);
+ if (shapeLevel && shape.instance) {
+ shapeLevel.remove(shape.instance);
+ }
}
}
update(shape) {
- try {
+ if (shape && shape.model) {
//
- } catch (err) {
- console.error(err);
}
}
diff --git a/src/iscs_new/selectHandle.js b/src/iscs_new/selectHandle.js
index d5e219ba0..897077603 100644
--- a/src/iscs_new/selectHandle.js
+++ b/src/iscs_new/selectHandle.js
@@ -15,16 +15,16 @@ export default class SelectHandle {
onSelected(e) {
if (e.target) {
- this.e = {...e };
+ this.e = {...e};
if (['Control'].includes(this.$controller.getKeyStr())) {
+ console.log(this.$controller.isSelected(e.target.model.code));
if (this.$controller.isSelected(e.target.model.code)) {
this.delSelected(e.target);
} else {
this.addSelected(e.target);
}
- } else if (this.$controller.selectingHandle.isSelecting()) {
- this.addSelected(e.target);
} else {
+ console.log(2222)
this.clear();
this.addSelected(e.target);
}
@@ -33,23 +33,11 @@ export default class SelectHandle {
addSelected(target) {
this.$controller.storage.set(target.model.code, target);
-
target.active();
-
- if (!target.highLightInstance) {
- target.highLightInstance = this.createSelected(target);
- this.$painter.addToLevel(shapeLayer.HightLight)(target.highLightInstance);
- }
}
delSelected(target) {
target.inactive();
-
- if (target.highLightInstance) {
- this.$painter.removeFromLevel(shapeLayer.HightLight)(target.highLightInstance);
- target.highLightInstance = null;
- }
-
this.$controller.storage.delete(target.model.code);
}
@@ -61,7 +49,7 @@ export default class SelectHandle {
createSelected(target) {
if (this.$map.draggle) {
- switch (target.model._type) {
+ switch (target.model.type) {
case graphic.Line:
return new LineDraggable(this);
case graphic.Image:
diff --git a/src/iscs_new/selectingHandle.js b/src/iscs_new/selectingHandle.js
index 5c3cdd06f..b21a732c7 100644
--- a/src/iscs_new/selectingHandle.js
+++ b/src/iscs_new/selectingHandle.js
@@ -1,6 +1,7 @@
import * as graphic from './core/graphic.js';
import shapeRender from './constant/shapeRender';
import shapeLayer from './constant/shapeLayer';
+import shapeType from './constant/shapeType.js';
function shapeStyleBuilder() {
return {
@@ -56,11 +57,11 @@ export default class SelectingHandle {
const selectingRect = this.selecting.getBoundingRect();
Object.values(this.$map.getMapShape()).forEach(el => {
- if (el.instance && selectingRect.intersect(el.instance.getBoundingRect())) {
- if (el.model.composeCode) {
- this.setSelected(this.$map.getShapeByCode(el.model.composeCode));
- } else {
+ if (el.model && this.checkSelectingRectContainShape(selectingRect, el)) {
+ console.log(1111111);
+ if (!el.model.composeCode) {
this.setSelected(el);
+ this.$controller.setLocking(true);
}
}
});
@@ -78,6 +79,11 @@ export default class SelectingHandle {
this.$painter.removeFromLevel(shapeLayer.SelectIng)(this.selecting);
}
+ checkSelectingRectContainShape(rect, shape) {
+ const shapeRect = shape.getBoundingRect();
+ return shapeRect? rect.intersect(shapeRect): false;
+ }
+
normalizedArea(begin, end) {
const options = this.$map.getOption();
const x = (begin.x + options.offsetX) / options.scaleRate;
diff --git a/src/iscs_new/utils/orders.js b/src/iscs_new/utils/orders.js
new file mode 100644
index 000000000..560498317
--- /dev/null
+++ b/src/iscs_new/utils/orders.js
@@ -0,0 +1,7 @@
+export default {
+ ADD: '__ADD__',
+ DELETE: '__DEL__',
+ UPDATE: '__UPT__',
+ BINDING: '__BINDING__',
+ UNBINDING: '__UNBINDING__',
+}
diff --git a/src/views/test/index.vue b/src/views/test/index.vue
index b1721132c..5467ee670 100644
--- a/src/views/test/index.vue
+++ b/src/views/test/index.vue
@@ -4,6 +4,7 @@
删除
+ 解绑
源数据
@@ -14,9 +15,12 @@