Commit 00fae476 authored by techird's avatar techird

release-1.2.1

parents 241a3f58 bd435c0a
.idea
.DS_Store
*.sublime-project
*.sublime-workspace
node_modules/
\ No newline at end of file
node_modules/
_drafts/
\ No newline at end of file
# KityMinder 更新日志
## v1.2.1
### 体验优化
1. 较大提升了文件载入和操作的性能
2. 拖动时不显示子节点和连接线
3. 文字输入细节体验优化
4. 历史回退使用动画回退
5. 美化帮助窗口的样式
### BUG 修复
1. 修复 F2 不能编辑的 BUG
2. 修复按 Shift + Tab 页面溢出的 BUG
## v1.2.0
### 新功能
......@@ -20,6 +35,7 @@
4. 添加了布局时的动画效果
5. 扩大了超链接的点击范围
6. 优先级增加至 9 个,进度增加至 9 个
7. 支持ipad编辑
### BUG 修复
......
( function () {
var helpContent = '<div class="help-content" style="padding:20px;width:360px;">';
helpContent += '<h2>基本操作</h2>';
helpContent += '<p>编辑脑图的时候,最基本的操作是插入节点、编辑节点、删除节点、设置节点样式</p>';
helpContent += '<ul>';
helpContent += ' <li><h3>插入子节点:</h3>在选中的节点中按 Tab 键</li>';
helpContent += ' <li><h3>插入同级节点:</h3>在选中的节点中按 Enter/Return 键</li>';
helpContent += ' <li><h3>编辑节点:</h3>选中节点直接输入文字、双击节点或选中节点按F2键均可进入编辑模式</li>';
helpContent += ' <li><h3>设置节点文本格式:</h3>你可以选中一个或多个节点后,在工具栏中改变选中节点的文本格式。也可以使用快捷键来使用这些功能:撤销(Ctrl+Z)、重做(Ctrl+Y)、加粗(Ctrl+B)、斜体(Ctrl+I)</li>';
helpContent += ' <li><h3>添加标签:</h3>选中节点,点击工具栏上的‘添加标签’按钮可以为节点添加/删除标签</li>';
helpContent += ' <li><h3>添加/删除超链接:</h3>选中节点,点击工具栏上的‘添加超链接’/‘删除超链接’按钮可以为节点添加、删除超链接</li>';
helpContent += '</ul>';
helpContent += '<h2>导入导出</h2>';
helpContent += '<p>您可以导出你的脑图到本地,方法是点击工具栏上的导出按钮,然后选择要导出的格式。下面列出支持的格式列表:</p>';
helpContent += '<ul>';
helpContent += ' <li><h3>大纲文本:</h3>导出成以制表符界定大纲的文本,此格式可以被导入</li>';
helpContent += ' <li><h3>KityMinder格式:</h3>KityMinder自身的保存格式(JSON),此格式可以被导入</li>';
helpContent += ' <li><h3>PNG 图片:</h3>导出成 PNG 位图格式,此格式不可被导入</li>';
helpContent += ' <li><h3>SVG 矢量图:</h3>导出成 SVG 矢量图格式,可以被矢量工具二次加工,此格式不可被导入</li>';
helpContent += '</ul>';
helpContent += '<p>导出的文件可以直接拖放到 KityMinder 上直接打开</p>';
helpContent += '<h2>云盘功能</h2>';
helpContent += '<p>使用百度账号登录后,您可以使用云存储和分享功能</p>';
helpContent += '<ul>';
helpContent += ' <li><h3>登录:</h3>点击登录按钮</li>';
helpContent += ' <li><h3>保存(CTRL+S):</h3>点击保存按钮,将会把文件保存到你的云盘里</li>';
helpContent += ' <li><h3>分享(CTRL+SHIFT+S):</h3>点击分享按钮,会生成分享链接,该链接可以打开您分享的脑图</li>';
helpContent += ' <li><h3>打开:</h3>点击您账号的下拉按钮,会列出最近保存的脑图文件,点击即可打开</li>';
helpContent += '</ul>';
helpContent += '<h2>视野导航</h2>';
helpContent += '<p>视野导航包括以下几个功能:</p>';
helpContent += '<ul>';
helpContent += ' <li><h3>视野拖动:</h3>根节点未被选中的情况下,拖动根节点可以拖动视野;或者使用空格键切换拖动状态</li>';
helpContent += ' <li><h3>视野缩放:</h3>点击工具栏中的“放大”和“缩小”按钮可以缩放视野,或者按着 Ctrl 键使用滚轮缩放</li>';
helpContent += ' <li><h3>视野复位:</h3>双击空白处,可以将视野复位</li>';
helpContent += ' <li><h3>展开/收起节点:</h3>选中单个节点,点击工具栏中的“展开节点”和“收起节点”按钮可以展开/收起节点下的全部子节点</li>';
helpContent += '</ul>';
helpContent += '</div>';
KM.registerWidget( 'help', {
tpl: helpContent,
initContent: function ( km ) {
var lang = km.getLang( 'dialogs.help' ),
html;
if ( lang ) {
html = $.parseTmpl( this.tpl, lang );
(function() {
// 用于存储整个快捷菜单的机构信息的字符串
var helpInfo = '';
$.ajax({
type: 'get',
dataType: 'text',
url: 'dialogs/help/operation.txt',
success: function(text) {
createHelpHtml(text);
}
});
function createHelpHtml(text) {
var txt = text;
// 用于存储获取的某一行数据
var line = '';
// 用于临时存储处理一条line字符串之后的结果
var result = '';
// 判断是否为第一个份菜单,用于控制div.shortcuts-table标签前是否添加</div>。
var isFirstTable = true;
// // 判断是否为每份菜单的第一项
// var isFirstTr = true;
// 正则表达式 start
// 1、匹配菜单分类标题
var reg_thead = /^##/g;
// 2、匹配菜单项
var reg_tcell = /\:/g;
// 3、匹配键值
var reg_key = /\`(.+?)\`/g;
// var 4、匹配快捷键组合选择
var reg_opt = /or|\+|,/gi;
// 菜单分类标题1
var temp = '';
var xmlhttp;
var arr, keys, info;
// help-container start
helpInfo += '<div class="help-container' + (kity.Browser.mac ? ' mac' : '') + '">';
// help-header start
helpInfo += '<h2 class="help-header">操作说明</h2>';
// help-header end
// help-article start
helpInfo += '<div class="help-article row">';
// 开始读取operation.txt文件信息
txt.split('\n').forEach(function(line) {
result = '';
// 如果line以##开头,表明是菜单分类标题
if (reg_thead.test(line)) {
// isFirstTr = true;
// 如果不是第一个分类菜单,那么就需要在添加下一个开始标签之前,为上一个菜单添加结束标签
if (!isFirstTable) {
result += '</table>';
}
// 处理第一个分类菜单后,就需要把标示第一个分类菜单的变量改变
else {
isFirstTable = false;
}
temp = line.substring(line.lastIndexOf(' '));
result += '<table class="shortcuts-table "><tr><td></td><td><span class="shortcuts-thead">' + temp + '</span></td>';
} else if (/\S/.test(line)) {
// else if(reg_tcell.test(line)) {
result += '<tr class="shortcuts-tbody"><td class="shortcuts-group"><div class="right">';
arr = line.split(':');
keys = arr[0];
info = arr[1];
keys = keys.toLowerCase().replace(reg_key, '<span class="shortcuts-key label $1">$1</span>');
result += keys;
result += '</div></td><td class="shortcuts-use">' + info + '</td>';
// 加最后一项的结尾标签
result += '</tr>';
}
// 处理完每一行之后,将result添加到helpInfo之后
helpInfo += result;
result = '';
});
// 要在处理完最后一个分类菜单后,为这个菜单添加结束标签
helpInfo += '<table>';
// 读取operation.txt文件信息完毕
helpInfo += '</div>';
// help-article end
helpInfo += '</div>';
// // help-container end
// $("#help").html(helpInfo);
KM.registerWidget('help', {
tpl: helpInfo,
initContent: function(km) {
var lang = km.getLang('dialogs.help'),
html;
if (lang) {
html = $.parseTmpl(this.tpl, lang);
}
this.root().html(html);
},
initEvent: function(km, $w) {
}
this.root().html( html );
},
initEvent: function ( km, $w ) {},
width: 400
} );
} )();
\ No newline at end of file
});
}
})();
\ No newline at end of file
## 节点操作
`Enter`: 插入兄弟节点
`Tab`: 插入子节点
`Delete`: 删除节点
`Up`, `Down`, `Left`, `Right`: 节点导航
`Alt` + `Up`, `Alt` + `Down`: 向上/向下调整顺序
`/`: 展开/收起节点
`F2`: 编辑节点
`Ctrl` + `A`: 全选节点
`Ctrl` + `C`: 复制节点
`Ctrl` + `X`: 剪切节点
`Ctrl` + `V`: 粘贴节点
`Ctrl` + `B`: 加粗
`Ctrl` + `I`: 斜体
## 视野控制
`Space`: 切换编辑/抓手模式
`滚轮`: 移动视野
`右键拖动`: 拖动视野
`空白处双击`: 居中根节点
`+`, `-`: 放大/缩小视野
## 文件操作
`Ctrl` + `N`: 新建
`Ctrl` + `S`: 保存
`Ctrl` + `Shift` + `S`: 分享
## 后悔药
`Ctrl` + `Z`: 撤销
`Ctrl` + `Y`: 重做
\ No newline at end of file
( function () {
var helpContent = '<div class="help-content" style="padding:20px;width:360px;">';
helpContent += '<h2>基本操作</h2>';
helpContent += '<p>编辑脑图的时候,最基本的操作是插入节点、编辑节点、删除节点、设置节点样式</p>';
helpContent += '<ul>';
helpContent += ' <li><h3>插入子节点:</h3>在选中的节点中按 Tab 键</li>';
helpContent += ' <li><h3>插入同级节点:</h3>在选中的节点中按 Enter/Return 键</li>';
helpContent += ' <li><h3>编辑节点:</h3>选中节点直接输入文字、双击节点或选中节点按F2键均可进入编辑模式</li>';
helpContent += ' <li><h3>设置节点文本格式:</h3>你可以选中一个或多个节点后,在工具栏中改变选中节点的文本格式。也可以使用快捷键来使用这些功能:撤销(Ctrl+Z)、重做(Ctrl+Y)、加粗(Ctrl+B)、斜体(Ctrl+I)</li>';
helpContent += ' <li><h3>添加标签:</h3>选中节点,点击工具栏上的‘添加标签’按钮可以为节点添加/删除标签</li>';
helpContent += ' <li><h3>添加/删除超链接:</h3>选中节点,点击工具栏上的‘添加超链接’/‘删除超链接’按钮可以为节点添加、删除超链接</li>';
helpContent += '</ul>';
helpContent += '<h2>导入导出</h2>';
helpContent += '<p>您可以导出你的脑图到本地,方法是点击工具栏上的导出按钮,然后选择要导出的格式。下面列出支持的格式列表:</p>';
helpContent += '<ul>';
helpContent += ' <li><h3>大纲文本:</h3>导出成以制表符界定大纲的文本,此格式可以被导入</li>';
helpContent += ' <li><h3>KityMinder格式:</h3>KityMinder自身的保存格式(JSON),此格式可以被导入</li>';
helpContent += ' <li><h3>PNG 图片:</h3>导出成 PNG 位图格式,此格式不可被导入</li>';
helpContent += ' <li><h3>SVG 矢量图:</h3>导出成 SVG 矢量图格式,可以被矢量工具二次加工,此格式不可被导入</li>';
helpContent += '</ul>';
helpContent += '<p>导出的文件可以直接拖放到 KityMinder 上直接打开</p>';
helpContent += '<h2>云盘功能</h2>';
helpContent += '<p>使用百度账号登录后,您可以使用云存储和分享功能</p>';
helpContent += '<ul>';
helpContent += ' <li><h3>登录:</h3>点击登录按钮</li>';
helpContent += ' <li><h3>保存(CTRL+S):</h3>点击保存按钮,将会把文件保存到你的云盘里</li>';
helpContent += ' <li><h3>分享(CTRL+SHIFT+S):</h3>点击分享按钮,会生成分享链接,该链接可以打开您分享的脑图</li>';
helpContent += ' <li><h3>打开:</h3>点击您账号的下拉按钮,会列出最近保存的脑图文件,点击即可打开</li>';
helpContent += '</ul>';
helpContent += '<h2>视野导航</h2>';
helpContent += '<p>视野导航包括以下几个功能:</p>';
helpContent += '<ul>';
helpContent += ' <li><h3>视野拖动:</h3>根节点未被选中的情况下,拖动根节点可以拖动视野;或者使用空格键切换拖动状态</li>';
helpContent += ' <li><h3>视野缩放:</h3>点击工具栏中的“放大”和“缩小”按钮可以缩放视野,或者按着 Ctrl 键使用滚轮缩放</li>';
helpContent += ' <li><h3>视野复位:</h3>双击空白处,可以将视野复位</li>';
helpContent += ' <li><h3>展开/收起节点:</h3>选中单个节点,点击工具栏中的“展开节点”和“收起节点”按钮可以展开/收起节点下的全部子节点</li>';
helpContent += '</ul>';
helpContent += '</div>';
KM.registerWidget( 'help', {
tpl: helpContent,
initContent: function ( km ) {
var lang = km.getLang( 'dialogs.help' ),
html;
if ( lang ) {
html = $.parseTmpl( this.tpl, lang );
(function() {
// 用于存储整个快捷菜单的机构信息的字符串
var helpInfo = '';
$.ajax({
type: 'get',
dataType: 'text',
url: 'dialogs/help/operation.txt',
success: function(text) {
createHelpHtml(text);
}
});
function createHelpHtml(text) {
var txt = text;
// 用于存储获取的某一行数据
var line = '';
// 用于临时存储处理一条line字符串之后的结果
var result = '';
// 判断是否为第一个份菜单,用于控制div.shortcuts-table标签前是否添加</div>。
var isFirstTable = true;
// // 判断是否为每份菜单的第一项
// var isFirstTr = true;
// 正则表达式 start
// 1、匹配菜单分类标题
var reg_thead = /^##/g;
// 2、匹配菜单项
var reg_tcell = /\:/g;
// 3、匹配键值
var reg_key = /\`(.+?)\`/g;
// var 4、匹配快捷键组合选择
var reg_opt = /or|\+|,/gi;
// 菜单分类标题1
var temp = '';
var xmlhttp;
var arr, keys, info;
// help-container start
helpInfo += '<div class="help-container' + (kity.Browser.mac ? ' mac' : '') + '">';
// help-header start
helpInfo += '<h2 class="help-header">操作说明</h2>';
// help-header end
// help-article start
helpInfo += '<div class="help-article row">';
// 开始读取operation.txt文件信息
txt.split('\n').forEach(function(line) {
result = '';
// 如果line以##开头,表明是菜单分类标题
if (reg_thead.test(line)) {
// isFirstTr = true;
// 如果不是第一个分类菜单,那么就需要在添加下一个开始标签之前,为上一个菜单添加结束标签
if (!isFirstTable) {
result += '</table>';
}
// 处理第一个分类菜单后,就需要把标示第一个分类菜单的变量改变
else {
isFirstTable = false;
}
temp = line.substring(line.lastIndexOf(' '));
result += '<table class="shortcuts-table "><tr><td></td><td><span class="shortcuts-thead">' + temp + '</span></td>';
} else if (/\S/.test(line)) {
// else if(reg_tcell.test(line)) {
result += '<tr class="shortcuts-tbody"><td class="shortcuts-group"><div class="right">';
arr = line.split(':');
keys = arr[0];
info = arr[1];
keys = keys.toLowerCase().replace(reg_key, '<span class="shortcuts-key label $1">$1</span>');
result += keys;
result += '</div></td><td class="shortcuts-use">' + info + '</td>';
// 加最后一项的结尾标签
result += '</tr>';
}
// 处理完每一行之后,将result添加到helpInfo之后
helpInfo += result;
result = '';
});
// 要在处理完最后一个分类菜单后,为这个菜单添加结束标签
helpInfo += '<table>';
// 读取operation.txt文件信息完毕
helpInfo += '</div>';
// help-article end
helpInfo += '</div>';
// // help-container end
// $("#help").html(helpInfo);
KM.registerWidget('help', {
tpl: helpInfo,
initContent: function(km) {
var lang = km.getLang('dialogs.help'),
html;
if (lang) {
html = $.parseTmpl(this.tpl, lang);
}
this.root().html(html);
},
initEvent: function(km, $w) {
}
this.root().html( html );
},
initEvent: function ( km, $w ) {},
width: 400
} );
} )();
\ No newline at end of file
});
}
})();
\ No newline at end of file
## 节点操作
`Enter`: 插入兄弟节点
`Tab`: 插入子节点
`Delete`: 删除节点
`Up`, `Down`, `Left`, `Right`: 节点导航
`Alt` + `Up`, `Alt` + `Down`: 向上/向下调整顺序
`/`: 展开/收起节点
`F2`: 编辑节点
`Ctrl` + `A`: 全选节点
`Ctrl` + `C`: 复制节点
`Ctrl` + `X`: 剪切节点
`Ctrl` + `V`: 粘贴节点
`Ctrl` + `B`: 加粗
`Ctrl` + `I`: 斜体
## 视野控制
`Space`: 切换编辑/抓手模式
`滚轮`: 移动视野
`右键拖动`: 拖动视野
`空白处双击`: 居中根节点
`+`, `-`: 放大/缩小视野
## 文件操作
`Ctrl` + `N`: 新建
`Ctrl` + `S`: 保存
`Ctrl` + `Shift` + `S`: 分享
## 后悔药
`Ctrl` + `Z`: 撤销
`Ctrl` + `Y`: 重做
\ No newline at end of file
......@@ -7,26 +7,26 @@
<meta name="description" content="百度脑图,便捷的脑图编辑工具。让您在线上直接创建、保存并分享你的思路。">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<script src="lib/jquery-2.1.0.min.js?_=1404922397905" charset="utf-8"></script>
<script src="lib/ZeroClipboard.min.js?_=1404922397905" charset="utf-8"></script>
<script src="lib/jquery-2.1.0.min.js?_=1406196567611" charset="utf-8"></script>
<script src="lib/ZeroClipboard.min.js?_=1406196567611" charset="utf-8"></script>
<script type="text/javascript">
ZeroClipboard.setDefaults( { moviePath: 'lib/ZeroClipboard.swf' } );
</script>
<script src="lib/kity.min.js?_=1404922397905" charset="utf-8"></script>
<script src="kityminder.all.min.js?_=1404922397905" charset="utf-8"></script>
<script src="kityminder.config.js?_=1404922397905" charset="utf-8"></script>
<script src="lang/zh-cn/zh-cn.js?_=1404922397905" charset="utf-8"></script>
<script src="lib/kity.min.js?_=1406196567611" charset="utf-8"></script>
<script src="kityminder.all.min.js?_=1406196567611" charset="utf-8"></script>
<script src="kityminder.config.js?_=1406196567611" charset="utf-8"></script>
<script src="lang/zh-cn/zh-cn.js?_=1406196567611" charset="utf-8"></script>
<script src="lib/zip.js?_=1404922397905" charset="utf-8"></script>
<script src="lib/zip.js?_=1406196567611" charset="utf-8"></script>
<script>
zip.inflateJSPath = 'lib/inflate.js';
</script>
<script src="lib/jquery.xml2json.js?_=1404922397905" charset="utf-8"></script>
<script src="lib/baidu-frontia-js-full-1.0.0.js?_=1404922397905" charset="utf-8"></script>
<script src="social/draftmanager.js?_=1404922397905" charset="utf-8"></script>
<script src="social/social.js?_=1404922397905" charset="utf-8"></script>
<script src="lib/jquery.xml2json.js?_=1406196567611" charset="utf-8"></script>
<script src="lib/baidu-frontia-js-full-1.0.0.js?_=1406196567611" charset="utf-8"></script>
<script src="social/draftmanager.js?_=1406196567611" charset="utf-8"></script>
<script src="social/social.js?_=1406196567611" charset="utf-8"></script>
<link href="social/social.css" rel="stylesheet">
<link href="themes/default/css/import.css" type="text/css" rel="stylesheet" />
......@@ -76,24 +76,30 @@
KityMinder
<a id="km-version"
href="https://github.com/fex-team/kityminder/blob/dev/CHANGELOG.md"
target="blank">
target="blank"
tabindex="-1">
</a>
under
<a href="https://raw.githubusercontent.com/fex-team/kityminder/dev/LICENSE"
target="_blank">BSD License
target="_blank"
tabindex="-1">BSD License
</a>.
Powered by f-cube,
<a href="http://fex.baidu.com"
target="_blank">FEX
target="_blank"
tabindex="-1">FEX
</a> |
<a href="https://github.com/fex-team/kityminder.git"
target="_blank">Source
target="_blank"
tabindex="-1">Source
</a>
<a href="https://github.com/fex-team/kityminder/issues/new"
target="_blank">Bug
target="_blank"
tabindex="-1">Bug
</a> |
<a href="mailto:kity@baidu.com"
target="_blank">Contact Us
target="_blank"
tabindex="-1">Contact Us
</a>
</div>
</div>
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*!
* ====================================================
* kity - v2.0.0 - 2014-07-08
* kity - v2.0.0 - 2014-07-23
* https://github.com/fex-team/kity
* GitHub: https://github.com/fex-team/kity.git
* Copyright (c) 2014 Baidu FEX; Licensed BSD
......@@ -372,6 +372,8 @@ define("animate/frame", [], function(require, exports) {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame || function(fn) {
return setTimeout(fn, 1e3 / 60);
};
var cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame || window.webkitCancelAnimationFrame || window.msCancelAnimationFrame || window.clearTimeout;
var frameRequestId;
// 等待执行的帧的集合,这些帧的方法将在下个动画帧同步执行
var pendingFrames = [];
/**
......@@ -381,7 +383,7 @@ define("animate/frame", [], function(require, exports) {
*/
function pushFrame(frame) {
if (pendingFrames.push(frame) === 1) {
requestAnimationFrame(executePendingFrames);
frameRequestId = requestAnimationFrame(executePendingFrames);
}
}
/**
......@@ -393,6 +395,7 @@ define("animate/frame", [], function(require, exports) {
while (frames.length) {
executeFrame(frames.pop());
}
frameRequestId = 0;
}
/**
* 请求一个帧,执行指定的动作。动作回调提供一些有用的信息
......@@ -433,6 +436,9 @@ define("animate/frame", [], function(require, exports) {
if (~index) {
pendingFrames.splice(index, 1);
}
if (pendingFrames.length === 0) {
cancelAnimationFrame(frameRequestId);
}
}
/**
* 初始化一个帧,主要用于后续计算
......@@ -1661,12 +1667,12 @@ define("graphic/box", [ "core/class" ], function(require, exports, module) {
this.y = y || 0;
this.width = width || 0;
this.height = height || 0;
this.left = x;
this.left = this.x;
this.right = this.x + this.width;
this.top = this.y;
this.bottom = this.y + this.height;
this.cx = x + this.width / 2;
this.cy = y + this.height / 2;
this.cx = this.x + this.width / 2;
this.cy = this.y + this.height / 2;
},
getRangeX: function() {
return [ this.left, this.right ];
......@@ -3174,22 +3180,37 @@ define("graphic/geometry", [ "core/utils", "graphic/point", "core/class", "graph
*
* @return {Number} 贝塞尔曲线的长度
*/
g.bezierLength = cacher(function bezierLength(bezierArray, tolerate) {
// 切割成多少段来计算
tolerate = Math.max(tolerate || .001, 1e-9);
function len(p, q) {
var dx = p[0] - q[0], dy = p[1] - q[1];
return Math.sqrt(dx * dx + dy * dy);
}
var cutted, p, q, m, cuttedLength;
cutted = cutBezier(bezierArray);
p = bezierArray.slice(0, 2);
q = bezierArray.slice(6);
m = cutted[1].slice(0, 2);
cuttedLength = len(p, m) + len(m, q);
if (cuttedLength - len(p, q) < tolerate) return cuttedLength;
// 递归计算
return bezierLength(cutted[0], tolerate / 2) + bezierLength(cutted[1], tolerate / 3);
g.bezierLength = cacher(function bezierLength(bezierArray) {
// 表示(c[0]*t^4 + c[1]*t^3 + c[2]*t^2 + c[3]*t^1 + c[4])^(1/2)的函数
function f(x) {
var m = c0 * Math.pow(x, 4) + c1 * Math.pow(x, 3) + c2 * Math.pow(x, 2) + c3 * x + c4;
if (m < 0) {
m = 0;
}
return Math.pow(m, .5);
}
// 用Newton-Cotes型求积公式
var arr = bezierArray;
// 三次贝塞尔曲线函数求导后,求出对应的方程系数,用cx[],cy[]表示x`(t)和y`(t)的系数
var cx0, cx1, cx2;
var cy0, cy1, cy2;
// 用c[]表示x`(t)^2 + y`(t)^2的结果的系数
var c0, c1, c2, c3, c4;
// 求x`(t) 和 y`(t)的系数
cx0 = -3 * arr[0] + 9 * arr[2] - 9 * arr[4] + 3 * arr[6];
cx1 = 6 * arr[0] - 12 * arr[2] + 6 * arr[4];
cx2 = -3 * arr[0] + 3 * arr[2];
cy0 = -3 * arr[1] + 9 * arr[3] - 9 * arr[5] + 3 * arr[7];
cy1 = 6 * arr[1] - 12 * arr[3] + 6 * arr[5];
cy2 = -3 * arr[1] + 3 * arr[3];
// 求x`(t)^2 + y`(t)^2的结果的系数 c[]
c0 = Math.pow(cx0, 2) + Math.pow(cy0, 2);
c1 = 2 * (cx0 * cx1 + cy0 * cy1);
c2 = 2 * (cx0 * cx2 + cy0 * cy2) + Math.pow(cx1, 2) + Math.pow(cy1, 2);
c3 = 2 * (cx1 * cx2 + cy1 * cy2);
c4 = Math.pow(cx2, 2) + Math.pow(cy2, 2);
// 用cotes积分公式求值
return (f(0) + f(1) + 4 * (f(.125) + f(.375) + f(.625) + f(.875)) + 2 * (f(.25) + f(.5) + f(.75))) / 24;
});
// 计算一个 pathSegment 中每一段的在整体中所占的长度范围,以及总长度
// 方法要求每一段都是贝塞尔曲线
......@@ -5171,6 +5192,7 @@ define("graphic/shape", [ "graphic/svg", "core/utils", "graphic/eventhandler", "
} else {
this.node.setAttribute(a, v);
}
return this;
},
getAttr: function(a) {
return this.node.getAttribute(a);
......@@ -6025,9 +6047,15 @@ define("graphic/use", [ "graphic/svg", "core/class", "graphic/shape", "core/util
var Use = Class.createClass("Use", {
base: require("graphic/shape"),
constructor: function(shape) {
var shapeId = null;
this.callBase("use");
shapeId = shape.getId();
this.ref(shape);
},
ref: function(shape) {
if (!shape) {
this.node.removeAttributeNS(Svg.xlink, "xlink:href");
return this;
}
var shapeId = shape.getId();
if (shapeId) {
this.node.setAttributeNS(Svg.xlink, "xlink:href", "#" + shapeId);
}
......@@ -6039,6 +6067,7 @@ define("graphic/use", [ "graphic/svg", "core/class", "graphic/shape", "core/util
if (shape.node.getAttribute("stroke") === "none") {
shape.node.removeAttribute("stroke");
}
return this;
}
});
var Shape = require("graphic/shape");
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This diff is collapsed.
......@@ -740,8 +740,9 @@ $(function() {
// 确定上传文件名
if (!remotePath) {
filename = window.prompt('请输入文件名: ', minder.getMinderTitle());
filename = window.prompt('请输入文件名: ', minder.getMinderTitle().replace(/[\/\\\:\?\|\<\>\"\'\*]/g, ''));
if (!filename) return;
filename = filename.replace(/[\/\\\:\?\|\<\>\"\'\*]/g, '');
uploadPath = generateRemotePath(filename);
} else {
uploadPath = remotePath;
......
.help-content{
line-height: 20px;
font-size: 12px;
}
.help-content ul{
list-style: none;
padding:0;
}
.help-content ul li{
color:#666;
}
.help-content h2{color:#333;font-size: 18px;}
.help-content h3{
color:#333;
display: inline;
font-size: 14px;
.blur {
-webkit-filter: blur(5px);
-moz-filter: blur(5px);
-mz-filter: blur(5px);
-o-filter: blur(5px);
filter: blur(5px);
filter: url(../images/blur.svg#blur);
/* transition: all ease 0.5s; */
}
.kmui-modal.kmui-dialog-help .kmui-modal-header {
display: none;
}
.kmui-modal.kmui-dialog-help .kmui-modal-body {
position: fixed;
left: 0;
top: 85px;
right: 0;
bottom: 0;
max-height: 1000000px;
background: hsla(222, 14%, 41%, 0.8);
}
.shortcuts-opt {
margin: 0px 7px;
background-color: #fff;
font-size: 14px;
}
.shortcuts-group {
padding-right: 15px;
width: 200px;
text-shadow: none;
}
.shortcuts-thead {
font-size: 14px;
font-weight: bold;
line-height: 14px;
}
#div1 {
display: none;
}
/*.help-container {
width: 586px;
float: left;
}*/
.shortcuts-use {
width: 160px;
font-size: 14px;
font-weight: lighter;
}
.help-header {
padding-bottom: 9px;
margin: 20px 20px 30px;
border-bottom: 1px solid #EEE;
display: none;
}
.shortcuts-table {
max-width: 100%;
background-color: transparent;
border-collapse: collapse;
border-spacing: 0px;
float: left;
margin-left: 10px;
margin-top: 30px;
}
.shortcuts-table tr:first-child td span{
padding: 10px 0;
font-size: 18px;
display: block;
color: white;
}
.shortcuts-table td {
display: table-cell;
float: none;
margin-left: 0px;
padding-bottom: 7px;
}
.shortcuts-table td[colspan] {
text-align: center;
}
.shortcuts-table h2 {
font-size: 31.5px;
line-height: 40px;
}
.help-container {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 20px;
color: hsl(0, 100%, 100%);
text-shadow: 0 1px black;
margin: 30px;
}
.shortcuts-key {
display: inline-block;
padding: 3px 8px 5px;
font-size: 14px;
font-weight: normal;
line-height: 14px;
color: hsl(0, 0%, 43%);
/* text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.25); */
white-space: nowrap;
vertical-align: baseline;
background-color: hsl(0, 0%, 99%);
border-radius: 3px;
/* border: 1px solid hsl(0, 0%, 60%); */
text-transform: capitalize;
box-shadow: inset 0 -2px hsl(0, 0%, 92%), inset 0 -3px hsl(0, 100%, 100%), 0 1px 2px rgba(255, 255, 255, 0.3);
}
.mac .shortcuts-key.ctrl,
.mac .shortcuts-key.shift,
.mac .shortcuts-key.alt,
.shortcuts-key.up,
.shortcuts-key.down,
.shortcuts-key.left,
.shortcuts-key.right {
text-indent: -1000px;
position: relative;
width: 9px;
}
.mac .shortcuts-key.ctrl:after,
.mac .shortcuts-key.shift:after,
.mac .shortcuts-key.alt:after,
.shortcuts-key.up:after,
.shortcuts-key.down:after,
.shortcuts-key.left:after,
.shortcuts-key.right:after {
display: block;
position: absolute;
text-align: center;
left: 5px;
top: 4px;
width: 16px;
height: 16px;
text-indent: 0;
}
.mac .shortcuts-key.ctrl:after {
content: '⌘';
}
.mac .shortcuts-key.shift:after {
content: '⇧';
}
.mac .shortcuts-key.alt:after {
content: '⌥';
}
.shortcuts-key.up:after {
content: '↑';
top: 2px;
}
.shortcuts-key.down:after {
content: '↓';
top: 2px;
}
.shortcuts-key.left:after {
content: '←';
top: 2px;
}
.shortcuts-key.right:after {
content: '→';
top: 2px;
}
div.right {
float: right;
}
\ No newline at end of file
......@@ -2,7 +2,6 @@
html, body, div {
margin: 0;
padding: 0;
margin-top: 0 !important;
}
html, body, #kityminder, div.kmui-editor-body {
overflow: hidden;
......@@ -233,7 +232,14 @@ button#share-btn:hover {
.km-minderNode{
cursor:default;
}
.kmui-container, .kmui-editor-body {
.kmui-container {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.kmui-editor-body {
position: absolute;
left: 0;
top: 0;
......
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<filter id="blur">
<feGaussianBlur stdDeviation="5" />
</filter>
</svg>
\ No newline at end of file
......@@ -76,24 +76,30 @@
KityMinder
<a id="km-version"
href="https://github.com/fex-team/kityminder/blob/dev/CHANGELOG.md"
target="blank">
target="blank"
tabindex="-1">
</a>
under
<a href="https://raw.githubusercontent.com/fex-team/kityminder/dev/LICENSE"
target="_blank">BSD License
target="_blank"
tabindex="-1">BSD License
</a>.
Powered by f-cube,
<a href="http://fex.baidu.com"
target="_blank">FEX
target="_blank"
tabindex="-1">FEX
</a> |
<a href="https://github.com/fex-team/kityminder.git"
target="_blank">Source
target="_blank"
tabindex="-1">Source
</a>
<a href="https://github.com/fex-team/kityminder/issues/new"
target="_blank">Bug
target="_blank"
tabindex="-1">Bug
</a> |
<a href="mailto:kity@baidu.com"
target="_blank">Contact Us
target="_blank"
tabindex="-1">Contact Us
</a>
</div>
</div>
......
Subproject commit 47c11b5d7977c81df1c2f1d779933d38ac6edb0e
Subproject commit fec9187f532aea5284d1fac25767dcca9ad43ce4
......@@ -2,7 +2,7 @@
"name": "kityminder",
"title": "kityminder",
"description": "Kity Minder",
"version": "1.1.3",
"version": "1.2.1",
"homepage": "https://github.com/fex-team/kityminder",
"author": {
"name": "f-cube @ FEX",
......
echo -e "\033[0;33;1mPublish start."
echo -e "\033[0;33;1m> Checking out gh-pages\033[0m"
git checkout -q gh-pages
echo -e "\033[0;33;1m> Checking out gh-pages...\033[0m"
git branch -D gh-pages -q
git checkout -q -b gh-pages
echo -e "\033[0;33;1m> Merging server changes\033[0m"
git pull origin gh-pages
echo -e "\033[0;33;1m> Delete server branch...\033[0m"
git push origin :gh-pages -q
echo -e "\033[0;33;1m> Merging dev commits\033[0m"
git merge dev -qm "merge from dev"
echo -e "\033[0;33;1m> Building dist js files\033[0m"
echo -e "\033[0;33;1m> Building dist js files...\033[0m"
grunt -q > GRUNT_OUTPUT
rm -f GRUNT_OUTPUT
echo -e "\033[0;33;1m> Commit dist js files...\033[0m"
git add dist
echo -e "\033[0;33;1m> Commit dist js files\033[0m"
git commit -qm "publish"
echo -e "\033[0;33;1m> Pusing to git...\033[0m"
......
......@@ -740,8 +740,9 @@ $(function() {
// 确定上传文件名
if (!remotePath) {
filename = window.prompt('请输入文件名: ', minder.getMinderTitle());
filename = window.prompt('请输入文件名: ', minder.getMinderTitle().replace(/[\/\\\:\?\|\<\>\"\'\*]/g, ''));
if (!filename) return;
filename = filename.replace(/[\/\\\:\?\|\<\>\"\'\*]/g, '');
uploadPath = generateRemotePath(filename);
} else {
uploadPath = remotePath;
......
......@@ -33,6 +33,16 @@ KM.registerToolbarUI('markers help preference resource', function(name) {
}
KM.setWidgetBody(name, $dialog, me);
}).attachTo($btn);
if (name == 'help') {
$dialog.kmui().on('beforeshow', function() {
$btn.kmui().active(true);
$('.kmui-editor-body').addClass('blur');
}).on('beforehide', function() {
$btn.kmui().active(false);
$('.kmui-editor-body').removeClass('blur');
});
}
});
me.on('interactchange', function() {
......
......@@ -34,6 +34,7 @@ kity.extendClass(Minder, {
}
this._connectContainer.addShape(connection);
this.updateConnect(node);
},
removeConnect: function(node) {
......@@ -72,10 +73,10 @@ KityMinder.registerModule('Connect', {
'nodeattach': function(e) {
this.createConnect(e.node);
},
'noderemove': function(e) {
'nodedetach': function(e) {
this.removeConnect(e.node);
},
'layoutapply noderender': function(e) {
'layoutapply layoutfinish noderender': function(e) {
this.updateConnect(e.node);
}
}
......
......@@ -3,7 +3,7 @@ var KityMinder = window.KM = window.KityMinder = function() {
instanceId = 0,
uuidMap = {};
return {
version: '1.2.0',
version: '1.2.1',
uuid: function(name) {
name = name || 'unknown';
uuidMap[name] = uuidMap[name] || 0;
......
......@@ -192,7 +192,7 @@ kity.extendClass(Minder, {
},
refresh: function(duration) {
this.getRoot().preTraverse(function(node) { node.render(); });
this.getRoot().renderTree();
this.layout(duration).fire('contentchange').fire('interactchange');
return this;
},
......@@ -200,6 +200,14 @@ kity.extendClass(Minder, {
applyLayoutResult: function(root, duration) {
root = root || this.getRoot();
var me = this;
var complex = root.getComplex();
function consume() {
if (!--complex) me.fire('layoutallfinish');
}
// 节点复杂度大于 100,关闭动画
if (complex > 300) duration = 0;
function applyMatrix(node, matrix) {
node.getRenderContainer().setMatrix(node._lastLayoutTransform = matrix);
......@@ -219,39 +227,38 @@ kity.extendClass(Minder, {
matrix.m.e = Math.round(matrix.m.e);
matrix.m.f = Math.round(matrix.m.f);
if (!matrix.equals(lastMatrix) || true) {
// 如果当前有动画,停止动画
if (node._layoutTimeline) {
node._layoutTimeline.stop();
delete node._layoutTimeline;
}
// 如果要求以动画形式来更新,创建动画
if (duration > 0) {
node._layoutTimeline = new kity.Animator(lastMatrix, matrix, applyMatrix)
.start(node, duration, 'ease')
.on('finish', function() {
// 可能性能低的时候会丢帧
clearTimeout(node._lastFixTimeout);
node._lastFixTimeout = setTimeout(function() {
applyMatrix(node, matrix);
me.fire('layoutfinish', {
node: node,
matrix: matrix
});
// 如果当前有动画,停止动画
if (node._layoutTimeline) {
node._layoutTimeline.stop();
node._layoutTimeline = null;
}
// 如果要求以动画形式来更新,创建动画
if (duration) {
node._layoutTimeline = new kity.Animator(lastMatrix, matrix, applyMatrix)
.start(node, duration + 300, 'ease')
.on('finish', function() {
//可能性能低的时候会丢帧,手动添加一帧
kity.Timeline.requestFrame(function() {
applyMatrix(node, matrix);
me.fire('layoutfinish', {
node: node,
matrix: matrix
});
consume();
});
}
// 否则直接更新
else {
applyMatrix(node, matrix);
me.fire('layoutfinish', {
node: node,
matrix: matrix
});
}
}
// 否则直接更新
else {
applyMatrix(node, matrix);
me.fire('layoutfinish', {
node: node,
matrix: matrix
});
consume();
}
for (var i = 0; i < node.children.length; i++) {
......
......@@ -175,21 +175,30 @@ var Minder = KityMinder.Minder = kity.createClass('KityMinder', {
this._status = 'normal';
this._rollbackStatus = 'normal';
},
setStatus: function(status) {
if (status) {
this.fire('statuschange',{
lastStatus:this._status,
currentStatus:status
});
this._rollbackStatus = this._status;
this._status = status;
} else {
this._status = '';
}
return this;
},
setStatus: (function() {
var sf = ~window.location.href.indexOf('status');
var tf = ~window.location.href.indexOf('trace');
return function(status) {
if (status != this._status) {
this._rollbackStatus = this._status;
this._status = status;
this.fire('statuschange', {
lastStatus: this._rollbackStatus,
currentStatus: this._status
});
if (sf) {
console.log(window.event.type, this._rollbackStatus, '->', this._status);
if (tf) {
console.trace();
}
}
}
return this;
};
})(),
rollbackStatus: function() {
this._status = this._rollbackStatus;
this.setStatus(this._rollbackStatus);
},
getStatus: function() {
return this._status;
......
......@@ -7,7 +7,7 @@ kity.extendClass(Minder, {
this._commands = {};
this._query = {};
this._modules = {};
this._renderers = {};
this._rendererClasses = {};
var i, name, type, module, moduleDeals,
dealCommands, dealEvents, dealRenderers;
......@@ -51,12 +51,12 @@ kity.extendClass(Minder, {
if (dealRenderers) {
for (type in dealRenderers) {
this._renderers[type] = this._renderers[type] || [];
this._rendererClasses[type] = this._rendererClasses[type] || [];
if (Utils.isArray(dealRenderers[type])) {
this._renderers[type] = this._renderers[type].concat(dealRenderers[type]);
this._rendererClasses[type] = this._rendererClasses[type].concat(dealRenderers[type]);
} else {
this._renderers[type].push(dealRenderers[type]);
this._rendererClasses[type].push(dealRenderers[type]);
}
}
}
......
......@@ -11,47 +11,46 @@ kity.extendClass(Minder, {
createNode: function(unknown, parent, index) {
var node = new MinderNode(unknown);
this.fire('nodecreate', {
node: node
});
this.fire('nodecreate', { node: node });
this.appendNode(node,parent, index);
return node;
},
appendNode: function(node, parent, index) {
if (parent) parent.insertChild(node, index);
this.handelNodeCreate(node);
this.fire('nodeattach', {
node: node
});
this.attachNode(node);
return this;
},
removeNode: function(node) {
if (node.parent) {
node.parent.removeChild(node);
this.handelNodeRemove(node);
this.fire('noderemove', {
node: node
});
this.detachNode(node);
this.fire('noderemove', { node: node });
}
},
handelNodeCreate: function(node) {
attachNode: function(node) {
var rc = this._rc;
node.traverse(function(current) {
current.attached = true;
rc.addShape(current.getRenderContainer());
});
rc.addShape(node.getRenderContainer());
this.fire('nodeattach', {
node: node
});
},
handelNodeRemove: function(node) {
detachNode: function(node) {
var rc = this._rc;
node.traverse(function(current) {
current.attached = false;
rc.removeShape(current.getRenderContainer());
});
this.fire('nodedetach', {
node: node
});
},
getMinderTitle: function() {
......
......@@ -24,88 +24,173 @@ var Renderer = KityMinder.Renderer = kity.createClass('Renderer', {
}
});
kity.extendClass(Minder, {
kity.extendClass(Minder, (function() {
_createRendererForNode: function(node) {
var registered = this._renderers;
function createRendererForNode(node, registered) {
var renderers = [];
['center', 'left', 'right', 'top', 'bottom', 'outline', 'outside'].forEach(function(section) {
if (registered['before' + section]) {
renderers = renderers.concat(registered['before' + section]);
var before = 'before' + section;
var after = 'after' + section;
if (registered[before]) {
renderers = renderers.concat(registered[before]);
}
if (registered[section]) {
renderers = renderers.concat(registered[section]);
}
if (registered['after' + section]) {
renderers = renderers.concat(registered['after' + section]);
if (registered[after]) {
renderers = renderers.concat(registered[after]);
}
});
node._renderers = renderers.map(function(Renderer) {
return new Renderer(node);
});
},
renderNode: function(node) {
}
var rendererClasses = this._renderers;
var g = KityMinder.Geometry;
var i, latestBox, renderer;
return {
if (!node._renderers) {
this._createRendererForNode(node);
}
renderNodeBatch: function(nodes) {
var rendererClasses = this._rendererClasses;
var lastBoxes = [];
var rendererCount = 0;
var i, j, renderer, node;
this.fire('beforerender', {node: node});
if (!nodes.length) return;
node._contentBox = g.wrapBox({
left: 0,
right: 0,
top: 0,
bottom: 0
});
for (j = 0; j < nodes.length; j++) {
node = nodes[j];
if (!node._renderers) {
createRendererForNode(node, rendererClasses);
}
node._contentBox = new kity.Box();
this.fire('beforerender', {
node: node
});
}
node._renderers.forEach(function(renderer) {
// 所有节点渲染器数量是一致的
rendererCount = nodes[0]._renderers.length;
// 判断当前上下文是否应该渲染
if (renderer.shouldRender(node)) {
for (i = 0; i < rendererCount; i++) {
// 应该渲染,但是渲染图形没创建过,需要创建
if (!renderer.getRenderShape()) {
renderer.setRenderShape(renderer.create(node));
if (renderer.bringToBack) {
node.getRenderContainer().prependShape(renderer.getRenderShape());
} else {
node.getRenderContainer().appendShape(renderer.getRenderShape());
// 获取延迟盒子数据
for (j = 0; j < nodes.length; j++) {
if (typeof(lastBoxes[j]) == 'function') {
lastBoxes[j] = lastBoxes[j]();
}
if (!(lastBoxes[j] instanceof kity.Box)) {
lastBoxes[j] = new kity.Box(lastBoxes[j]);
}
}
// 强制让渲染图形显示
renderer.getRenderShape().setVisible(true);
for (j = 0; j < nodes.length; j++) {
node = nodes[j];
renderer = node._renderers[i];
// 更新渲染图形
latestBox = renderer.update(renderer.getRenderShape(), node, node._contentBox);
// 合并盒子
if (lastBoxes[j]) {
node._contentBox = node._contentBox.merge(lastBoxes[j]);
}
// 判断当前上下文是否应该渲染
if (renderer.shouldRender(node)) {
// 应该渲染,但是渲染图形没创建过,需要创建
if (!renderer.getRenderShape()) {
renderer.setRenderShape(renderer.create(node));
if (renderer.bringToBack) {
node.getRenderContainer().prependShape(renderer.getRenderShape());
} else {
node.getRenderContainer().appendShape(renderer.getRenderShape());
}
}
// 强制让渲染图形显示
renderer.getRenderShape().setVisible(true);
// 更新渲染图形
lastBoxes[j] = renderer.update(renderer.getRenderShape(), node, node._contentBox);
}
// 合并渲染区域
if (latestBox) {
node._contentBox = g.mergeBox(node._contentBox, latestBox);
// 如果不应该渲染,但是渲染图形创建过了,需要隐藏起来
else if (renderer.getRenderShape()) {
renderer.getRenderShape().setVisible(false);
lastBoxes[j] = null;
}
}
}
// 如果不应该渲染,但是渲染图形创建过了,需要隐藏起来
else if (renderer.getRenderShape()) {
renderer.getRenderShape().setVisible(false);
for (j = 0; j < nodes.length; j++) {
this.fire('noderender', {
node: nodes[j]
});
}
},
});
renderNode: function(node) {
var rendererClasses = this._rendererClasses;
var g = KityMinder.Geometry;
var i, latestBox, renderer;
this.fire('noderender', {
node: node
});
}
});
if (!node._renderers) {
createRendererForNode(node, rendererClasses);
}
this.fire('beforerender', {
node: node
});
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().appendShape(renderer.getRenderShape());
}
}
// 强制让渲染图形显示
renderer.getRenderShape().setVisible(true);
// 更新渲染图形
latestBox = renderer.update(renderer.getRenderShape(), node, node._contentBox);
if (typeof(latestBox) == 'function') latestBox = latestBox();
// 合并渲染区域
if (latestBox) {
node._contentBox = g.mergeBox(node._contentBox, latestBox);
}
}
// 如果不应该渲染,但是渲染图形创建过了,需要隐藏起来
else if (renderer.getRenderShape()) {
renderer.getRenderShape().setVisible(false);
}
});
this.fire('noderender', {
node: node
});
}
};
})());
kity.extendClass(MinderNode, {
render: function() {
......@@ -113,6 +198,15 @@ kity.extendClass(MinderNode, {
this.getMinder().renderNode(this);
return this;
},
renderTree: function() {
if (!this.attached) return;
var list = [];
this.traverse(function(node) {
list.push(node);
});
this.getMinder().renderNodeBatch(list);
return this;
},
getRenderer: function(type) {
var rs = this._renderers;
for (var i = 0; i < rs.length; i++) {
......@@ -122,6 +216,6 @@ kity.extendClass(MinderNode, {
},
getContentBox: function() {
//if (!this._contentBox) this.render();
return this.parent && this.parent.isCollapsed() ? new kity.Box() : this._contentBox;
return this.parent && this.parent.isCollapsed() ? new kity.Box() : (this._contentBox || new kity.Box());
}
});
\ No newline at end of file
......@@ -61,6 +61,7 @@ KityMinder.registerModule('TemplateModule', {
execute: function(minder, name) {
minder.useTemplate(name);
minder.execCommand('camera');
},
queryValue: function(minder) {
......
......@@ -123,6 +123,9 @@ var TreeDragger = kity.createClass('TreeDragger', {
if (!this._dragMode) {
return;
}
this._fadeDragSources(1);
if (this._dropSucceedTarget) {
this._dragSources.forEach(function(source) {
......@@ -172,6 +175,7 @@ var TreeDragger = kity.createClass('TreeDragger', {
this._calcDropTargets();
this._calcOrderHints();
this._dragMode = true;
this._minder.setStatus('dragtree');
return true;
},
......@@ -191,8 +195,16 @@ var TreeDragger = kity.createClass('TreeDragger', {
},
_fadeDragSources: function(opacity) {
var minder = this._minder;
this._dragSources.forEach(function(source) {
source.getRenderContainer().fxOpacity(opacity, 200);
source.traverse(function(node) {
if (opacity < 1) {
minder.detachNode(node);
} else {
minder.attachNode(node);
}
}, true);
});
},
......@@ -250,12 +262,12 @@ var TreeDragger = kity.createClass('TreeDragger', {
},
_leaveDragMode: function() {
this._fadeDragSources(1);
this._dragMode = false;
this._dropSucceedTarget = null;
this._orderSucceedHint = null;
this._renderDropHint(null);
this._renderOrderHint(null);
this._minder.rollbackStatus();
},
_drawForDragMode: function() {
......@@ -337,6 +349,9 @@ KityMinder.registerModule('DragTree', function() {
return {
init: function() {
dragger = new TreeDragger(this);
window.addEventListener('mouseup', function() {
dragger.dragEnd();
});
},
events: {
'normal.mousedown inputready.mousedown': function(e) {
......@@ -346,12 +361,13 @@ KityMinder.registerModule('DragTree', function() {
dragger.dragStart(e.getPosition(this.getRenderContainer()));
}
},
'normal.mousemove': function(e) {
'normal.mousemove dragtree.mousemove': function(e) {
dragger.dragMove(e.getPosition(this.getRenderContainer()));
},
'normal.mouseup': function(e) {
dragger.dragEnd(e.getPosition(this.getRenderContainer()));
e.stopPropagation();
'normal.mouseup dragtree.beforemouseup': function(e) {
dragger.dragEnd();
//e.stopPropagation();
e.preventDefault();
this.fire('contentchange');
},
'statuschange': function(e) {
......
......@@ -242,7 +242,7 @@ Minder.Receiver = kity.createClass('Receiver', {
case keymap.Alt:
case keymap.Cmd:
case keymap.F2:
if(this.selection.isHide() && this.km.getStatus() != 'inputready'){
if(this.selection.isHide() && this.km.getStatus() != 'textedit'){
this.km.setStatus('normal');
return;
}
......
......@@ -72,10 +72,8 @@ KityMinder.registerModule('Expand', function() {
function setExpandState(node, state, policy) {
policy = policy || EXPAND_POLICY.KEEP_STATE;
policy(node, state, policy);
node.traverse(function(node) {
node.render();
});
node.getMinder().layout(200);
node.renderTree();
node.getMinder().layout(100);
}
// 将展开的操作和状态读取接口拓展到 MinderNode 上
......@@ -177,7 +175,7 @@ KityMinder.registerModule('Expand', function() {
var pathData = ['M', 1.5 - this.radius, 0, 'L', this.radius - 1.5, 0];
if (state == STATE_COLLAPSE) {
pathData.push(['M', 0, 1.5 - this.radius, 'L', 0, this.radius - 1.5]);
}
}
this.sign.setPathData(pathData);
}
});
......@@ -226,13 +224,17 @@ KityMinder.registerModule('Expand', function() {
'beforerender': function(e) {
var node = e.node;
var visible = !node.parent || node.parent.isExpanded();
var minder = this;
node.getRenderContainer().setVisible(visible);
if (!visible) e.stopPropagation();
},
'normal.keydown': function(e) {
if (this.getStatus() == 'textedit') return;
if (e.originEvent.keyCode == keymap['/']) {
var expanded = this.getSelectedNode().isExpanded();
var node = this.getSelectedNode();
if (!node || node == this.getRoot()) return;
var expanded = node.isExpanded();
this.getSelectedNodes().forEach(function(node) {
if (expanded) node.collapse();
else node.expand();
......
......@@ -89,7 +89,8 @@ KityMinder.registerModule("HistoryModule", function() {
if (child.isSelected()) {
selectedNodes.push(child);
}
km.appendNode(child,parent);
km.appendNode(child, parent);
child._lastLayoutTransform = parent._lastLayoutTransform;
child.render();
var children = utils.cloneArr(child.children);
......@@ -123,7 +124,7 @@ KityMinder.registerModule("HistoryModule", function() {
}
traverseNode(km.getRoot(), target);
km.layout();
km.layout(200);
km.select(selectedNodes,true);
......
KityMinder.registerModule("KeyboardModule", function() {
KityMinder.registerModule('KeyboardModule', function() {
var min = Math.min,
max = Math.max,
abs = Math.abs,
......@@ -127,11 +127,20 @@ KityMinder.registerModule("KeyboardModule", function() {
km.select(nextNode, true);
}
}
var lastFrame;
return {
'events': {
'contentchange layoutfinish': function() {
buildPositionNetwork(this.getRoot());
'layoutallfinish': function() {
var root = this.getRoot();
function build() {
buildPositionNetwork(root);
}
kity.Timeline.releaseFrame(lastFrame);
lastFrame = kity.Timeline.requestFrame(build);
},
'inputready.beforekeydown': function(e) {
var keyEvent = e.originEvent;
if (keyEvent.shiftKey && keyEvent.keyCode == KityMinder.keymap.Tab) e.preventDefault();
},
'normal.keydown': function(e) {
......@@ -143,7 +152,10 @@ KityMinder.registerModule("KeyboardModule", function() {
var keyEvent = e.originEvent;
if (keyEvent.altKey || keyEvent.ctrlKey || keyEvent.metaKey || keyEvent.shiftKey) return;
if (keyEvent.altKey || keyEvent.ctrlKey || keyEvent.metaKey || keyEvent.shiftKey) {
if ([keys.Tab].indexOf(keyEvent.keyCode)) e.preventDefault;
return;
}
switch (keyEvent.keyCode) {
case keys.Enter:
......
......@@ -6,7 +6,8 @@ var TextRenderer = KityMinder.TextRenderer = kity.createClass('TextRenderer', {
create: function() {
return new kity.Text()
.setId(KityMinder.uuid('node_text'))
.setVerticalAlign('middle');
.setVerticalAlign('middle')
.setAttr('text-rendering', 'inherit');
},
update: function(text, node) {
......@@ -16,7 +17,9 @@ var TextRenderer = KityMinder.TextRenderer = kity.createClass('TextRenderer', {
if (kity.Browser.ie) {
box.y += 1;
}
return new kity.Box(r(box.x), r(box.y), r(box.width), r(box.height));
return function() {
return new kity.Box(r(box.x), r(box.y), r(box.width), r(box.height));
};
},
setTextStyle: function(node, text) {
......
......@@ -16,8 +16,7 @@ var ViewDragger = kity.createClass("ViewDragger", {
move: function(offset, duration) {
if (!duration) {
this._minder.getRenderContainer().translate(offset.x | 0, offset.y | 0);
}
else {
} else {
this._minder.getRenderContainer().fxTranslate(offset.x | 0, offset.y | 0, duration, 'easeOutCubic');
}
},
......@@ -28,23 +27,40 @@ var ViewDragger = kity.createClass("ViewDragger", {
lastPosition = null,
currentPosition = null;
this._minder.on('normal.mousedown normal.touchstart readonly.mousedown readonly.touchstart', function(e) {
function dragEnd(e) {
lastPosition = null;
if (e.originEvent.button == 2) {
e.originEvent.preventDefault(); // 阻止中键拉动
}
// 点击未选中的根节点临时开启
if (e.getTargetNode() == this.getRoot() || e.originEvent.button == 2) {
lastPosition = e.getPosition();
isTempDrag = true;
e.stopPropagation();
// 临时拖动需要还原状态
if (isTempDrag) {
dragger.setEnabled(false);
isTempDrag = false;
if (dragger._minder.getStatus() == 'hand')
dragger._minder.rollbackStatus();
}
})
}
.on('normal.mousemove normal.touchmove readonly.touchmove readonly.mousemove', function(e) {
if (!isTempDrag) return;
var offset = kity.Vector.fromPoints(lastPosition, e.getPosition());
if (offset.length() > 3) this.setStatus('hand');
})
this._minder.on('normal.mousedown normal.touchstart ' +
'inputready.mousedown inputready.touchstart ' +
'readonly.mousedown readonly.touchstart', function(e) {
if (e.originEvent.button == 2) {
e.originEvent.preventDefault(); // 阻止中键拉动
}
// 点击未选中的根节点临时开启
if (e.getTargetNode() == this.getRoot() || e.originEvent.button == 2) {
lastPosition = e.getPosition();
isTempDrag = true;
}
})
.on('normal.mousemove normal.touchmove ' +
'readonly.touchmove readonly.mousemove ' +
'inputready.mousemove inputready.touchmove', function(e) {
if (!isTempDrag) return;
var offset = kity.Vector.fromPoints(lastPosition, e.getPosition());
if (offset.length() > 3) this.setStatus('hand');
})
.on('hand.beforemousedown hand.beforetouchstart', function(e) {
// 已经被用户打开拖放模式
......@@ -68,16 +84,9 @@ var ViewDragger = kity.createClass("ViewDragger", {
}
})
.on('mouseup touchend', function(e) {
lastPosition = null;
.on('mouseup touchend', dragEnd);
// 临时拖动需要还原状态
if (isTempDrag) {
dragger.setEnabled(false);
isTempDrag = false;
this.rollbackStatus();
}
});
window.addEventListener('mouseup', dragEnd);
}
});
......
......@@ -5,6 +5,11 @@ KityMinder.registerModule('Zoom', function() {
me.setDefaultOptions('zoom', [10, 20, 30, 50, 80, 100, 120, 150, 200]);
function setTextRendering() {
var value = me._zoomValue >= 100 ? 'optimize-speed' : 'geometricPrecision';
me.getRenderContainer().setAttr('text-rendering', value);
}
function fixPaperCTM(paper) {
var node = paper.shapeNode;
var ctm = node.getCTM();
......@@ -23,6 +28,9 @@ KityMinder.registerModule('Zoom', function() {
};
paper.setViewPort(viewport);
if (value == 100) fixPaperCTM(paper);
},
getZoomValue: function() {
return this._zoomValue;
}
});
......@@ -32,6 +40,12 @@ KityMinder.registerModule('Zoom', function() {
if (!value) return;
setTextRendering();
if (minder.getRoot().getComplex() > 200) {
minder._zoomValue = value;
return minder.zoom(value);
}
var animator = new kity.Animator({
beginValue: minder._zoomValue,
finishValue: value,
......@@ -43,7 +57,7 @@ KityMinder.registerModule('Zoom', function() {
if (timeline) {
timeline.pause();
}
timeline = animator.start(minder, 300, 'easeInOutSine');
timeline = animator.start(minder, 300, 'easeInOutSine', function() {});
}
var ZoomCommand = kity.createClass('Zoom', {
......@@ -95,6 +109,7 @@ KityMinder.registerModule('Zoom', function() {
return {
init: function() {
this._zoomValue = 100;
setTextRendering();
},
commands: {
'zoom-in': ZoomInCommand,
......
.help-content{
line-height: 20px;
font-size: 12px;
}
.help-content ul{
list-style: none;
padding:0;
}
.help-content ul li{
color:#666;
}
.help-content h2{color:#333;font-size: 18px;}
.help-content h3{
color:#333;
display: inline;
font-size: 14px;
.blur {
-webkit-filter: blur(5px);
-moz-filter: blur(5px);
-mz-filter: blur(5px);
-o-filter: blur(5px);
filter: blur(5px);
filter: url(../images/blur.svg#blur);
/* transition: all ease 0.5s; */
}
.kmui-modal.kmui-dialog-help .kmui-modal-header {
display: none;
}
.kmui-modal.kmui-dialog-help .kmui-modal-body {
position: fixed;
left: 0;
top: 85px;
right: 0;
bottom: 0;
max-height: 1000000px;
background: hsla(222, 14%, 41%, 0.8);
}
.shortcuts-opt {
margin: 0px 7px;
background-color: #fff;
font-size: 14px;
}
.shortcuts-group {
padding-right: 15px;
width: 200px;
text-shadow: none;
}
.shortcuts-thead {
font-size: 14px;
font-weight: bold;
line-height: 14px;
}
#div1 {
display: none;
}
/*.help-container {
width: 586px;
float: left;
}*/
.shortcuts-use {
width: 160px;
font-size: 14px;
font-weight: lighter;
}
.help-header {
padding-bottom: 9px;
margin: 20px 20px 30px;
border-bottom: 1px solid #EEE;
display: none;
}
.shortcuts-table {
max-width: 100%;
background-color: transparent;
border-collapse: collapse;
border-spacing: 0px;
float: left;
margin-left: 10px;
margin-top: 30px;
}
.shortcuts-table tr:first-child td span{
padding: 10px 0;
font-size: 18px;
display: block;
color: white;
}
.shortcuts-table td {
display: table-cell;
float: none;
margin-left: 0px;
padding-bottom: 7px;
}
.shortcuts-table td[colspan] {
text-align: center;
}
.shortcuts-table h2 {
font-size: 31.5px;
line-height: 40px;
}
.help-container {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
line-height: 20px;
color: hsl(0, 100%, 100%);
text-shadow: 0 1px black;
margin: 30px;
}
.shortcuts-key {
display: inline-block;
padding: 3px 8px 5px;
font-size: 14px;
font-weight: normal;
line-height: 14px;
color: hsl(0, 0%, 43%);
/* text-shadow: 0px -1px 0px rgba(0, 0, 0, 0.25); */
white-space: nowrap;
vertical-align: baseline;
background-color: hsl(0, 0%, 99%);
border-radius: 3px;
/* border: 1px solid hsl(0, 0%, 60%); */
text-transform: capitalize;
box-shadow: inset 0 -2px hsl(0, 0%, 92%), inset 0 -3px hsl(0, 100%, 100%), 0 1px 2px rgba(255, 255, 255, 0.3);
}
.mac .shortcuts-key.ctrl,
.mac .shortcuts-key.shift,
.mac .shortcuts-key.alt,
.shortcuts-key.up,
.shortcuts-key.down,
.shortcuts-key.left,
.shortcuts-key.right {
text-indent: -1000px;
position: relative;
width: 9px;
}
.mac .shortcuts-key.ctrl:after,
.mac .shortcuts-key.shift:after,
.mac .shortcuts-key.alt:after,
.shortcuts-key.up:after,
.shortcuts-key.down:after,
.shortcuts-key.left:after,
.shortcuts-key.right:after {
display: block;
position: absolute;
text-align: center;
left: 5px;
top: 4px;
width: 16px;
height: 16px;
text-indent: 0;
}
.mac .shortcuts-key.ctrl:after {
content: '⌘';
}
.mac .shortcuts-key.shift:after {
content: '⇧';
}
.mac .shortcuts-key.alt:after {
content: '⌥';
}
.shortcuts-key.up:after {
content: '↑';
top: 2px;
}
.shortcuts-key.down:after {
content: '↓';
top: 2px;
}
.shortcuts-key.left:after {
content: '←';
top: 2px;
}
.shortcuts-key.right:after {
content: '→';
top: 2px;
}
div.right {
float: right;
}
\ No newline at end of file
......@@ -2,7 +2,6 @@
html, body, div {
margin: 0;
padding: 0;
margin-top: 0 !important;
}
html, body, #kityminder, div.kmui-editor-body {
overflow: hidden;
......@@ -233,7 +232,14 @@ button#share-btn:hover {
.km-minderNode{
cursor:default;
}
.kmui-container, .kmui-editor-body {
.kmui-container {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
}
.kmui-editor-body {
position: absolute;
left: 0;
top: 0;
......
<svg version="1.1" xmlns="http://www.w3.org/2000/svg">
<filter id="blur">
<feGaussianBlur stdDeviation="5" />
</filter>
</svg>
\ No newline at end of file
<svg viewBox="0 0 1200 1200" width="32px" height="32px">
<g id="cat-face">
<path style="fill:#272B2D;" d="M1066.769,368.482L1119.5,80L830,131.611C760.552,97.29,682.35,77.999,599.641,77.999
c-82.424,0-160.371,19.161-229.641,53.26L81,81l50.769,289l0,0c-33.792,69.019-52.77,146.612-52.77,228.641
c0,287.542,233.099,520.642,520.642,520.642s520.642-233.099,520.642-520.642C1120.282,516.011,1101.028,437.88,1066.769,368.482z"
/>
</g>
<g id="cat-eye">
<path style="fill:#FFFFFF;" d="M920.255,371C794.746,371,693,472.746,693,598.255s101.746,227.255,227.255,227.255
s227.255-101.746,227.255-227.255S1045.765,371,920.255,371z M920,746c-80.081,0-145-64.919-145-145s64.919-145,145-145
s145,64.919,145,145S1000.081,746,920,746z"/>
<path style="fill:#FFFFFF;" d="M276.255,371C150.746,371,49,472.746,49,598.255s101.746,227.255,227.255,227.255
s227.255-101.746,227.255-227.255S401.765,371,276.255,371z M276,745c-80.081,0-145-64.919-145-145s64.919-145,145-145
s145,64.919,145,145S356.081,745,276,745z"/>
</g>
</svg>
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