Commit c7dc0702 authored by techird's avatar techird

优化渲染机制

parent 257373fa
......@@ -2,6 +2,7 @@ var Minder = KityMinder.Minder = kity.createClass('KityMinder', {
constructor: function(options) {
this._options = Utils.extend(window.KITYMINDER_CONFIG || {}, options);
this.setDefaultOptions(KM.defaultOptions);
this._initEvents();
this._initMinder();
this._initSelection();
......
......@@ -7,15 +7,7 @@ kity.extendClass(Minder, {
this._commands = {};
this._query = {};
this._modules = {};
this._renderers = {
center: [],
left: [],
right: [],
top: [],
bottom: [],
outline: [],
outside: []
};
this._renderers = {};
var i, name, type, module, moduleDeals,
dealCommands, dealEvents, dealRenderers;
......@@ -59,8 +51,7 @@ kity.extendClass(Minder, {
if (dealRenderers) {
for (type in dealRenderers) {
if (!(type in this._renderers)) continue;
this._renderers[type] = this._renderers[type] || [];
if (Utils.isArray(dealRenderers[type])) {
this._renderers[type] = this._renderers[type].concat(dealRenderers[type]);
......
......@@ -7,8 +7,20 @@ var Renderer = KityMinder.Renderer = kity.createClass('Renderer', {
throw new Error('Not implement: Renderer.create()');
},
shouldRender: function() {
return true;
},
update: function() {
throw new Error('Not implement: Renderer.update()');
},
getRenderShape: function() {
return this._renderShape || null;
},
setRenderShape: function(shape) {
this._renderShape = shape;
}
});
......@@ -23,42 +35,73 @@ kity.extendClass(Minder, {
_createRendererForNode: function(node) {
var registered = this._renderers;
var renderers = [];
renderers = renderers.concat(registered.center);
renderers = renderers.concat(registered.left);
renderers = renderers.concat(registered.right);
renderers = renderers.concat(registered.top);
renderers = renderers.concat(registered.bottom);
renderers = renderers.concat(registered.outline);
renderers = renderers.concat(registered.outside);
['center', 'left', 'top', 'bottom', 'outline', 'outside'].forEach(function(section) {
if (registered['before' + section]) {
renderers = renderers.concat(registered['before' + section]);
}
if (registered[section]) {
renderers = renderers.concat(registered[section]);
}
if (registered['after' + section]) {
renderers = renderers.concat(registered['after' + section]);
}
});
node._renderers = renderers.map(function(Renderer) {
var renderer = new Renderer(node);
renderer.create(node);
return renderer;
return new Renderer(node);
});
},
renderNode: function(node) {
var rendererClasses = this._renderers,
g = KityMinder.Geometry,
contentBox = node._contentBox = g.wrapBox({
left: 0,
right: 0,
top: 0,
bottom: 0
});
var i, latestBox;
var rendererClasses = this._renderers;
var g = KityMinder.Geometry;
var i, latestBox, renderer;
if (!node._renderers) {
this._createRendererForNode(node);
}
for (i = 0; i < node._renderers.length; i++) {
latestBox = node._renderers[i].update(node, contentBox);
if (latestBox) {
node._contentBox = contentBox = g.mergeBox(contentBox, latestBox);
node._contentBox = g.wrapBox({
left: 0,
right: 0,
top: 0,
bottom: 0
});
node._renderers.forEach(function(renderer) {
// 判断当前上下文是否应该渲染
if (renderer.shouldRender(node)) {
// 应该渲染,但是渲染图形没创建过,需要创建
if (!renderer.getRenderShape()) {
renderer.setRenderShape(renderer.create(node));
if (renderer.bringToBack) {
node.getRenderContainer().prependShape(renderer.getRenderShape());
} else {
node.getRenderContainer().prependShape(renderer.getRenderShape());
}
}
// 强制让渲染图形显示
renderer.getRenderShape().setVisible(true);
// 更新渲染图形
latestBox = renderer.update(renderer.getRenderShape(), node, node._contentBox);
// 合并渲染区域
if (latestBox) {
node._contentBox = g.mergeBox(node._contentBox, latestBox);
}
}
}
// 如果不应该渲染,但是渲染图形创建过了,需要隐藏起来
else if (renderer.getRenderShape()) {
renderer.getRenderShape().setVisible(false);
}
});
this.fire('noderender', {
node: node
......@@ -74,7 +117,7 @@ kity.extendClass(MinderNode, {
getRenderer: function(type) {
var rs = this._renderers;
for (var i = 0; i < rs.length; i++) {
if (rs[i] instanceof type) return rs[i];
if (rs[i].getType() == type) return rs[i];
}
return null;
},
......
KityMinder.registerModule('basestylemodule', function() {
var km = this;
function getNodeDataOrStyle(node, name) {
return node.getData(name) || node.getStyle(name);
}
KityMinder.TextRenderer.registerStyleHook(function(node, text) {
text.setFont({
weight: getNodeDataOrStyle(node, 'font-weight'),
style: getNodeDataOrStyle(node, 'font-style')
});
});
return {
'commands': {
'bold': kity.createClass('boldCommand', {
......
......@@ -20,7 +20,7 @@ KityMinder.registerModule('TextEditModule', function() {
km.textEditNode = function(node) {
var textShape = node.getTextShape();
var textShape = node.getRenderer('TextRenderer').getRenderShape();
this.setStatus('textedit');
sel.setHide();
sel.setStartOffset(0);
......@@ -72,14 +72,14 @@ KityMinder.registerModule('TextEditModule', function() {
km.setStatus('normal');
}
if (node) {
var textShape = node.getTextShape();
var textShape = node.getRenderer('TextRenderer').getRenderShape();
textShape.setStyle('cursor', 'default');
if (this.isSingleSelect() && node.isSelected()) { // && e.kityEvent.targetShape.getType().toLowerCase()== 'text'
sel.collapse();
sel.setSelectionShowStatus(true);
node.getTextShape().setStyle('cursor', 'text');
node.getRenderer('TextRenderer').getRenderShape().setStyle('cursor', 'text');
km.setStatus('textedit');
receiver.setTextEditStatus(true)
.setSelection(sel)
......@@ -140,7 +140,7 @@ KityMinder.registerModule('TextEditModule', function() {
!orgEvt.altKey) {
//准备输入状态
var textShape = node.getTextShape();
var textShape = node.getRenderer('TextRenderer').getRenderShape();
sel.setHide();
sel.setStartOffset(0);
......@@ -184,7 +184,7 @@ KityMinder.registerModule('TextEditModule', function() {
if (node) {
if (this.isSingleSelect() && node.isSelected()) {
//准备输入状态
var textShape = node.getTextShape();
var textShape = node.getRenderer('TextRenderer').getRenderShape();
sel.setHide();
sel.setStartOffset(0);
......@@ -247,7 +247,7 @@ KityMinder.registerModule('TextEditModule', function() {
'restoreScene': function() {
var node = this.getSelectedNode();
if (node && this.isSingleSelect()) {
var textShape = node.getTextShape();
var textShape = node.getRenderer('TextRenderer').getRenderShape();
sel.setHide();
sel.setStartOffset(0);
sel.setEndOffset(textShape.getContent().length);
......@@ -292,10 +292,10 @@ KityMinder.registerModule('TextEditModule', function() {
return;
}
var textShape = node.getTextShape();
var textShape = node.getRenderer('TextRenderer').getRenderShape();
textShape.setStyle('cursor', 'default');
node.getTextShape().setStyle('cursor', 'text');
node.getRenderer('TextRenderer').getRenderShape().setStyle('cursor', 'text');
km.setStatus('textedit');
receiver.setTextEditStatus(true)
.setSelection(sel)
......
......@@ -107,7 +107,7 @@ Minder.Receiver = kity.createClass('Receiver', {
me.setContainerStyle();
me.minderNode.render().layout();
me.textShape = me.minderNode.getTextShape();
me.textShape = me.minderNode.getRenderer('TextRenderer').getRenderShape();
if (text.length === 0) {
me.textShape.setOpacity(0);
}
......
......@@ -177,7 +177,7 @@ KityMinder.registerModule('Expand', function() {
}
});
var ExpanderRenderer = kity.createClass('Expander', {
var ExpanderRenderer = kity.createClass('ExpanderRenderer', {
base: Renderer,
create: function(node) {
......@@ -186,15 +186,20 @@ KityMinder.registerModule('Expand', function() {
node.getRenderContainer().addShape(this.expander);
node.expanderRenderer = this;
this.node = node;
return this.expander;
},
update: function(node) {
shouldRender: function(node) {
return !node.isRoot();
},
update: function(expander, node, box) {
if (!node.parent) return;
var visible = node.parent.isExpanded();
node.getRenderContainer().setVisible(visible);
this.expander.setState(visible && node.children.length ? node.getData(EXPAND_STATE_DATA) : 'hide');
expander.setState(visible && node.children.length ? node.getData(EXPAND_STATE_DATA) : 'hide');
var x, y;
......@@ -222,8 +227,8 @@ KityMinder.registerModule('Expand', function() {
},
events: {
'layoutapply': function(e) {
var r = e.node.getRenderer(ExpanderRenderer);
r.update(e.node);
var r = e.node.getRenderer('ExpanderRenderer');
r.update(r.getRenderShape(), e.node);
}
},
renderers: {
......
KityMinder.registerModule("fontmodule", function() {
function getNodeDataOrStyle(node, name) {
return node.getData(name) || node.getStyle(name);
}
KityMinder.TextRenderer.registerStyleHook(function(node, text) {
text.fill(getNodeDataOrStyle(node, 'color'));
text.setFont({
family: getNodeDataOrStyle(node, 'font-family'),
size: getNodeDataOrStyle(node, 'font-size')
});
});
return {
defaultOptions: {
......
......@@ -9,18 +9,17 @@ KityMinder.registerModule('OutlineModule', function() {
base: Renderer,
create: function(node) {
var group = new kity.Group();
var outline = this.outline = new kity.Rect()
.setId(KityMinder.uuid('node_outline'));
var bg = this.bg = new kity.Rect()
var shadow = this.shadow = new kity.Rect()
.setId(KityMinder.uuid('node_shadow'))
.fill('black')
.setOpacity(0.2);
node.getRenderContainer()
.prependShape(outline)
.prependShape(bg);
group.addShapes([shadow, outline]);
if (wireframe) {
var oxy = this.oxy = new kity.Path()
......@@ -30,22 +29,28 @@ KityMinder.registerModule('OutlineModule', function() {
var box = this.wireframe = new kity.Rect()
.stroke('lightgreen');
node.getRenderContainer().addShapes([oxy, box]);
group.addShapes([oxy, box]);
}
this.bringToBack = true;
return group;
},
update: function(node) {
update: function(created, node) {
var contentBox = node.getContentBox();
var paddingLeft = node.getStyle('padding-left'),
paddingRight = node.getStyle('padding-right'),
paddingTop = node.getStyle('padding-top'),
paddingBottom = node.getStyle('padding-bottom');
var outlineBox = {
x: contentBox.x - paddingLeft,
y: contentBox.y - paddingTop,
width: contentBox.width + paddingLeft + paddingRight,
height: contentBox.height + paddingTop + paddingBottom
};
this.outline
.setPosition(outlineBox.x, outlineBox.y)
.setSize(outlineBox.width, outlineBox.height)
......@@ -55,13 +60,13 @@ KityMinder.registerModule('OutlineModule', function() {
node.getStyle('background'));
if (node.getLevel() < 2) {
this.bg
this.shadow
.setVisible(true)
.setPosition(outlineBox.x + 3, outlineBox.y + 4)
.setSize(outlineBox.width, outlineBox.height)
.setRadius(node.getStyle('radius'));
} else {
this.bg.setVisible(false);
this.shadow.setVisible(false);
}
if (wireframe) {
......
......@@ -84,23 +84,19 @@ KityMinder.registerModule('PriorityModule', function() {
base: KityMinder.Renderer,
create: function(node) {
this.priority = new PriorityIcon();
node.getRenderContainer().addShape(this.priority);
return new PriorityIcon();
},
update: function(node, box) {
var data = node.getData(PRIORITY_DATA);
var spaceLeft = node.getStyle('space-left');
var icon = this.priority;
var x, y;
if (!data) {
icon.setVisible(false);
return null;
}
shouldRender: function(node) {
return node.getData(PRIORITY_DATA);
},
icon.setVisible(true).setValue(data);
update: function(icon, node, box) {
var data = node.getData(PRIORITY_DATA);
var spaceLeft = node.getStyle('space-left'),
x, y;
icon.setValue(data);
x = box.left - icon.width - spaceLeft;
y = -icon.height / 2;
......
......@@ -77,23 +77,19 @@ KityMinder.registerModule('ProgressModule', function() {
base: KityMinder.Renderer,
create: function(node) {
this.progress = new ProgressIcon();
node.getRenderContainer().addShape(this.progress);
return new ProgressIcon();
},
update: function(node) {
shouldRender: function(node) {
return node.getData(PROGRESS_DATA);
},
update: function(icon, node, box) {
var data = node.getData(PROGRESS_DATA);
var spaceLeft = node.getStyle('space-left');
var icon = this.progress;
var box = node.getContentBox();
var x, y;
if (!data) {
icon.setVisible(false);
return null;
}
icon.setVisible(true).setValue(data);
icon.setValue(data);
x = box.left - icon.width - spaceLeft;
y = -icon.height / 2;
......
/* global Renderer: true */
kity.extendClass(MinderNode, {
getTextShape: function() {
return this._textShape;
var TextRenderer = KityMinder.TextRenderer = kity.createClass('TextRenderer', {
base: Renderer,
create: function() {
return new kity.Text()
.setId(KityMinder.uuid('node_text'))
.setVerticalAlign('middle');
},
update: function(text, node) {
this.setTextStyle(node, text.setContent(node.getText()));
return text.getBoundaryBox();
},
setTextStyle: function(node, text) {
var hooks = TextRenderer._styleHooks;
hooks.forEach(function(hook) {
hook(node, text);
});
}
});
KityMinder.registerModule('text', {
'renderers': {
center: kity.createClass('TextRenderer', {
base: Renderer,
create: function(node) {
var textShape = new kity.Text().setId(KityMinder.uuid('node_text'));
node.getRenderContainer().addShape(textShape);
utils.extend(TextRenderer, {
_styleHooks: [],
node._textShape = textShape;
},
update: function(node) {
function dataOrStyle(name) {
return node.getData(name) || node.getStyle(name);
}
return node.getTextShape()
.setContent(node.getText())
.setFont({
family: dataOrStyle('font-family'),
size: dataOrStyle('font-size'),
weight: dataOrStyle('font-weight'),
style: dataOrStyle('font-style')
})
.setVerticalAlign('middle')
.fill(node.getData('color') || node.getStyle('color'))
.getBoundaryBox();
registerStyleHook: function(fn) {
TextRenderer._styleHooks.push(fn);
}
});
}
})
KityMinder.registerModule('text', {
'renderers': {
center: TextRenderer
}
});
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment