增加鼠标处理

This commit is contained in:
ival 2019-07-09 19:04:45 +08:00
parent 7441b41a51
commit 0360b10a79
9 changed files with 264 additions and 80 deletions

View File

@ -1,7 +0,0 @@
class EventController {
constructor(jmap) {
}
}

View File

@ -1,15 +1,28 @@
import * as zrUtil from 'zrender/src/core/util';
import zrender from 'zrender';
import Painter from './painter';
import ProxyHandle from './proxyHandle';
import MouseController from './mouseController';
import deviceState from './config/deviceState';
import deviceStyle from './config/deviceStyle';
import deviceType from './config/deviceType';
import { parser, deviceFactory } from './utils/parser';
const renderer = 'canvas';
const devicePixelRatio = 2;
class Jmap {
constructor(opts) {
// 挂载的dom节点
this.$dom = opts.dom;
// 绘图句柄
this.zr = zrender.init(opts.dom, Object.assign({
renderer,
devicePixelRatio,
width: opts.dom.clientWidth,
height: opts.dom.clientHeight
}, opts.config));
// 鼠标事件
this.events = { Pan: 'pan', Zoom: 'zoom', Selected: 'selected', Contextmenu: 'contextmenu' };
// 回调事件
this.methods = opts.methods;
@ -18,7 +31,7 @@ class Jmap {
this.data = {};
// 默认初始状态
this.defaultStateDict = this.loaddefaultState();
this.defaultStateDict = this.loadDefaultState();
// 皮肤参数
this.skinStyle = '';
@ -29,11 +42,16 @@ class Jmap {
// 设备数据
this.mapDevice = {};
// 设备代理数据
// 代理数据
this.proxyData = {};
// 绘图模块
this.$painter = new Painter(this, opts);
this.painter = new Painter(this);
// 鼠标事件
this.mouseController = new MouseController(this);
this.mouseController.enable();
}
/**
@ -41,34 +59,36 @@ class Jmap {
* @param {*} data
*/
loadData(skinStyle, data) {
// 保存皮肤类型
this.skinStyle = skinStyle;
// 保存原始数据
this.data = data;
// 加载皮肤
this.styleDict = this.loadStyle(skinStyle);
console.log('开始解析');
// 解析地图数据
this.mapDevice = parser(data, this.defaultStateDict);
console.log('解析数据完成');
// 生成代理对象
this.proxyData = new Proxy(this.mapDevice, new ProxyHandle(this));
this.proxyData = new Proxy(this.mapDevice, new ProxyHandle(this.painter));
this.methods.dataLoaded();
// 数据加载完成回调
(this.methods.dataLoaded instanceof Function) && this.methods.dataLoaded();
// 初次渲染视图
this.$painter.repaint(this.mapDevice, this.styleDict);
this.painter.repaint(this.mapDevice, this.styleDict);
this.methods.stateLoaded();
// 视图渲染完成回调
(this.methods.viewLoaded instanceof Function) && this.methods.viewLoaded();
}
loadStyle(skinStyle) {
return deviceStyle;
}
loaddefaultState() {
loadDefaultState() {
const defaultStateDict = {};
zrUtil.each(Object.keys(deviceState), (type) => {
@ -81,6 +101,18 @@ class Jmap {
return defaultStateDict;
}
setDefaultState() {
let list = [];
Object.values(this.mapDevice).forEach(elem => {
let code = elem._code;
let type = elem._type;
list.push(Object.assign({ code, type }, this.defaultStateDict[type]));
})
this.update(list);
}
syncData(model) {
let code = model.code;
let type = model.type;
@ -113,7 +145,7 @@ class Jmap {
device = this.proxyData[code] = Object.assign(device, { model });
}
// this.syncData(model);
this.syncData(model);
})
}
@ -130,8 +162,16 @@ class Jmap {
})
}
getZr() {
return this.zr;
}
getPainter() {
return this.$painter;
return this.painter;
}
getEvents() {
return this.events;
}
getSkinStyle() {
@ -151,11 +191,11 @@ class Jmap {
}
refresh() {
this.$painter.refresh();
this.painter.refresh();
}
clear() {
this.$painter.clear();
this.painter.clear();
}
dispose() {
@ -163,7 +203,8 @@ class Jmap {
this.styleDict = {};
this.mapDevice = {};
this.proxyData = {};
this.$painter.dispose();
this.zr && zrender.dispose(this.zr);
this.painter.dispose();
}
}

170
src/jmap/mouseController.js Normal file
View File

@ -0,0 +1,170 @@
import deviceType from './config/deviceType';
import Eventful from 'zrender/src/mixin/Eventful';
import * as eventTool from 'zrender/src/core/event';
class EventModel {
constructor(e) {
this.clientX = e.event.clientX;
this.clientY = e.event.clientY;
debugger
let view = e.target;
if (view) {
if (view._subType) {
this.subType = view._subType;
}
if (view._val) {
this.val = view._val;
}
}
while (view) {
if (view._type in Object.values(deviceType)) {
this.code = view._code;
this.type = view._type;
break;
}
if (!this.val) {
if (view._subType) {
this.subType = view._subType;
}
if (view._val) {
this.val = view._val;
}
}
view = view.parent;
}
}
}
class MouseController extends Eventful {
constructor(jmap) {
super();
this.zr = jmap.getZr();
this.events = jmap.getEvents();
this.throttle = 100; // 刷新频率
let clickHandler = this.click.bind(this);
let contextmenuHandler = this.contextmenu.bind(this);
let moveEventHandler = this.moveEvent.bind(this);
this.zr.on('click', clickHandler);
this.zr.on('contextmenu', contextmenuHandler);
this.zr.on('mousemove', moveEventHandler);
let mousedownHandler = this.mousedown.bind(this);
let mousemoveHandler = this.mousemove.bind(this);
let mouseupHandler = this.mouseup.bind(this);
let mousewheelHandler = this.mousewheel.bind(this);
this.enable = function (opts) {
opts = opts || {};
this._moveOnMouseMove = opts.moveOnMouseMove || true;
this._zoomOnMouseWheel = opts.zoomOnMouseWheel || false;
this._preventDefaultMouseMove = opts.preventDefaultMouseMove || true;
this.disable();
this.zr.on('mousedown', mousedownHandler);
this.zr.on('mousemove', mousemoveHandler);
this.zr.on('mouseup', mouseupHandler);
this.zr.on('mousewheel', mousewheelHandler);
}
this.disable = function () {
this.zr.off('mousedown', mousedownHandler);
this.zr.off('mousemove', mouseupHandler);
this.zr.off('mouseup', mousemoveHandler);
this.zr.off('mousewheel', mousewheelHandler);
}
this.isDragging = function () { return this._dragging; }
}
mousedown(e) {
if (eventTool.notLeftMouse(e)) {
return;
}
this._x = e.offsetX;
this._y = e.offsetY;
this._dragging = true;
}
mousemove(e) {
if (eventTool.notLeftMouse(e)
|| !this._moveOnMouseMove
|| !this._dragging
) {
return;
}
let oldX = this._x;
let oldY = this._y;
let dx = e.offsetX - oldX;
let dy = e.offsetY - oldY;
this._x = e.offsetX;
this._y = e.offsetY;
this._preventDefaultMouseMove && eventTool.stop(e.event);
this.trigger(this.events.Pan, {
dx: dx, dy: dy, oldX: oldX, oldY: oldY, newX: this._x, newY: this._y
});
}
mouseup(e) {
if (!eventTool.notLeftMouse(e)) {
this._dragging = false;
}
}
mousewheel(e) {
let shouldZoom = this._zoomOnMouseWheel;
let wheelDelta = e.wheelDelta;
let originX = e.offsetX;
let originY = e.offsetY;
if (wheelDelta === 0 || !shouldZoom) {
return;
}
if (shouldZoom) {
eventTool.stop(e.event);
let scale = 1;
if (wheelDelta > 0) {
scale = 1;
} else if (wheelDelta < 0) {
scale = -1;
}
this.trigger(this.events.Zoom, {
type: 'zoom', scale: scale, originX: originX, originY: originY
});
}
}
click(e) {
var em = this.checkEvent(e);
this.trigger(this.events.Selected, em);
}
contextmenu(e) {
var em = this.checkEvent(e);
this.trigger(this.events.Contextmenu, em);
}
moveEvent(e) {
return new EventModel(e);
}
checkEvent(e) {
return new EventModel(e);
}
}
export default MouseController;

View File

@ -1,20 +1,13 @@
import zrender from 'zrender';
import * as zrUtil from 'zrender/src/core/util';
import Group from 'zrender/src/container/Group';
import deviceType from './config/deviceType';
import shapefactory from './shape/factory';
import ZoomController from './zoomController';
const renderer = 'canvas';
const devicePixelRatio = 2;
import ZoomHandle from './zoomHandle';
class Painter {
constructor(jamp, opts) {
constructor(jamp) {
// 父级实例
this.$jamp = jamp;
// zrender实例
this.$zr = null;
this.jmap = jamp;
// 图层数据
this.viewLevelMap = {};
@ -26,24 +19,21 @@ class Painter {
this.parentLevel = null;
// 视图控制器
this.zoomController = null;
this.zoomHandle = new ZoomHandle(this);
// 挂载视图
this.mount(opts.dom, Object.assign({ renderer, devicePixelRatio, width: opts.dom.width, height: opts.dom.clientHeight }, opts.config));
// 初始绘图实例
this.initPainterInstance();
}
/**
* 挂载视图
* 初始绘图实例
* @param {*} dom
* @param {*} config
*/
mount(dom, config) {
// 挂载页面视图
this.$zr = zrender.init(dom, config);
initPainterInstance() {
// 添加父级图层
this.parentLevel = new Group({ name: '__parent__' });
this.$zr.add(this.parentLevel);
this.jmap.getZr().add(this.parentLevel);
// 添加子级图层
zrUtil.each(Object.values(deviceType), (type) => {
@ -51,9 +41,6 @@ class Painter {
this.viewLevelMap[type] = level;
this.parentLevel.add(level);
});
// 视图控制器
this.zoomController = new ZoomController(this);
}
/**
@ -77,9 +64,9 @@ class Painter {
add(device) {
const type = device._type;
const code = device._code;
const view = shapefactory(type, device, this.$jamp.getStyleDict());
const view = shapefactory(type, device, this.jmap.getStyleDict());
if (view) {
this.zoomController.transformView(view);
this.zoomHandle.transformView(view);
this.viewInstance[code] = view;
this.viewLevelMap[type].add(view);
}
@ -116,7 +103,7 @@ class Painter {
* @param {*} zoom
*/
updateZoomTransform(zoom) {
this.zoomController.updateTransform(zoom);
this.zoomHandle.updateTransform(zoom);
}
/**
@ -131,7 +118,7 @@ class Painter {
* 刷新画布将在下一个渲染帧的时候被刷新
*/
refresh() {
this.$zr && this.$zr.refresh();
this.jmap.getZr() && this.jmap.getZr().refresh();
}
/**
@ -153,10 +140,9 @@ class Painter {
* 销毁 ZRender 实例
*/
dispose() {
this.$zr && zrender.dispose(this.$zr);
this.$zr = null;
this.viewInstance = {};
this.viewLevelMap = {};
this.parentLevel = null;
}
}

View File

@ -1,13 +1,13 @@
class ProxyHandle {
constructor(jmap) {
this.$painter = jmap.getPainter();
constructor(painter) {
this.painter = painter;
}
set(target, code, device) {
if (this.$painter.hasViewInstance(code)) {
this.$painter.update(device);
if (this.painter.hasViewInstance(code)) {
this.painter.update(device);
} else {
this.$painter.add(device);
this.painter.add(device);
}
return Reflect.set(target, code, device);
}
@ -15,18 +15,10 @@ class ProxyHandle {
deleteProperty(target, code) {
let device = target[code];
if (device) {
this.$painter.delete(target[code]);
this.painter.delete(target[code]);
}
return Reflect.deleteProperty(target, code);
}
// has(target, code) {
// return Reflect.has(target, code);
// }
// get(target, code) {
// return Reflect.get(target, code);
// }
}
export default ProxyHandle;

View File

@ -1,5 +1,6 @@
import Line from 'zrender/src/graphic/shape/Line';
import Group from 'zrender/src/container/Group';
import { stat } from 'fs';
class Link extends Group {
constructor({ _code, _type, zlevel, model, state }, style, styleGlobal) {
@ -44,7 +45,10 @@ class Link extends Group {
}
setState({ _code, _type, zlevel, model, state }) {
this.link.setStyle('stroke', 'green');
switch (state.status) {
case '01': this.link.setStyle('stroke', 'green'); break;
case '02': this.link.setStyle('stroke', 'yellow'); break;
}
}
tipBasePoint() {

View File

@ -7,7 +7,8 @@ export function deviceFactory(type, defaultStateDict, elem) {
_type: type,
_code: elem.code,
model: elem,
state: Object.assign({}, defaultStateDict[type])
state: {},
// state: Object.assign({}, defaultStateDict[type])
}, deviceRender[type]);
}

View File

@ -19,12 +19,12 @@ function createBoundingRect(view) {
return rect;
}
class ZoomController {
class ZoomHandle {
constructor(painter) {
this.$zr = painter.$zr;
this.zr = painter.jmap.getZr();
this.parentLevel = painter.parentLevel;
this.rect = { x: 0, y: 0, width: this.$zr.getWidth(), height: this.$zr.getHeight() };
this.rect = { x: 0, y: 0, width: this.zr.getWidth(), height: this.zr.getHeight() };
this.transform = createTransform({ scale: 1, offsetX: 0, offsetY: 0 });
}
@ -74,4 +74,4 @@ class ZoomController {
}
}
export default ZoomController;
export default ZoomHandle;

View File

@ -25,6 +25,7 @@
},
methods: {
dataLoaded() { console.log('dataLoaded'); },
viewLoaded() { console.log('viewLoaded'); },
stateLoaded() { console.log('stateLoaded'); },
stateUpdated() { console.log('stateUpdated'); }
}
@ -40,11 +41,9 @@
}
}
this.jmap.loadData('01',
{
linkList: list
}
);
this.jmap.loadData('01', { linkList: list });
this.jmap.setDefaultState();
// this.jmap.render([
// {code: '11', type: 'Link', beg: { x: 20 , y: 100}, end: { x: 120, y: 100 }}
@ -58,8 +57,6 @@
// {code: '11', type: 'Link', beg: { x: 0 , y: 0}, end: { x: 200, y: 200 }}
// ]);
console.log(this.jmap.mapDevice, this.jmap.proxyData, this.jmap.data);
// this.jmap.update([]);
},
methods: {