Commit c7dc0702 authored by techird's avatar techird

优化渲染机制

parent 257373fa
...@@ -2,6 +2,7 @@ var Minder = KityMinder.Minder = kity.createClass('KityMinder', { ...@@ -2,6 +2,7 @@ var Minder = KityMinder.Minder = kity.createClass('KityMinder', {
constructor: function(options) { constructor: function(options) {
this._options = Utils.extend(window.KITYMINDER_CONFIG || {}, options); this._options = Utils.extend(window.KITYMINDER_CONFIG || {}, options);
this.setDefaultOptions(KM.defaultOptions); this.setDefaultOptions(KM.defaultOptions);
this._initEvents(); this._initEvents();
this._initMinder(); this._initMinder();
this._initSelection(); this._initSelection();
......
...@@ -7,15 +7,7 @@ kity.extendClass(Minder, { ...@@ -7,15 +7,7 @@ kity.extendClass(Minder, {
this._commands = {}; this._commands = {};
this._query = {}; this._query = {};
this._modules = {}; this._modules = {};
this._renderers = { this._renderers = {};
center: [],
left: [],
right: [],
top: [],
bottom: [],
outline: [],
outside: []
};
var i, name, type, module, moduleDeals, var i, name, type, module, moduleDeals,
dealCommands, dealEvents, dealRenderers; dealCommands, dealEvents, dealRenderers;
...@@ -59,8 +51,7 @@ kity.extendClass(Minder, { ...@@ -59,8 +51,7 @@ kity.extendClass(Minder, {
if (dealRenderers) { if (dealRenderers) {
for (type in dealRenderers) { for (type in dealRenderers) {
this._renderers[type] = this._renderers[type] || [];
if (!(type in this._renderers)) continue;
if (Utils.isArray(dealRenderers[type])) { if (Utils.isArray(dealRenderers[type])) {
this._renderers[type] = this._renderers[type].concat(dealRenderers[type]); this._renderers[type] = this._renderers[type].concat(dealRenderers[type]);
......
...@@ -7,8 +7,20 @@ var Renderer = KityMinder.Renderer = kity.createClass('Renderer', { ...@@ -7,8 +7,20 @@ var Renderer = KityMinder.Renderer = kity.createClass('Renderer', {
throw new Error('Not implement: Renderer.create()'); throw new Error('Not implement: Renderer.create()');
}, },
shouldRender: function() {
return true;
},
update: function() { update: function() {
throw new Error('Not implement: Renderer.update()'); 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, { ...@@ -23,42 +35,73 @@ kity.extendClass(Minder, {
_createRendererForNode: function(node) { _createRendererForNode: function(node) {
var registered = this._renderers; var registered = this._renderers;
var renderers = []; var renderers = [];
renderers = renderers.concat(registered.center);
renderers = renderers.concat(registered.left); ['center', 'left', 'top', 'bottom', 'outline', 'outside'].forEach(function(section) {
renderers = renderers.concat(registered.right); if (registered['before' + section]) {
renderers = renderers.concat(registered.top); renderers = renderers.concat(registered['before' + section]);
renderers = renderers.concat(registered.bottom); }
renderers = renderers.concat(registered.outline); if (registered[section]) {
renderers = renderers.concat(registered.outside); renderers = renderers.concat(registered[section]);
}
if (registered['after' + section]) {
renderers = renderers.concat(registered['after' + section]);
}
});
node._renderers = renderers.map(function(Renderer) { node._renderers = renderers.map(function(Renderer) {
var renderer = new Renderer(node); return new Renderer(node);
renderer.create(node);
return renderer;
}); });
}, },
renderNode: function(node) { renderNode: function(node) {
var rendererClasses = this._renderers, var rendererClasses = this._renderers;
g = KityMinder.Geometry, var g = KityMinder.Geometry;
contentBox = node._contentBox = g.wrapBox({ var i, latestBox, renderer;
left: 0,
right: 0,
top: 0,
bottom: 0
});
var i, latestBox;
if (!node._renderers) { if (!node._renderers) {
this._createRendererForNode(node); this._createRendererForNode(node);
} }
for (i = 0; i < node._renderers.length; i++) { node._contentBox = g.wrapBox({
latestBox = node._renderers[i].update(node, contentBox); left: 0,
if (latestBox) { right: 0,
node._contentBox = contentBox = g.mergeBox(contentBox, latestBox); 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', { this.fire('noderender', {
node: node node: node
...@@ -74,7 +117,7 @@ kity.extendClass(MinderNode, { ...@@ -74,7 +117,7 @@ kity.extendClass(MinderNode, {
getRenderer: function(type) { getRenderer: function(type) {
var rs = this._renderers; var rs = this._renderers;
for (var i = 0; i < rs.length; i++) { 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; return null;
}, },
......
KityMinder.registerModule('basestylemodule', function() { KityMinder.registerModule('basestylemodule', function() {
var km = this; 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 { return {
'commands': { 'commands': {
'bold': kity.createClass('boldCommand', { 'bold': kity.createClass('boldCommand', {
......
...@@ -20,7 +20,7 @@ KityMinder.registerModule('TextEditModule', function() { ...@@ -20,7 +20,7 @@ KityMinder.registerModule('TextEditModule', function() {
km.textEditNode = function(node) { km.textEditNode = function(node) {
var textShape = node.getTextShape(); var textShape = node.getRenderer('TextRenderer').getRenderShape();
this.setStatus('textedit'); this.setStatus('textedit');
sel.setHide(); sel.setHide();
sel.setStartOffset(0); sel.setStartOffset(0);
...@@ -72,14 +72,14 @@ KityMinder.registerModule('TextEditModule', function() { ...@@ -72,14 +72,14 @@ KityMinder.registerModule('TextEditModule', function() {
km.setStatus('normal'); km.setStatus('normal');
} }
if (node) { if (node) {
var textShape = node.getTextShape(); var textShape = node.getRenderer('TextRenderer').getRenderShape();
textShape.setStyle('cursor', 'default'); textShape.setStyle('cursor', 'default');
if (this.isSingleSelect() && node.isSelected()) { // && e.kityEvent.targetShape.getType().toLowerCase()== 'text' if (this.isSingleSelect() && node.isSelected()) { // && e.kityEvent.targetShape.getType().toLowerCase()== 'text'
sel.collapse(); sel.collapse();
sel.setSelectionShowStatus(true); sel.setSelectionShowStatus(true);
node.getTextShape().setStyle('cursor', 'text'); node.getRenderer('TextRenderer').getRenderShape().setStyle('cursor', 'text');
km.setStatus('textedit'); km.setStatus('textedit');
receiver.setTextEditStatus(true) receiver.setTextEditStatus(true)
.setSelection(sel) .setSelection(sel)
...@@ -140,7 +140,7 @@ KityMinder.registerModule('TextEditModule', function() { ...@@ -140,7 +140,7 @@ KityMinder.registerModule('TextEditModule', function() {
!orgEvt.altKey) { !orgEvt.altKey) {
//准备输入状态 //准备输入状态
var textShape = node.getTextShape(); var textShape = node.getRenderer('TextRenderer').getRenderShape();
sel.setHide(); sel.setHide();
sel.setStartOffset(0); sel.setStartOffset(0);
...@@ -184,7 +184,7 @@ KityMinder.registerModule('TextEditModule', function() { ...@@ -184,7 +184,7 @@ KityMinder.registerModule('TextEditModule', function() {
if (node) { if (node) {
if (this.isSingleSelect() && node.isSelected()) { if (this.isSingleSelect() && node.isSelected()) {
//准备输入状态 //准备输入状态
var textShape = node.getTextShape(); var textShape = node.getRenderer('TextRenderer').getRenderShape();
sel.setHide(); sel.setHide();
sel.setStartOffset(0); sel.setStartOffset(0);
...@@ -247,7 +247,7 @@ KityMinder.registerModule('TextEditModule', function() { ...@@ -247,7 +247,7 @@ KityMinder.registerModule('TextEditModule', function() {
'restoreScene': function() { 'restoreScene': function() {
var node = this.getSelectedNode(); var node = this.getSelectedNode();
if (node && this.isSingleSelect()) { if (node && this.isSingleSelect()) {
var textShape = node.getTextShape(); var textShape = node.getRenderer('TextRenderer').getRenderShape();
sel.setHide(); sel.setHide();
sel.setStartOffset(0); sel.setStartOffset(0);
sel.setEndOffset(textShape.getContent().length); sel.setEndOffset(textShape.getContent().length);
...@@ -292,10 +292,10 @@ KityMinder.registerModule('TextEditModule', function() { ...@@ -292,10 +292,10 @@ KityMinder.registerModule('TextEditModule', function() {
return; return;
} }
var textShape = node.getTextShape(); var textShape = node.getRenderer('TextRenderer').getRenderShape();
textShape.setStyle('cursor', 'default'); textShape.setStyle('cursor', 'default');
node.getTextShape().setStyle('cursor', 'text'); node.getRenderer('TextRenderer').getRenderShape().setStyle('cursor', 'text');
km.setStatus('textedit'); km.setStatus('textedit');
receiver.setTextEditStatus(true) receiver.setTextEditStatus(true)
.setSelection(sel) .setSelection(sel)
......
...@@ -107,7 +107,7 @@ Minder.Receiver = kity.createClass('Receiver', { ...@@ -107,7 +107,7 @@ Minder.Receiver = kity.createClass('Receiver', {
me.setContainerStyle(); me.setContainerStyle();
me.minderNode.render().layout(); me.minderNode.render().layout();
me.textShape = me.minderNode.getTextShape(); me.textShape = me.minderNode.getRenderer('TextRenderer').getRenderShape();
if (text.length === 0) { if (text.length === 0) {
me.textShape.setOpacity(0); me.textShape.setOpacity(0);
} }
......
...@@ -177,7 +177,7 @@ KityMinder.registerModule('Expand', function() { ...@@ -177,7 +177,7 @@ KityMinder.registerModule('Expand', function() {
} }
}); });
var ExpanderRenderer = kity.createClass('Expander', { var ExpanderRenderer = kity.createClass('ExpanderRenderer', {
base: Renderer, base: Renderer,
create: function(node) { create: function(node) {
...@@ -186,15 +186,20 @@ KityMinder.registerModule('Expand', function() { ...@@ -186,15 +186,20 @@ KityMinder.registerModule('Expand', function() {
node.getRenderContainer().addShape(this.expander); node.getRenderContainer().addShape(this.expander);
node.expanderRenderer = this; node.expanderRenderer = this;
this.node = node; this.node = node;
return this.expander;
}, },
update: function(node) { shouldRender: function(node) {
return !node.isRoot();
},
update: function(expander, node, box) {
if (!node.parent) return; if (!node.parent) return;
var visible = node.parent.isExpanded(); var visible = node.parent.isExpanded();
node.getRenderContainer().setVisible(visible); 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; var x, y;
...@@ -222,8 +227,8 @@ KityMinder.registerModule('Expand', function() { ...@@ -222,8 +227,8 @@ KityMinder.registerModule('Expand', function() {
}, },
events: { events: {
'layoutapply': function(e) { 'layoutapply': function(e) {
var r = e.node.getRenderer(ExpanderRenderer); var r = e.node.getRenderer('ExpanderRenderer');
r.update(e.node); r.update(r.getRenderShape(), e.node);
} }
}, },
renderers: { renderers: {
......
KityMinder.registerModule("fontmodule", function() { 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 { return {
defaultOptions: { defaultOptions: {
......
...@@ -9,18 +9,17 @@ KityMinder.registerModule('OutlineModule', function() { ...@@ -9,18 +9,17 @@ KityMinder.registerModule('OutlineModule', function() {
base: Renderer, base: Renderer,
create: function(node) { create: function(node) {
var group = new kity.Group();
var outline = this.outline = new kity.Rect() var outline = this.outline = new kity.Rect()
.setId(KityMinder.uuid('node_outline')); .setId(KityMinder.uuid('node_outline'));
var bg = this.bg = new kity.Rect() var shadow = this.shadow = new kity.Rect()
.setId(KityMinder.uuid('node_shadow')) .setId(KityMinder.uuid('node_shadow'))
.fill('black') .fill('black')
.setOpacity(0.2); .setOpacity(0.2);
node.getRenderContainer() group.addShapes([shadow, outline]);
.prependShape(outline)
.prependShape(bg);
if (wireframe) { if (wireframe) {
var oxy = this.oxy = new kity.Path() var oxy = this.oxy = new kity.Path()
...@@ -30,22 +29,28 @@ KityMinder.registerModule('OutlineModule', function() { ...@@ -30,22 +29,28 @@ KityMinder.registerModule('OutlineModule', function() {
var box = this.wireframe = new kity.Rect() var box = this.wireframe = new kity.Rect()
.stroke('lightgreen'); .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 contentBox = node.getContentBox();
var paddingLeft = node.getStyle('padding-left'), var paddingLeft = node.getStyle('padding-left'),
paddingRight = node.getStyle('padding-right'), paddingRight = node.getStyle('padding-right'),
paddingTop = node.getStyle('padding-top'), paddingTop = node.getStyle('padding-top'),
paddingBottom = node.getStyle('padding-bottom'); paddingBottom = node.getStyle('padding-bottom');
var outlineBox = { var outlineBox = {
x: contentBox.x - paddingLeft, x: contentBox.x - paddingLeft,
y: contentBox.y - paddingTop, y: contentBox.y - paddingTop,
width: contentBox.width + paddingLeft + paddingRight, width: contentBox.width + paddingLeft + paddingRight,
height: contentBox.height + paddingTop + paddingBottom height: contentBox.height + paddingTop + paddingBottom
}; };
this.outline this.outline
.setPosition(outlineBox.x, outlineBox.y) .setPosition(outlineBox.x, outlineBox.y)
.setSize(outlineBox.width, outlineBox.height) .setSize(outlineBox.width, outlineBox.height)
...@@ -55,13 +60,13 @@ KityMinder.registerModule('OutlineModule', function() { ...@@ -55,13 +60,13 @@ KityMinder.registerModule('OutlineModule', function() {
node.getStyle('background')); node.getStyle('background'));
if (node.getLevel() < 2) { if (node.getLevel() < 2) {
this.bg this.shadow
.setVisible(true) .setVisible(true)
.setPosition(outlineBox.x + 3, outlineBox.y + 4) .setPosition(outlineBox.x + 3, outlineBox.y + 4)
.setSize(outlineBox.width, outlineBox.height) .setSize(outlineBox.width, outlineBox.height)
.setRadius(node.getStyle('radius')); .setRadius(node.getStyle('radius'));
} else { } else {
this.bg.setVisible(false); this.shadow.setVisible(false);
} }
if (wireframe) { if (wireframe) {
......
...@@ -84,23 +84,19 @@ KityMinder.registerModule('PriorityModule', function() { ...@@ -84,23 +84,19 @@ KityMinder.registerModule('PriorityModule', function() {
base: KityMinder.Renderer, base: KityMinder.Renderer,
create: function(node) { create: function(node) {
this.priority = new PriorityIcon(); return new PriorityIcon();
node.getRenderContainer().addShape(this.priority);
}, },
update: function(node, box) { shouldRender: function(node) {
var data = node.getData(PRIORITY_DATA); return node.getData(PRIORITY_DATA);
var spaceLeft = node.getStyle('space-left'); },
var icon = this.priority;
var x, y;
if (!data) {
icon.setVisible(false);
return null;
}
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; x = box.left - icon.width - spaceLeft;
y = -icon.height / 2; y = -icon.height / 2;
......
...@@ -77,23 +77,19 @@ KityMinder.registerModule('ProgressModule', function() { ...@@ -77,23 +77,19 @@ KityMinder.registerModule('ProgressModule', function() {
base: KityMinder.Renderer, base: KityMinder.Renderer,
create: function(node) { create: function(node) {
this.progress = new ProgressIcon(); return new ProgressIcon();
node.getRenderContainer().addShape(this.progress);
}, },
update: function(node) { shouldRender: function(node) {
return node.getData(PROGRESS_DATA);
},
update: function(icon, node, box) {
var data = node.getData(PROGRESS_DATA); var data = node.getData(PROGRESS_DATA);
var spaceLeft = node.getStyle('space-left'); var spaceLeft = node.getStyle('space-left');
var icon = this.progress;
var box = node.getContentBox();
var x, y; var x, y;
if (!data) { icon.setValue(data);
icon.setVisible(false);
return null;
}
icon.setVisible(true).setValue(data);
x = box.left - icon.width - spaceLeft; x = box.left - icon.width - spaceLeft;
y = -icon.height / 2; y = -icon.height / 2;
......
/* global Renderer: true */ /* global Renderer: true */
kity.extendClass(MinderNode, { var TextRenderer = KityMinder.TextRenderer = kity.createClass('TextRenderer', {
getTextShape: function() { base: Renderer,
return this._textShape;
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', { utils.extend(TextRenderer, {
'renderers': { _styleHooks: [],
center: kity.createClass('TextRenderer', {
base: Renderer,
create: function(node) {
var textShape = new kity.Text().setId(KityMinder.uuid('node_text'));
node.getRenderContainer().addShape(textShape);
node._textShape = textShape; registerStyleHook: function(fn) {
}, TextRenderer._styleHooks.push(fn);
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();
} 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