增加动画处理
This commit is contained in:
parent
870852b97a
commit
eb429506f5
76
src/iscs_new/animateHandle.js
Normal file
76
src/iscs_new/animateHandle.js
Normal file
@ -0,0 +1,76 @@
|
||||
import Group from 'zrender/src/container/Group';
|
||||
|
||||
|
||||
class Animate {
|
||||
constructor(state) {
|
||||
this.state = {...state}
|
||||
this.shapeFactory = this.shape? this.shape.shapeFactory: null;
|
||||
this.timer = null;
|
||||
this.total = 0;
|
||||
this.count = 0;
|
||||
}
|
||||
|
||||
run(delay) {
|
||||
this.total = this.total + delay;
|
||||
if (this.total > this.state.time) {
|
||||
clearTimeout(this.timer);
|
||||
this.timer = setTimeout(this.__animate.bind(this), this.state.delay);
|
||||
this.count = this.count + 1;
|
||||
this.total = 0;
|
||||
}
|
||||
}
|
||||
|
||||
isLoop() {
|
||||
return this.state.loop;
|
||||
}
|
||||
|
||||
__animate() {
|
||||
const shape = this.state.shape;
|
||||
const frameList = this.state.frameList;
|
||||
const mapView = this.__traverse(shape, {});
|
||||
if(shape && frameList) {
|
||||
const size = frameList.length;
|
||||
const frame = frameList[this.count%size];
|
||||
Object.keys(frame).forEach(name => {
|
||||
const view = mapView[name];
|
||||
const model = frame[name];
|
||||
if (view && model) {
|
||||
view.attr({shape: model.shape, style: model.style});
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
__traverse(group, map) {
|
||||
group.eachChild(el => {
|
||||
if (el instanceof Group) {
|
||||
this.__traverse(el, map);
|
||||
} else {
|
||||
map[el.name] = el;
|
||||
}
|
||||
})
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
class AnimateHandle {
|
||||
constructor(painter) {
|
||||
this.animates = [];
|
||||
}
|
||||
|
||||
onframe (delay) {
|
||||
const animate = this.animates.shift();
|
||||
if (animate) {
|
||||
animate.run(delay);
|
||||
if (animate.isLoop()) {
|
||||
this.animates.push(animate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
animate(state) {
|
||||
this.animates.push(new Animate(state));
|
||||
}
|
||||
}
|
||||
|
||||
export default AnimateHandle
|
@ -44,6 +44,7 @@ class Element extends AbstractShape {
|
||||
this.instance.origin = utils.createOrigin(this.instance);
|
||||
this.instance.transform = utils.createTransform({scale: this.model.scale, position: this.model.position, rotation: this.model.rotation});
|
||||
this.add(this.instance);
|
||||
// this.instance.animate('style', true).when(1000, {fill: 'blue'}).when(2000, {fill: 'rellow'}).start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -60,13 +60,13 @@ function update2List(source, model, action, name='') {
|
||||
|
||||
return updateModel;
|
||||
}
|
||||
|
||||
class ShapeFactory extends Eventful {
|
||||
constructor(map) {
|
||||
super();
|
||||
this.$map = map;
|
||||
this.$painter = map.getPainter();
|
||||
this.$controller = map.getController();
|
||||
this.$zr = map.getZr();
|
||||
|
||||
this.border = new graphic.Rect(shapeStyleBuilder());
|
||||
|
||||
@ -100,8 +100,9 @@ class ShapeFactory extends Eventful {
|
||||
|
||||
parseTemplates(list=[]) {
|
||||
list.forEach(el => {
|
||||
this.mapTemplate[el.type] = templateParser.parser(el);
|
||||
this.mapTemplate[el.type] = templateParser.parse(el);
|
||||
})
|
||||
console.log(this.mapTemplate);
|
||||
}
|
||||
|
||||
parse(source={}, take=None) {
|
||||
|
@ -3,8 +3,8 @@ class TemplateParser {
|
||||
constructor() {
|
||||
}
|
||||
|
||||
parser(template) {
|
||||
const model = {
|
||||
parse(template) {
|
||||
return {
|
||||
type: template.type,
|
||||
name: template.name,
|
||||
isActive: template.isActive,
|
||||
@ -13,7 +13,6 @@ class TemplateParser {
|
||||
mapState: this.parseState(template.stateList),
|
||||
mapEvent: this.parseEvent(template.eventList),
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
parseShape(list=[], map={}) {
|
||||
|
@ -43,25 +43,32 @@ class JMap {
|
||||
const optionHandler = this.setOption.bind(this);
|
||||
|
||||
this.draw = opts.draw;
|
||||
// 实例化zr
|
||||
this.$zr = zrender.init(opts.dom, { renderer, devicePixelRatio, width, height, ...utils.deepClone(opts.config||{})});
|
||||
this.$zr.dom.setAttribute('tabIndex', -1);
|
||||
this.$zr.dom.style.cursor = 'auto';
|
||||
|
||||
// 实例化缩放偏移缩放参数
|
||||
this.$option = new Option({ scaleRate: 1, offsetX: 0, offsetY: 0, ...utils.deepClone(opts.option||{})}, (dataZoom) => { this.$controller.trigger(events.DataZoom, dataZoom); }); // 缩放
|
||||
|
||||
// 实例化绘图模块
|
||||
this.$painter = new Painter(this);
|
||||
this.$painter.updateZrSize({width: this.$zr.getWidth(), height: this.$zr.getHeight()});
|
||||
this.$painter.updateTransform(this.$option);
|
||||
|
||||
// 实例化事件分发模块
|
||||
this.$controller = new Controller(this);
|
||||
this.$controller.enable();
|
||||
this.$controller.on(this.events.__Pan, optionHandler);
|
||||
this.$controller.on(this.events.__Zoom, optionHandler);
|
||||
|
||||
this.$eventEmitter = new Eventful(this);
|
||||
// 名声周期发射器
|
||||
this.$eventEmitter = new Eventful({});
|
||||
|
||||
// 数据容器工厂
|
||||
this.$shapeFactory = new ShapeFactory(this);
|
||||
|
||||
// 状态处理器
|
||||
this.$stateHandle = new StateHandle(this);
|
||||
|
||||
this.disable = function() {
|
||||
@ -71,6 +78,10 @@ class JMap {
|
||||
}
|
||||
|
||||
setMap(templates=[], source={}, eventOpts={}) {
|
||||
// 清楚数据
|
||||
this.$shapeFactory.clear();
|
||||
this.$painter.clear();
|
||||
|
||||
// 绑定事件
|
||||
this.$controller.enable(eventOpts);
|
||||
|
||||
@ -135,8 +146,6 @@ class JMap {
|
||||
}
|
||||
|
||||
repaint(source={}) {
|
||||
this.$shapeFactory.clear();
|
||||
this.$painter.clear();
|
||||
this.$shapeFactory.parse(source, shape => {
|
||||
if (shape) {
|
||||
this.$painter.add(shape);
|
||||
@ -193,7 +202,7 @@ class JMap {
|
||||
}
|
||||
|
||||
update(list=[]) {
|
||||
this.$painter.update(this.$stateHandle.update(list));
|
||||
this.$painter.update(this.$stateHandle.update(this.$shapeFactory, list));
|
||||
this.$eventEmitter.trigger(events.StateUpdate, list);
|
||||
return this;
|
||||
}
|
||||
@ -274,6 +283,9 @@ class JMap {
|
||||
case events.DataLoaded:
|
||||
this.$eventEmitter.on(events.DataLoaded, cb, context);
|
||||
break;
|
||||
case events.ViewLoaded:
|
||||
this.$eventEmitter.on(events.ViewLoaded, cb, context);
|
||||
break;
|
||||
case events.StateLoaded:
|
||||
this.$eventEmitter.on(events.StateLoaded, cb, context);
|
||||
break;
|
||||
@ -286,15 +298,16 @@ class JMap {
|
||||
case events.OptionUpdate:
|
||||
this.$eventEmitter.on(events.OptionUpdate, cb, context);
|
||||
break;
|
||||
case events.Reflect:
|
||||
this.$controller.on(events.Reflect, _.throttle(cb, 200), context);
|
||||
break;
|
||||
|
||||
case events.Selected:
|
||||
this.$controller.on(events.Selected, cb, context);
|
||||
break;
|
||||
case events.ContextMenu:
|
||||
this.$controller.on(events.ContextMenu, cb, context);
|
||||
break;
|
||||
case events.Reflect:
|
||||
this.$controller.on(events.Reflect, _.throttle(cb, 200), context);
|
||||
break;
|
||||
case events.DataZoom:
|
||||
this.$controller.on(events.DataZoom, cb, context);
|
||||
break;
|
||||
@ -318,6 +331,9 @@ class JMap {
|
||||
case events.DataLoaded:
|
||||
this.$eventEmitter.off(events.DataLoaded, cb, context);
|
||||
break;
|
||||
case events.ViewLoaded:
|
||||
this.$eventEmitter.off(events.ViewLoaded, cb, context);
|
||||
break;
|
||||
case events.StateLoaded:
|
||||
this.$eventEmitter.off(events.StateLoaded, cb, context);
|
||||
break;
|
||||
@ -330,15 +346,16 @@ class JMap {
|
||||
case events.OptionUpdate:
|
||||
this.$eventEmitter.off(events.OptionUpdate, cb, context);
|
||||
break;
|
||||
case events.Reflect:
|
||||
this.$controller.off(events.Reflect, _.throttle(cb, 200));
|
||||
break;
|
||||
|
||||
case events.Selected:
|
||||
this.$controller.off(events.Selected, cb);
|
||||
break;
|
||||
case events.ContextMenu:
|
||||
this.$controller.off(events.ContextMenu, cb);
|
||||
break;
|
||||
case events.Reflect:
|
||||
this.$controller.off(events.Reflect, _.throttle(cb, 200));
|
||||
break;
|
||||
case events.DataZoom:
|
||||
this.$controller.off(events.DataZoom, cb);
|
||||
break;
|
||||
|
@ -2,28 +2,41 @@ import * as graphic from './core/graphic';
|
||||
import shapeLayer from './constant/shapeLayer';
|
||||
import Group from 'zrender/src/container/Group';
|
||||
import TransformHandle from './transformHandle';
|
||||
import AnimateHandle from './animateHandle';
|
||||
|
||||
class Painter extends Group {
|
||||
constructor(map) {
|
||||
super({name: `__Container__` });
|
||||
// 添加父级图层
|
||||
const zr = map.getZr();
|
||||
zr.add(this);
|
||||
|
||||
// 初始图层
|
||||
this.initLevels(map);
|
||||
|
||||
// 视图控制器
|
||||
this.$transformHandle = new TransformHandle(this);
|
||||
|
||||
// 动画处理器
|
||||
this.$animateHandle = new AnimateHandle(this);
|
||||
|
||||
// 重新动画函数,加入钩子
|
||||
this.onframe(zr);
|
||||
}
|
||||
|
||||
onframe(zr) {
|
||||
const onframe = zr.animation.onframe;
|
||||
const animateHandle = this.$animateHandle;
|
||||
zr.animation.onframe = (...args) => {
|
||||
onframe.apply(zr.animation, args);
|
||||
animateHandle.onframe(...args);
|
||||
}
|
||||
}
|
||||
|
||||
initLevels(map) {
|
||||
// 初始化图层对象
|
||||
this.mapShapeLayer = {};
|
||||
|
||||
// 获取顶层图层
|
||||
this.$zr = map.getZr();
|
||||
|
||||
// 添加父级图层
|
||||
this.$zr.add(this);
|
||||
|
||||
// 创建select图层
|
||||
this.mapShapeLayer[shapeLayer.Selecting] = new Group({ name: shapeLayer.Selecting });
|
||||
|
||||
@ -58,10 +71,10 @@ class Painter extends Group {
|
||||
}
|
||||
}
|
||||
|
||||
update(shape) {
|
||||
if (shape) {
|
||||
//
|
||||
}
|
||||
update(stateList=[]) {
|
||||
stateList.forEach(state => {
|
||||
this.$animateHandle.animate(state);
|
||||
})
|
||||
}
|
||||
|
||||
updateTransform(opt) {
|
||||
@ -100,6 +113,7 @@ class Painter extends Group {
|
||||
destroy() {
|
||||
this.clear();
|
||||
this.mapShapeLayer = {};
|
||||
this.mapAnimate = {};
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,24 @@ export default class StateHandle {
|
||||
}
|
||||
|
||||
parse(shapeFactory, state) {
|
||||
console.log(shapeFactory, state);
|
||||
return state;
|
||||
const mapTemplate = shapeFactory.getMapTemplate();
|
||||
const template = mapTemplate[state.type];
|
||||
const templateState = template.mapState[state.status];
|
||||
|
||||
return {
|
||||
...state,
|
||||
...templateState,
|
||||
shape: shapeFactory.getShapeByCode(state.code),
|
||||
frameList: templateState.frameList.map(frame => {
|
||||
return Object.fromEntries(frame.map(el => {
|
||||
const mapState = template.mapShape[el.name];
|
||||
return [el.name, {
|
||||
...el,
|
||||
...mapState[el.status]
|
||||
}]
|
||||
}));
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
update(shapeFactory, states=[]) {
|
||||
@ -17,7 +33,7 @@ export default class StateHandle {
|
||||
// this.updateState(this.parse(shapeFactory, state)), // 处理自身
|
||||
// this.updateState(this.parse(shapeFactory, state)) // 处理依赖
|
||||
];
|
||||
}, []);
|
||||
}, []).sort((a,b) => a.weight - b.weight);
|
||||
}
|
||||
|
||||
updateState(state={}) {
|
||||
|
@ -93,7 +93,10 @@ export default {
|
||||
});
|
||||
|
||||
Vue.prototype.$iscs = this.$iscs;
|
||||
|
||||
this.$iscs.on('viewLoaded', this.onUpdate, this);
|
||||
this.$iscs.on('contextmenu', this.onContextMenu, this);
|
||||
this.$iscs.on('selected', this.onSelected, this);
|
||||
this.$iscs.on('keyboard', this.onKeyboard, this);
|
||||
this.$iscs.setMap([
|
||||
{
|
||||
type: 'Device',
|
||||
@ -104,7 +107,10 @@ export default {
|
||||
{ name: 'a',
|
||||
type: 'Rect',
|
||||
shape: {},
|
||||
style: {},
|
||||
style: {
|
||||
fill: 'red',
|
||||
stroke: 'black'
|
||||
},
|
||||
stateList: [
|
||||
{ status: 'st1', shape: {}, style:{ fill: 'yellow', stroke: 'black'} },
|
||||
{ status: 'st2', shape: {}, style:{ fill: 'blue', stroke: 'black'} }
|
||||
@ -113,7 +119,10 @@ export default {
|
||||
{ name: 'b',
|
||||
type: 'Circle',
|
||||
shape: {},
|
||||
style: {},
|
||||
style: {
|
||||
fill: 'red',
|
||||
stroke: 'black'
|
||||
},
|
||||
stateList: [
|
||||
{ status: 'st1', shape: {}, style:{ fill: 'yellow', stroke: 'black'} },
|
||||
{ status: 'st2', shape: {}, style:{ fill: 'blue', stroke: 'black'} }
|
||||
@ -121,8 +130,8 @@ export default {
|
||||
},
|
||||
],
|
||||
stateList: [
|
||||
{ status: 's1', frameList: [[{name: 'a', status: 'st1'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st2'}, {name: 'b', status: 'st2'}]], weight: 2, needDefault: false, loop: true },
|
||||
{ status: 's2', frameList: [[{name: 'a', status: 'st2'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st1'}, {name: 'b', status: 'st2'}]], weight: 2, needDefault: false, lopp: false }
|
||||
{ status: 's1', frameList: [[{name: 'a', status: 'st1'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st2'}, {name: 'b', status: 'st2'}]], weight: 2, loop: true, delay: 2000, time: 200, needDefault: false },
|
||||
{ status: 's2', frameList: [[{name: 'a', status: 'st2'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st1'}, {name: 'b', status: 'st2'}]], weight: 1, loop: true, delay: 5000, time: 500, needDefault: true }
|
||||
]
|
||||
}
|
||||
], {
|
||||
@ -268,7 +277,7 @@ export default {
|
||||
scale: [0.5, 0.5],
|
||||
position: [100, 100],
|
||||
rotation: Math.PI/2,
|
||||
composeCode: '1000',
|
||||
// composeCode: '1000',
|
||||
},
|
||||
{
|
||||
code: '101',
|
||||
@ -277,17 +286,17 @@ export default {
|
||||
scale: [1, 1],
|
||||
position: [200, 0],
|
||||
rotation: 0,
|
||||
composeCode: '1000'
|
||||
// composeCode: '1000'
|
||||
},
|
||||
{
|
||||
code: '1000',
|
||||
type: 'Device',
|
||||
scale: [1, 1],
|
||||
position: [0, 0],
|
||||
rotation: 0,
|
||||
elementCodes: ['100', '101'],
|
||||
composeCode: ''
|
||||
}
|
||||
// {
|
||||
// code: '1000',
|
||||
// type: 'Device',
|
||||
// scale: [1, 1],
|
||||
// position: [0, 0],
|
||||
// rotation: 0,
|
||||
// elementCodes: ['100', '101'],
|
||||
// composeCode: ''
|
||||
// }
|
||||
]
|
||||
}, {
|
||||
panEnable: true,
|
||||
@ -299,18 +308,17 @@ export default {
|
||||
reflect: true
|
||||
});
|
||||
|
||||
this.$iscs.update([
|
||||
{ status: 's1', frameList: [[{name: 'a', status: 'st1'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st2'}, {name: 'b', status: 'st2'}]], weight: 2, needDefault: false, loop: true },
|
||||
{ status: 's2', frameList: [[{name: 'a', status: 'st2'}, {name: 'b', status: 'st1'}], [{name: 'a', status: 'st1'}, {name: 'b', status: 'st2'}]], weight: 2, needDefault: false, lopp: false }
|
||||
]);
|
||||
this.$iscs.on('contextmenu', this.onContextMenu, this);
|
||||
this.$iscs.on('selected', this.onSelected, this);
|
||||
this.$iscs.on('keyboard', this.onKeyboard, this);
|
||||
|
||||
window.document.oncontextmenu = function () {
|
||||
return false;
|
||||
};
|
||||
},
|
||||
onUpdate(e) {
|
||||
this.$iscs.update([
|
||||
{ status: 's1', code: '100', type: 'Device' },
|
||||
{ status: 's2', code: '101', type: 'Device' }
|
||||
]);
|
||||
},
|
||||
// 键盘快捷键事件
|
||||
onKeyboard(hook) {
|
||||
console.log(hook);
|
||||
|
Loading…
Reference in New Issue
Block a user