diff --git a/src/iscs_new/constant/shapeRender.js b/src/iscs_new/constant/shapeRender.js index 9e80d1feb..2156f1cda 100644 --- a/src/iscs_new/constant/shapeRender.js +++ b/src/iscs_new/constant/shapeRender.js @@ -1,4 +1,7 @@ export default { zlevel: 1, z: 9, + scale: [1, 1], + position: [0, 0], + rotation: 0 } diff --git a/src/iscs_new/factory/compose.js b/src/iscs_new/factory/compose.js index 0faadaaa9..962a072a5 100644 --- a/src/iscs_new/factory/compose.js +++ b/src/iscs_new/factory/compose.js @@ -1,5 +1,6 @@ import AbstractShape from '../core/abstractShape'; import shapeEvent from '../constant/shapeEvent'; +import * as utils from '../utils/utils'; class Compose extends AbstractShape { constructor(args) { @@ -7,6 +8,10 @@ class Compose extends AbstractShape { this.hightLightInstance.setShape(this.getBoundingRect()); } + create() { + // this.instance = new Group({}); + } + // 拖动 draft({dx, dy}) { this.model.elementCodes.forEach(code => { @@ -48,6 +53,8 @@ class Compose extends AbstractShape { el.attr(el.model) } }) + + } // 解除绑定 diff --git a/src/iscs_new/factory/element.js b/src/iscs_new/factory/element.js index 762f299d6..55cd76c04 100644 --- a/src/iscs_new/factory/element.js +++ b/src/iscs_new/factory/element.js @@ -1,6 +1,7 @@ import AbstractShape from '../core/abstractShape'; import shapeEvent from '../constant/shapeEvent'; import * as graphic from '../core/graphic'; +import * as utils from '../utils/utils'; import shapeLayer from '../constant/shapeLayer'; class Element extends AbstractShape { @@ -28,8 +29,8 @@ class Element extends AbstractShape { } this.instance = new elementBuilder({ - ...this.model, ...this.option, + ...this.model, shapeInstance: this, onmouseover, onmousemove, @@ -40,6 +41,15 @@ class Element extends AbstractShape { // 拖动 draft({dx, dy}) { + // const scale = this.instance._scale||[1,1]; + // const position = this.instance._position||[0,0]; + + // console.log(scale, position); + + // dx = (dx + position[0]) / scale[0]; + // dy = (dy + position[1]) / scale[1]; + + [dx, dy] = utils.createTransformPosition(this.instance, dx, dy); if (this.model.shape.hasOwnProperty('x')) { this.model.shape.x += dx; } @@ -75,7 +85,7 @@ class Element extends AbstractShape { }) } - this.instance.attr({...this.model, ...this.option, shapeInstance: this}) + this.instance.attr(this.model) } // 设置高亮 diff --git a/src/iscs_new/factory/index.js b/src/iscs_new/factory/index.js index 300eab13b..6b7e94779 100644 --- a/src/iscs_new/factory/index.js +++ b/src/iscs_new/factory/index.js @@ -101,7 +101,6 @@ class ShapeFactory extends Eventful { list.forEach(el => { this.mapTemplate[el.type] = templateParser.parser(el); }) - console.log(this.mapTemplate); } parse(source={}, walk=None) { diff --git a/src/iscs_new/factory/templateParser.js b/src/iscs_new/factory/templateParser.js index bf8fdf4e9..eb8c3381a 100644 --- a/src/iscs_new/factory/templateParser.js +++ b/src/iscs_new/factory/templateParser.js @@ -9,15 +9,15 @@ class TemplateParser { name: template.name, isActive: template.isActive, isFocus: template.isFocus, - mapShape: this.parseShape({}, template.shapeList), - mapState: this.parseState({}, template.shapeList), - mapEvent: this.parseEvent({}, template.shapeList), + mapShape: this.parseShape(template.shapeList), + mapState: this.parseState(template.stateList), + mapEvent: this.parseEvent(template.eventList), } return model; } - parseShape(map, list) { - (list.shapeList||[]).forEach(el => { + parseShape(list=[], map={}) { + list.forEach(el => { const shapeMap = map[el.name] = {}; shapeMap[defStatus] = { status: defStatus, style: el.style, shape: el.shape }; (el.stateList||[]).forEach(it => { @@ -27,15 +27,15 @@ class TemplateParser { return map; } - parseState(map, list) { - (list.stateList||[]).forEach(el => { + parseState(list=[], map={}) { + list.forEach(el => { map[el.status] = el; }) return map; } - parseEvent(map, list) { - (list.stateList||[]).forEach(el => { + parseEvent(list=[], map={}) { + list.forEach(el => { map[el.status] = el; }) return map; diff --git a/src/iscs_new/map.js b/src/iscs_new/map.js index 8998899bf..a838c84b6 100644 --- a/src/iscs_new/map.js +++ b/src/iscs_new/map.js @@ -15,7 +15,6 @@ import shapeType from './constant/shapeType'; const renderer = 'canvas'; const devicePixelRatio = 1; - class JMap { constructor(opts) { // 内部鼠标事件 @@ -95,48 +94,44 @@ class JMap { // 返回视图缩放偏移 this.$option.trigger(this.$option); + + return this; } setDefaultState() { this.$eventEmitter.trigger(events.StateLoaded); + return this; } setOption(opts={}) { - const option = this.pullBack(opts); - - this.$option.update(option); + this.$option.update(opts.type == this.events.__Zoom? pullBack(this.$zr, this.$option, opts):opts); this.$painter.updateTransform(this.$option); this.$controller.disable(); this.$controller.enable(); this.$eventEmitter.trigger(events.OptionUpdate); - } - - setDragging(e) { - if (e.dragTarget) { - const scaleRate = this.$option.getScaleRate(); - e.dx /= scaleRate; - e.dy /= scaleRate; - e.dragTarget.dragging(e); - } + return this; } setCenter(code) { const shape = this.$shapeFactory.getShapeByCode(code); if (shape && shape) { - var rect = utils.createBoundingRect(shape); + var rect = utils.createTransformBoundingRect(shape); var center = utils.calculateDCenter(rect, { width: this.$zr.getWidth(), height: this.$zr.getHeight() }); this.setOption(center); } + return this; } setBackgroundColor(color) { this.$zr.setBackgroundColor(color); + return this; } setCursorStyle(cursorStyle='auto') { this.$zr.setCursorStyle(cursorStyle); + return this; } repaint(source={}) { @@ -147,6 +142,7 @@ class JMap { this.$painter.add(shape); } }); + return this; } render(list=[]) { @@ -188,29 +184,13 @@ class JMap { }); this.$eventEmitter.trigger(events.ViewUpdate, list); + return this; } update(list=[]) { this.$painter.update(this.$stateHandle.update(list)); this.$eventEmitter.trigger(events.StateUpdate, list); - } - - pullBack(payload={}) { - if (payload.type == this.events.__Zoom) { - const zrWidth = this.$zr.getWidth(); - const zrHeight = this.$zr.getHeight(); - const originX = payload.originX || zrWidth / 2; - const originY = payload.originY || zrHeight / 2; - const x = (this.$option.offsetX + originX) / this.$option.scaleRate; - const y = (this.$option.offsetY + originY) / this.$option.scaleRate; - const newScaleRate = this.$option.getScaleRate(payload.scale); - const dx = originX - (x * newScaleRate - this.$option.offsetX); - const dy = originY - (y * newScaleRate - this.$option.offsetY); - payload.dx = dx; - payload.dy = dy; - } - - return payload||{}; + return this; } getEvents() { @@ -371,4 +351,17 @@ class JMap { } } +function pullBack(zr, option={}, payload={}) { + const zrWidth = zr.getWidth(); + const zrHeight = zr.getHeight(); + const originX = payload.originX || zrWidth / 2; + const originY = payload.originY || zrHeight / 2; + const x = (option.offsetX + originX) / option.scaleRate; + const y = (option.offsetY + originY) / option.scaleRate; + const newScaleRate = option.getScaleRate(payload.scale); + const dx = originX - (x * newScaleRate - option.offsetX); + const dy = originY - (y * newScaleRate - option.offsetY); + return {...payload, dx, dy}; +} + export default JMap; diff --git a/src/iscs_new/option.js b/src/iscs_new/option.js index e214aa06e..1242c9dfc 100644 --- a/src/iscs_new/option.js +++ b/src/iscs_new/option.js @@ -27,6 +27,8 @@ class Option { this.offsetY = opts.offsetY || 0; // y偏移 + this.rotation = opts.rotation || 0; // 旋转弧度 + this.throttle = opts.throttle || 100; // 刷新频率 this.disabled = false; diff --git a/src/iscs_new/painter.js b/src/iscs_new/painter.js index 20eff4d3e..fdaaac9ca 100644 --- a/src/iscs_new/painter.js +++ b/src/iscs_new/painter.js @@ -1,9 +1,7 @@ -import * as zrUtil from 'zrender/src/core/util'; -import * as vector from 'zrender/src/core/vector'; +import * as graphic from './core/graphic'; +import shapeLayer from './constant/shapeLayer'; import Group from 'zrender/src/container/Group'; import TransformHandle from './transformHandle'; -import shapeLayer from './constant/shapeLayer'; -import * as graphic from './core/graphic'; class Painter extends Group { constructor(map) { @@ -47,25 +45,19 @@ class Painter extends Group { } add(shape) { - if (shape && shape.model) { - const shapeLevel = this.mapShapeLevel[shape.model.type]; - if (shapeLevel && shape.instance) { - shapeLevel.add(shape.instance); - } + if (shape && shape.instance) { + this.addToLevel(shape.model.type)(shape.instance); } } remove(shape) { - if (shape && shape.model) { - const shapeLevel = this.mapShapeLevel[shape.model.type]; - if (shapeLevel && shape.instance) { - shapeLevel.remove(shape.instance); - } + if (shape && shape.instance) { + this.removeFromLevel(shape.model.type)(shape.instance); } } update(shape) { - if (shape && shape.model) { + if (shape && shape.instance) { // } } @@ -80,8 +72,8 @@ class Painter extends Group { addToLevel(name) { return (view) => { - this.$transformHandle.transformView(view); this.mapShapeLevel[name].add(view); + this.$transformHandle.transformView(view); this.dirty(); } } diff --git a/src/iscs_new/transformHandle.js b/src/iscs_new/transformHandle.js index 5b0d68f6f..25ca228b0 100644 --- a/src/iscs_new/transformHandle.js +++ b/src/iscs_new/transformHandle.js @@ -1,12 +1,12 @@ import * as utils from './utils/utils'; - +import * as matrix from 'zrender/src/core/matrix'; export default class TransformHandle { constructor(painter) { this.$painter = painter; this.rect = { x: 0, y: 0, width: 0, height: 0 }; - this.transform = utils.createTransform({ scaleRate: 1, offsetX: 0, offsetY: 0 }); + this.transform = utils.createTransform({scale:[1,1], position:[0,0], rotation:0 }); } getTransform() { @@ -14,7 +14,7 @@ export default class TransformHandle { } checkVisible(view) { - return utils.createBoundingRect(view).intersect(this.rect); + return utils.createTransformBoundingRect(view).intersect(this.rect); } visibleView(view) { @@ -33,7 +33,11 @@ export default class TransformHandle { // 视图进行缩放/平移 transformView(view) { if (view) { - view.transform = this.transform; + view.transform = matrix.mul( + matrix.create(), + matrix.copy(matrix.create(), this.transform), + utils.createTransform({scale: view.scale, position: view.position, rotation: view.rotation}), + ); view.decomposeTransform(); this.visibleView(view); } @@ -50,14 +54,14 @@ export default class TransformHandle { } // 更新偏移量 - updateTransform(opts) { - this.transform = utils.createTransform(opts); + updateTransform(opt) { + this.transform = utils.createTransform({scale: [opt.scaleRate, opt.scaleRate], position: [-opt.offsetX, -opt.offsetY], rotation: 0}); this.transformAll(); } // 更新画布尺寸 - updateZrSize(opts) { - this.rect = { x: 0, y: 0, width: opts.width, height: opts.height }; + updateZrSize(opt) { + this.rect = { x: 0, y: 0, width: opt.width, height: opt.height }; this.visibleAll(); } diff --git a/src/iscs_new/utils/utils.js b/src/iscs_new/utils/utils.js index 0b3c739f4..bb0272401 100644 --- a/src/iscs_new/utils/utils.js +++ b/src/iscs_new/utils/utils.js @@ -8,7 +8,7 @@ export function getUID(type) { return [(type || ''), base++, Math.random().toFixed(5)].join('_'); } -// clone一个对象 +// 克隆一个对象 export function deepClone(obj) { var tag = Array.isArray(obj) ? [] : {}; for (var key in obj) { @@ -26,7 +26,7 @@ export function deepClone(obj) { return tag; } -// 以clone的方式copy一个对象到另一个对象 +// 克隆一个对象到另一个对象 export function deepAssign(tag, obj) { return Object.assign(tag, deepClone(obj)); } @@ -45,43 +45,45 @@ export function assignByDepth(source, target, depth) { return source; } -// 代理一个线条重新计算偏移中心 -export function lineProxy(shape, origin, point) { - const dx = point.x - origin.x; - const dy = point.y - origin.y; - const dz = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); - shape.attr('origin', [origin.x, origin.y]); - shape.attr('rotation', -Math.atan2(dy, dx),); - shape.setShape({ - points: [ - [origin.x, origin.y], - [origin.x+dz, origin.y] - ] - }); - return shape; -} - // 创建一个transform -export function createTransform(opts) { +export function createTransform({scale=[1,1], position=[0,0], rotation=0}) { let transform = matrix.create(); - transform = matrix.scale(matrix.create(), transform, [opts.scaleRate, opts.scaleRate]); - transform = matrix.translate(matrix.create(), transform, [-opts.offsetX, -opts.offsetY]); + transform = matrix.scale(matrix.create(), transform, scale); + transform = matrix.translate(matrix.create(), transform, position); + transform = matrix.rotate(matrix.create(), transform, rotation); return transform; } // 计算缩放和偏移后的包围框 -export function createBoundingRect(view) { +export function createTransformBoundingRect(view) { const rect = view.getBoundingRect().clone(); - const scale = view.scale[0]; - const offsetX = view.position[0]; - const offsetY = view.position[1]; - rect.x = rect.x * scale + offsetX; - rect.y = rect.y * scale + offsetY; - rect.width = rect.width * scale; - rect.height = rect.height * scale; + + const transform = view.transform||matrix.identity(matrix.create()); + const scaleX = transform[0]; + const scaleY = transform[3]; + const offsetX = transform[4]; + const offsetY = transform[5]; + + rect.x = rect.x * scaleX + offsetX; + rect.y = rect.y * scaleY + offsetY; + rect.width = rect.width * scaleX; + rect.height = rect.height * scaleY; + return rect; } +// 计算缩放和偏移后的偏移 +export function createTransformPosition(view, x, y) { + // const transform = view.transform||matrix.identity(matrix.create()); + // const scaleX = transform[0]; + // const scaleY = transform[3]; + // const offsetX = transform[4]; + // const offsetY = transform[5]; + // x = x / scaleX + offsetX; + // y = y / scaleY + offsetY; + return [x, y] +} + // 计算视图中心 export function calculateDCenter(viewRect, bound) { var dx = (bound.width - viewRect.width) / 2 - viewRect.x; diff --git a/src/views/test/index.vue b/src/views/test/index.vue index 56cf106c0..55d44324c 100644 --- a/src/views/test/index.vue +++ b/src/views/test/index.vue @@ -99,15 +99,15 @@ export default { type: 'Device', name: 'test', isActive: false, - isFoucs: false, + isFocus: false, shapeList: [ { name: 'a', type: 'Rect', shape: {}, style: {}, stateList: [ - { status: 'a1', style:{}, shape: {} }, - { status: 'a2', style:{}, shape: {} } + { status: 'st1', shape: {}, style:{ fill: 'yellow', stroke: 'black'} }, + { status: 'st2', shape: {}, style:{ fill: 'blue', stroke: 'black'} } ] }, { name: 'b', @@ -115,14 +115,14 @@ export default { shape: {}, style: {}, stateList: [ - { status: 'b1', style:{}, shape: {} }, - { status: 'b2', style:{}, shape: {} } + { status: 'st1', shape: {}, style:{ fill: 'yellow', stroke: 'black'} }, + { status: 'st2', shape: {}, style:{ fill: 'blue', stroke: 'black'} } ] }, ], stateList: [ - { status: 't1', shapeList: [[{name: 'a', status: 'a1'}, {name: 'b', status: 'b1'}], [{name: 'a', status: 'a2'}, {name: 'b', status: 'a2'}]], weight: 2, needDefault: false, loop: true }, - { status: 't2', shapeList: [[{name: 'a', status: 'a1'}, {name: 'b', status: 'b1'}], [{name: 'a', status: 'a2'}, {name: 'b', status: 'a2'}]], weight: 2, needDefault: false, lopp: false } + { status: 's1', shapeList: [[{name: 'a', status: 'st1'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st2'}, {name: 'b', status: 'st2'}]], weight: 2, needDefault: false, loop: true }, + { status: 's2', shapeList: [[{name: 'a', status: 'st2'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st1'}, {name: 'b', status: 'st2'}]], weight: 2, needDefault: false, lopp: false } ] } ], { @@ -131,6 +131,8 @@ export default { code: '1', name: 'a', type: 'Rect', + // scale: [0.5, 0.5], + // _position: [100, 0], shape: { x: 100, y: 100, @@ -147,6 +149,8 @@ export default { code: '2', name: 'b', type: 'Circle', + // scale: [0.5, 0.5], + // position: [100, 0], shape: { cx: 100, cy: 100, @@ -193,6 +197,7 @@ export default { code: '5', name: 'c', type: 'Droplet', + // scale: [0.5, 0.5], shape: { cx: 300, cy: 200, @@ -252,6 +257,7 @@ export default { reflect: true }); + this.$iscs.update(); this.$iscs.on('contextmenu', this.onContextMenu, this); this.$iscs.on('selected', this.onSelected, this); this.$iscs.on('keyboard', this.onKeyboard, this);