Compare commits

..

152 Commits

Author SHA1 Message Date
wanglin2
c31a67e7bd 打包 2022-11-05 14:46:52 +08:00
wanglin2
f451d37254 demo网站增加英文翻译 2022-11-05 14:42:15 +08:00
wanglin25
377e507fd9 多语言开发中 2022-10-28 16:26:55 +08:00
wanglin25
dce55f3628 '增加从excel导入的功能' 2022-10-24 15:16:27 +08:00
wanglin25
600cadc861 打包 2022-10-24 10:31:35 +08:00
wanglin25
4d69f239f0 修复在小屏幕下侧边栏和工具栏重叠的问题 2022-10-24 10:28:50 +08:00
wanglin25
897c12b8e6 增加eslint校验、prettier格式化 2022-10-19 16:33:09 +08:00
wanglin25
9103574a88 优化小地图、优化拖拽性能 2022-10-19 09:54:38 +08:00
wanglin25
7c94ec19ac '支持双击节点内图片进行大图预览' 2022-10-18 19:13:15 +08:00
wanglin25
3e3a60cb03 优化本地文件编辑 2022-10-18 09:40:34 +08:00
wanglin25
ec69d81f6a 打包 2022-10-17 09:25:21 +08:00
街角小林
b2df7330fc Merge pull request #43 from huangyuanyin/main
优化 地图组件卸载的时候把相关事件移除
2022-10-17 09:20:38 +08:00
liuzhanghao
5265ceb803 优化 地图组件卸载的时候把相关事件移除 2022-10-14 18:11:57 +08:00
wanglin25
35d6297b72 Merge branch 'dev6' into main 2022-10-11 18:54:24 +08:00
wanglin25
5afe0a8c41 打包 2022-10-11 18:53:30 +08:00
wanglin25
81f86ccb30 优化:插入子节点时自动展开 2022-10-11 18:48:52 +08:00
wanglin25
87383498c8 修复小地图关闭时报错的问题 2022-10-11 18:36:16 +08:00
wanglin25
c68608c72c 合并 2022-10-11 11:10:00 +08:00
wanglin25
9d325d99a2 更新版本 2022-10-11 11:08:58 +08:00
wanglin2
bc59fa6dc7 修改文档 2022-10-10 22:40:44 +08:00
wanglin2
2daa59679a 修改文档 2022-10-10 22:40:12 +08:00
wanglin25
da456eeb8f 打包 2022-10-10 16:27:49 +08:00
wanglin25
5cd36b57d5 修复子节点收起状态复制时丢失的问题 2022-10-10 16:11:00 +08:00
wanglin25
e2b239fcbb 更新文档 2022-10-10 15:02:22 +08:00
wanglin25
5449e79d49 打包 2022-10-10 14:39:09 +08:00
wanglin25
c2045ddedc 支持小地图 2022-10-10 14:31:43 +08:00
wanglin2
5dfa215538 修改文档 2022-09-30 22:16:27 +08:00
wanglin25
d90013da71 打包 2022-09-30 14:48:08 +08:00
wanglin25
b3b74323f7 逻辑结构图、思维导图新增直线连接风格、直连风格 2022-09-30 14:44:40 +08:00
wanglin2
f9000ea478 逻辑结构图和思维导图支持直线连接线开发中 2022-09-25 22:07:21 +08:00
wanglin2
830e7e2482 打包 2022-09-24 20:42:53 +08:00
wanglin2
13ed7f28df 优化:手动创建节点时立即聚焦 2022-09-24 20:38:47 +08:00
wanglin2
17e79a0b23 修复连线样式深度更新问题 2022-09-24 20:13:53 +08:00
wanglin2
eee310ba49 支持新建、打开、 2022-09-24 17:08:11 +08:00
wanglin2
36c8927dd0 修改文档 2022-09-24 10:51:09 +08:00
wanglin2
05333daa63 支持展开到指定层级 2022-09-24 10:49:40 +08:00
wanglin25
5aed681198 支持展开到指定层级 2022-09-23 17:41:38 +08:00
wanglin25
8a438f2906 修复xmind8版本文件导入失败的问题 2022-09-23 16:16:08 +08:00
wanglin2
260de4987d 修改README 2022-09-21 21:02:17 +08:00
wanglin25
31cc658c06 打包 2022-09-21 20:11:12 +08:00
wanglin25
be6b41d74d 支持导入.xmind文件 2022-09-21 20:07:46 +08:00
wanglin25
4beeead53d 修复根节点添加多个节点爆栈的问题 2022-09-21 09:38:41 +08:00
wanglin25
af2df6acd3 导出svg增加title标签 2022-09-19 09:36:19 +08:00
wanglin2
c08d66acf2 打包 2022-09-17 22:00:15 +08:00
wanglin2
5a9cb9ac07 节点支持设置自定义线条样式 2022-09-17 16:18:38 +08:00
wanglin2
1662cd1be7 优化节点自定义线条样式 2022-09-17 15:09:34 +08:00
wanglin2
9dd5b3d47e 节点支持自定义线条样式 2022-09-17 15:00:12 +08:00
wanglin2
ece116317b 修改文档 2022-09-13 22:30:45 +08:00
wanglin25
d24d5c8281 修复节点展开收起的bug&打包 2022-09-13 10:34:20 +08:00
wanglin25
97c01cda3a 打包 2022-09-13 09:43:18 +08:00
wanglin25
6d520ece7e 修改文档 2022-09-13 09:33:05 +08:00
wanglin2
745041deef 节点支持多种形状开发完成 2022-09-12 23:07:01 +08:00
wanglin25
ae6c10cdf9 打包 2022-09-01 11:11:33 +08:00
街角小林
f5338d62fc Merge pull request #26 from huangyuanyin/main
fix 二级节点后无子节点,展开所有/收起所有操作后的报错信息
2022-09-01 11:07:38 +08:00
liuzhanghao
19fc12ff20 fix 2022-09-01 10:28:26 +08:00
liuzhanghao
d7640bb026 fix 二级节点后无子节点,展开所有/收起所有操作后的报错信息 2022-09-01 10:22:01 +08:00
wanglin
193b293cfe 更新readme 2022-08-22 21:03:08 +08:00
wanglin25
615ff3ea25 fix:修改右键菜单快捷键提示 2022-08-17 09:25:16 +08:00
wanglin25
8b9cfd2972 fix:修复右键菜单快捷键提示错误 2022-08-16 18:48:11 +08:00
wanglin25
03f8cb9290 fix:修复编辑节点文本时快捷键冲突的问题 2022-08-16 16:47:43 +08:00
wanglin
1ea0c7e316 修复输入字符串/和快捷键/冲突问题 2022-08-14 09:43:00 +08:00
wanglin
a39c8c30e6 打包 2022-08-08 21:24:02 +08:00
街角小林
26ce08c27d Update README.md 2022-08-08 20:09:31 +08:00
wanglin25
4bfc98a96f 支持导出为pdf 2022-08-08 20:06:59 +08:00
wanglin
7560411922 打包&发布新版本 2022-08-06 09:21:18 +08:00
wanglin25
4288e44f3a 支持Ctrl+左键多选 2022-08-05 17:21:21 +08:00
wanglin25
b82c5247fa Merge branch 'dev' of https://github.com/wanglin2/mind-map into dev 2022-08-05 09:30:19 +08:00
wanglin25
c7d2082944 新增库打包&修改文档 2022-08-05 09:29:59 +08:00
wanglin
29458ade9c 增加图标 2022-08-04 20:24:57 +08:00
wanglin25
49d366628e 修改文档 2022-08-04 15:06:07 +08:00
wanglin25
b093153262 新增快捷键 2022-08-04 14:48:52 +08:00
wanglin25
02f276bc2a 支持自由拖拽、修复一些bug 2022-08-04 11:39:17 +08:00
wanglin25
69cb961cc1 修复概要的一些bug 2022-08-02 08:59:05 +08:00
wanglin25
7096391f3b 修复拖拽节点时为隐藏概要内容的问题 2022-08-01 09:59:43 +08:00
wanglin25
280ffcf01d 修复初始渲染时激活节点没有触发页面效果的问题 2022-08-01 09:51:53 +08:00
wanglin25
db3c2b71f5 修复概要展开收起的定位错误问题 2022-08-01 09:36:25 +08:00
wanglin
f11f364d00 新增方法 2022-07-31 22:29:40 +08:00
wanglin
0e8c50d430 修复概要定位问题 2022-07-31 20:46:40 +08:00
wanglin
dd8d250857 修改及新增主题 2022-07-31 14:54:32 +08:00
wanglin
693ead6b49 概要开发中 2022-07-31 10:28:13 +08:00
wanglin
dc3c91270c 更新版本 2022-07-30 08:21:43 +08:00
街角小林
71ac739964 Merge pull request #16 from harris2012/patch-2
fix typo
2022-07-29 21:59:53 +08:00
街角小林
eae5dc5854 Merge pull request #15 from harris2012/patch-1
Update Node.js
2022-07-29 21:57:05 +08:00
Harris Zhang
c45ceac7dc fix typo 2022-07-29 17:55:20 +08:00
Harris Zhang
3d8702be8a Update Node.js 2022-07-29 11:29:25 +08:00
街角小林
084dd9fd84 Merge pull request #13 from harris2012/patch-1
Update index.js
2022-07-26 21:15:41 +08:00
Harris Zhang
0c6c68820f Update index.js 2022-07-26 19:12:47 +08:00
wanglin25
f5ff479f47 fix:1.节点图标不能删除的问题;2.工具按钮置灰仍然可以点击的问题 2022-06-28 19:55:31 +08:00
wanglin25
e9722efe93 增加只读模式 2022-06-08 14:30:45 +08:00
wanglin
db1f9c04c1 修改README 2022-05-10 23:09:54 +08:00
wanglin
b3e6412dbc 发布0.1.6版本 2022-05-10 23:08:02 +08:00
wanglin25
f58828469c 打包 2022-05-09 14:31:22 +08:00
wanglin25
cf7a92d9c7 节点备注支持markdown及富文本、修复不能选中文字的问题 2022-05-09 14:24:11 +08:00
wanglin25
ec0d021e92 修复节点标注在节点激活后无法隐藏问题 2022-05-09 11:31:05 +08:00
wanglin25
25a2d919fb 修复超链接、备注、标签等文字编辑时返回键和回车键与思维导图快捷键冲突的问题 2022-05-09 11:03:56 +08:00
wanglin
c3f4e2b797 增加版本号 2021-11-25 22:25:26 +08:00
wanglin25
a0c07522f9 新增支持节点拖拽 2021-11-25 16:06:18 +08:00
wanglin25
ca0cbdf009 '状态数据支持保存激活状态、视图状态(拖动位置、缩放值)' 2021-11-22 19:59:21 +08:00
wanglin
6263a49903 修复存在激活节点时设置主题存在的问题 2021-08-05 22:29:02 +08:00
wanglin
dce133f8f0 升级版本 2021-08-05 08:09:48 +08:00
wanglin
7f4f4e2fe0 增加快捷键功能 2021-08-05 00:06:27 +08:00
wanglin
4e4ade5c31 修复回退问题 2021-08-04 23:45:05 +08:00
wanglin
5423b42e9d 新增导出为json;优化一些细节 2021-08-04 07:26:01 +08:00
wanglin
9555375907 修改版本号及package.json 2021-08-01 11:58:08 +08:00
wanglin
cc19ce168b 增加本地存储功能 2021-08-01 10:49:57 +08:00
wanglin25
e324813eae 修复删除节点和节点编辑时的删除冲突问题 2021-07-27 14:17:58 +08:00
wanglin25
08a7ba380a '修改文章与打包' 2021-07-22 19:06:51 +08:00
wanglin25
dd2bfbcf93 '打包' 2021-07-22 14:13:49 +08:00
wanglin25
4ae5c914ca '打包' 2021-07-22 09:36:50 +08:00
wanglin
6f49577794 优化 2021-07-22 08:03:00 +08:00
wanglin
43a3dd97c7 修改文章 2021-07-21 22:50:46 +08:00
wanglin25
7226e40a6c '完成文章' 2021-07-21 20:24:37 +08:00
wanglin25
9f090a4474 文章写作中 2021-07-20 20:18:03 +08:00
wanglin
bf5298ab2f 文章 2021-07-20 07:48:22 +08:00
wanglin
ffe4fedbc3 修改文章 2021-07-19 07:39:34 +08:00
wanglin
07ad92e93a 添加图片 2021-07-18 22:47:03 +08:00
wanglin
5a004e40de 优化与文档编写 2021-07-18 22:27:34 +08:00
wanglin
8664bcc00b 完善开发文档 2021-07-16 19:33:01 +08:00
wanglin
d00f56c7f1 优化代码 2021-07-16 13:58:48 +08:00
wanglin
4ddce22076 基本完成 2021-07-16 13:42:37 +08:00
wanglin25
fdf4d51a1e '右键功能开发中' 2021-07-15 17:46:36 +08:00
wanglin25
a9ebe50fff Merge branch 'main' of https://github.com/wanglin2/mind-map into main 2021-07-15 09:46:53 +08:00
wanglin25
f8638088f3 '优化' 2021-07-15 09:46:27 +08:00
wanglin
081797e83b 右键菜单开发中 2021-07-14 23:57:36 +08:00
wanglin25
8adf5a7fb8 '修改样式' 2021-07-14 09:54:45 +08:00
wanglin25
194a920efa '打包' 2021-07-14 09:34:13 +08:00
wanglin
6b3741741c 修改配置 2021-07-14 08:13:23 +08:00
wanglin
80a7e334e4 修改配置 2021-07-14 08:09:23 +08:00
wanglin
5d45d7accf 打包 2021-07-14 07:38:30 +08:00
wanglin
b893776f82 修改打包配置i 2021-07-14 07:34:06 +08:00
wanglin
115a0ac480 修改 2021-07-14 07:28:31 +08:00
wanglin
cb43292aa5 上传打包文件 2021-07-13 23:29:22 +08:00
wanglin
7b773bd9ad 修改README 2021-07-13 23:20:41 +08:00
wanglin25
38a1e25cc2 '基本完成' 2021-07-13 16:39:50 +08:00
wanglin
fd0c471f00 优化 2021-07-13 08:04:47 +08:00
wanglin
97f84933f8 新增主题 2021-07-12 22:49:22 +08:00
wanglin25
321fc69798 '完成部分结构' 2021-07-12 20:12:21 +08:00
wanglin25
af2910bec8 '优化及增加主题' 2021-07-12 14:55:50 +08:00
wanglin
9deb20f1ca 回退功能开发中 2021-07-12 07:56:38 +08:00
wanglin
0f4d614c4e 增加快捷键和全屏功能 2021-07-11 22:21:40 +08:00
wanglin
eeba3153ef 完成多选操作 2021-07-11 13:33:06 +08:00
wanglin
554dab56d3 完成基本逻辑 2021-07-10 22:06:45 +08:00
wanglin
da28f89c52 日常提交 2021-07-04 22:53:36 +08:00
wanglin
8b0c62430e 完成导出功能 2021-07-04 16:56:37 +08:00
wanglin
adcf77f60d 日常提交 2021-06-28 07:46:12 +08:00
wanglin
54ae4b3e26 提交 2021-06-26 00:03:39 +08:00
wanglin
b0929da054 完成节点内容设置及主题 2021-06-26 00:01:03 +08:00
wanglin2
1528c3d64b Delete .DS_Store 2021-06-20 23:05:11 +08:00
wanglin2
ecc3ba8784 Delete .DS_Store 2021-06-20 23:04:56 +08:00
wanglin
947c4b2b44 完成节点内容布局 2021-06-20 23:03:23 +08:00
wanglin25
08c7768b18 修改忽略文件 2021-06-19 14:24:52 +08:00
wanglin25
efebe3f094 重构 2021-06-19 14:04:05 +08:00
42 changed files with 1281 additions and 2130 deletions

View File

@@ -93,7 +93,7 @@ npm run build
# 安装
> 当前仓库版本0.2.20当前npm版本0.2.20
> 当前仓库版本0.2.16当前npm版本0.2.16
```bash
npm i simple-mind-map
@@ -423,14 +423,6 @@ v0.1.5+
将节点移动到另一个节点的后面
#### moveNodeToCenter(node)
v0.2.17+
移动节点到画布中心。
目前如果是存在缩放的情况下回到中心会重置缩放。
## keyCommand实例
`keyCommand`实例负责快捷键的添加及触发,内置了一些快捷键,也可以自行添加。可通过`mindMap.keyCommand`获取到该实例。
@@ -558,12 +550,6 @@ v0.1.1+
动态设置变换数据可以通过getTransformData方法获取变换数据
#### setScale(scale)
v0.2.17+
设置缩放
## MiniMap实例
v0.2.11+

View File

@@ -1 +1 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>一个简单的web思维导图实现</title><link href="dist/js/chunk-2d20ec02.10aa67e3.js" rel="prefetch"><link href="dist/js/chunk-2d216b67.2d06497a.js" rel="prefetch"><link href="dist/js/chunk-5397ae43.e756f28b.js" rel="prefetch"><link href="dist/css/app.f735ed26.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.f631d5ff.css" rel="preload" as="style"><link href="dist/js/app.2fa527aa.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.68a34765.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.f631d5ff.css" rel="stylesheet"><link href="dist/css/app.f735ed26.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="dist/js/chunk-vendors.68a34765.js"></script><script src="dist/js/app.2fa527aa.js"></script></body></html>
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>一个简单的web思维导图实现</title><link href="dist/js/chunk-2d20ec02.10aa67e3.js" rel="prefetch"><link href="dist/js/chunk-2d216b67.2d06497a.js" rel="prefetch"><link href="dist/js/chunk-5397ae43.e756f28b.js" rel="prefetch"><link href="dist/css/app.6976ad01.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.f631d5ff.css" rel="preload" as="style"><link href="dist/js/app.ba6b7428.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.8be44735.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.f631d5ff.css" rel="stylesheet"><link href="dist/css/app.6976ad01.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="dist/js/chunk-vendors.8be44735.js"></script><script src="dist/js/app.ba6b7428.js"></script></body></html>

View File

@@ -15,7 +15,6 @@ import { layoutValueList } from './src/utils/constant'
import { SVG } from '@svgdotjs/svg.js'
import xmind from './src/parse/xmind'
import { simpleDeepClone } from './src/utils'
import KeyboardNavigation from './src/KeyboardNavigation'
// 默认选项配置
const defaultOpt = {
@@ -134,11 +133,6 @@ class MindMap {
mindMap: this
})
// 键盘导航类
this.keyboardNavigation = new KeyboardNavigation({
mindMap: this
})
// 批量执行类
this.batchExecution = new BatchExecution()

View File

@@ -1,6 +1,6 @@
{
"name": "simple-mind-map",
"version": "0.2.20",
"version": "0.2.16",
"description": "一个简单的web在线思维导图",
"authors": [
{

View File

@@ -76,11 +76,12 @@ class Drag extends Base {
// 计算鼠标按下的位置距离节点左上角的距离
this.drawTransform = this.mindMap.draw.transform()
let { scaleX, scaleY, translateX, translateY } = this.drawTransform
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.offsetX = x - (node.left * scaleX + translateX)
this.offsetY = y - (node.top * scaleY + translateY)
this.offsetX = e.clientX - (node.left * scaleX + translateX)
this.offsetY = e.clientY - (node.top * scaleY + translateY)
//
this.node = node
this.isMousedown = true
let { x, y } = this.mindMap.toPos(e.clientX, e.clientY)
this.mouseDownX = x
this.mouseDownY = y
})
@@ -274,7 +275,7 @@ class Drag extends Base {
}
}
// 检测兄弟节点位置
if (!this.prevNode && !this.nextNode && !node.isRoot) {// && this.node.isBrother(node)
if (!this.prevNode && !this.nextNode && this.node.isBrother(node)) {
if (left <= checkRight && right >= this.cloneNodeLeft) {
if (this.cloneNodeTop > bottom && this.cloneNodeTop <= bottom + 10) {
this.prevNode = node

View File

@@ -48,7 +48,6 @@ class Event extends EventEmitter {
this.onMousewheel = this.onMousewheel.bind(this)
this.onContextmenu = this.onContextmenu.bind(this)
this.onSvgMousedown = this.onSvgMousedown.bind(this)
this.onKeyup = this.onKeyup.bind(this)
}
/**
@@ -70,7 +69,6 @@ class Event extends EventEmitter {
this.mindMap.el.addEventListener('mousewheel', this.onMousewheel)
}
this.mindMap.svg.on('contextmenu', this.onContextmenu)
window.addEventListener('keyup', this.onKeyup)
}
/**
@@ -86,7 +84,6 @@ class Event extends EventEmitter {
window.removeEventListener('mouseup', this.onMouseup)
this.mindMap.el.removeEventListener('mousewheel', this.onMousewheel)
this.mindMap.svg.off('contextmenu', this.onContextmenu)
window.removeEventListener('keyup', this.onKeyup)
}
/**
@@ -180,16 +177,6 @@ class Event extends EventEmitter {
e.preventDefault()
this.emit('contextmenu', e)
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 11:12:11
* @Desc: 按键松开事件
*/
onKeyup(e) {
this.emit('keyup', e)
}
}
export default Event

View File

@@ -1,276 +0,0 @@
import { isKey } from './utils/keyMap'
import { bfsWalk } from './utils'
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 11:06:50
* @Desc: 键盘导航类
*/
export default class KeyboardNavigation {
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 11:07:24
* @Desc: 构造函数
*/
constructor(opt) {
this.opt = opt
this.mindMap = opt.mindMap
this.onKeyup = this.onKeyup.bind(this)
this.mindMap.on('keyup', this.onKeyup)
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 14:12:27
* @Desc: 处理按键事件
*/
onKeyup(e) {
;['Left', 'Up', 'Right', 'Down'].forEach(dir => {
if (isKey(e, dir)) {
if (this.mindMap.renderer.activeNodeList.length > 0) {
this.focus(dir)
} else {
let root = this.mindMap.renderer.root
this.mindMap.renderer.moveNodeToCenter(root)
root.active()
}
}
})
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 14:12:39
* @Desc: 聚焦到下一个节点
*/
focus(dir) {
// 当前聚焦的节点
let currentActiveNode = this.mindMap.renderer.activeNodeList[0]
// 当前聚焦节点的位置信息
let currentActiveNodeRect = this.getNodeRect(currentActiveNode)
// 寻找的下一个聚焦节点
let targetNode = null
let targetDis = Infinity
// 保存并维护距离最近的节点
let checkNodeDis = (rect, node) => {
let dis = this.getDistance(currentActiveNodeRect, rect)
if (dis < targetDis) {
targetNode = node
targetDis = dis
}
}
// 第一优先级:阴影算法
this.getFocusNodeByShadowAlgorithm({
currentActiveNode,
currentActiveNodeRect,
dir,
checkNodeDis
})
// 第二优先级:区域算法
if (!targetNode) {
this.getFocusNodeByAreaAlgorithm({
currentActiveNode,
currentActiveNodeRect,
dir,
checkNodeDis
})
}
// 第三优先级:简单算法
if (!targetNode) {
this.getFocusNodeBySimpleAlgorithm({
currentActiveNode,
currentActiveNodeRect,
dir,
checkNodeDis
})
}
// 找到了则让目标节点聚焦
if (targetNode) {
this.mindMap.renderer.moveNodeToCenter(targetNode)
targetNode.active()
}
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-12 16:22:54
* @Desc: 1.简单算法
*/
getFocusNodeBySimpleAlgorithm({
currentActiveNode,
currentActiveNodeRect,
dir,
checkNodeDis
}) {
// 遍历节点树
bfsWalk(this.mindMap.renderer.root, node => {
// 跳过当前聚焦的节点
if (node === currentActiveNode) return
// 当前遍历到的节点的位置信息
let rect = this.getNodeRect(node)
let { left, top, right, bottom } = rect
let match = false
// 按下了左方向键
if (dir === 'Left') {
// 判断节点是否在当前节点的左侧
match = right <= currentActiveNodeRect.left
// 按下了右方向键
} else if (dir === 'Right') {
// 判断节点是否在当前节点的右侧
match = left >= currentActiveNodeRect.right
// 按下了上方向键
} else if (dir === 'Up') {
// 判断节点是否在当前节点的上面
match = bottom <= currentActiveNodeRect.top
// 按下了下方向键
} else if (dir === 'Down') {
// 判断节点是否在当前节点的下面
match = top >= currentActiveNodeRect.bottom
}
// 符合要求,判断是否是最近的节点
if (match) {
checkNodeDis(rect, node)
}
})
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-12 16:24:54
* @Desc: 2.阴影算法
*/
getFocusNodeByShadowAlgorithm({
currentActiveNode,
currentActiveNodeRect,
dir,
checkNodeDis
}) {
bfsWalk(this.mindMap.renderer.root, node => {
if (node === currentActiveNode) return
let rect = this.getNodeRect(node)
let { left, top, right, bottom } = rect
let match = false
if (dir === 'Left') {
match =
left < currentActiveNodeRect.left &&
top < currentActiveNodeRect.bottom &&
bottom > currentActiveNodeRect.top
} else if (dir === 'Right') {
match =
right > currentActiveNodeRect.right &&
top < currentActiveNodeRect.bottom &&
bottom > currentActiveNodeRect.top
} else if (dir === 'Up') {
match =
top < currentActiveNodeRect.top &&
left < currentActiveNodeRect.right &&
right > currentActiveNodeRect.left
} else if (dir === 'Down') {
match =
bottom > currentActiveNodeRect.bottom &&
left < currentActiveNodeRect.right &&
right > currentActiveNodeRect.left
}
if (match) {
checkNodeDis(rect, node)
}
})
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-13 16:15:36
* @Desc: 3.区域算法
*/
getFocusNodeByAreaAlgorithm({
currentActiveNode,
currentActiveNodeRect,
dir,
checkNodeDis
}) {
// 当前聚焦节点的中心点
let cX = (currentActiveNodeRect.right + currentActiveNodeRect.left) / 2
let cY = (currentActiveNodeRect.bottom + currentActiveNodeRect.top) / 2
bfsWalk(this.mindMap.renderer.root, node => {
if (node === currentActiveNode) return
let rect = this.getNodeRect(node)
let { left, top, right, bottom } = rect
// 遍历到的节点的中心点
let ccX = (right + left) / 2
let ccY = (bottom + top) / 2
// 节点的中心点坐标和当前聚焦节点的中心点坐标的差值
let offsetX = ccX - cX
let offsetY = ccY - cY
if (offsetX === 0 && offsetY === 0) return
let match = false
if (dir === 'Left') {
match = offsetX <= 0 && offsetX <= offsetY && offsetX <= -offsetY
} else if (dir === 'Right') {
match = offsetX > 0 && offsetX >= -offsetY && offsetX >= offsetY
} else if (dir === 'Up') {
match = offsetY <= 0 && offsetY < offsetX && offsetY < -offsetX
} else if (dir === 'Down') {
match = offsetY > 0 && -offsetY < offsetX && offsetY > offsetX
}
if (match) {
checkNodeDis(rect, node)
}
})
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 14:12:50
* @Desc: 获取节点的位置信息
*/
getNodeRect(node) {
let { scaleX, scaleY, translateX, translateY } =
this.mindMap.draw.transform()
let { left, top, width, height } = node
return {
right: (left + width) * scaleX + translateX,
bottom: (top + height) * scaleY + translateY,
left: left * scaleX + translateX,
top: top * scaleY + translateY
}
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 14:13:04
* @Desc: 获取两个节点的距离
*/
getDistance(node1Rect, node2Rect) {
let center1 = this.getCenter(node1Rect)
let center2 = this.getCenter(node2Rect)
return Math.sqrt(
Math.pow(center1.x - center2.x, 2) + Math.pow(center1.y - center2.y, 2)
)
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 14:13:11
* @Desc: 获取节点的中心点
*/
getCenter({ left, right, top, bottom }) {
return {
x: (left + right) / 2,
y: (top + bottom) / 2
}
}
}

View File

@@ -549,30 +549,32 @@ class Render {
if (node.isRoot) {
return
}
// 移动节点
let nodeParent = node.parent
let nodeBorthers = nodeParent.children
let nodeIndex = nodeBorthers.findIndex(item => {
let parent = node.parent
let childList = parent.children
// 要移动节点的索引
let index = childList.findIndex(item => {
return item === node
})
if (nodeIndex === -1) {
if (index === -1) {
return
}
nodeBorthers.splice(nodeIndex, 1)
nodeParent.nodeData.children.splice(nodeIndex, 1)
// 目标节点
let existParent = exist.parent
let existBorthers = existParent.children
let existIndex = existBorthers.findIndex(item => {
// 目标节点的索引
let existIndex = childList.findIndex(item => {
return item === exist
})
if (existIndex === -1) {
return
}
existBorthers.splice(existIndex, 0, node)
existParent.nodeData.children.splice(existIndex, 0, node.nodeData)
// 当前节点在目标节点前面
if (index < existIndex) {
existIndex = existIndex - 1
}
// 节点实例
childList.splice(index, 1)
childList.splice(existIndex, 0, node)
// 节点数据
parent.nodeData.children.splice(index, 1)
parent.nodeData.children.splice(existIndex, 0, node.nodeData)
this.mindMap.render()
}
@@ -586,31 +588,34 @@ class Render {
if (node.isRoot) {
return
}
// 移动节点
let nodeParent = node.parent
let nodeBorthers = nodeParent.children
let nodeIndex = nodeBorthers.findIndex(item => {
let parent = node.parent
let childList = parent.children
// 要移动节点的索引
let index = childList.findIndex(item => {
return item === node
})
if (nodeIndex === -1) {
if (index === -1) {
return
}
nodeBorthers.splice(nodeIndex, 1)
nodeParent.nodeData.children.splice(nodeIndex, 1)
// 目标节点
let existParent = exist.parent
let existBorthers = existParent.children
let existIndex = existBorthers.findIndex(item => {
// 目标节点的索引
let existIndex = childList.findIndex(item => {
return item === exist
})
if (existIndex === -1) {
return
}
existIndex++
existBorthers.splice(existIndex, 0, node)
existParent.nodeData.children.splice(existIndex, 0, node.nodeData)
// 当前节点在目标节点前面
if (index < existIndex) {
// do nothing
} else {
existIndex = existIndex + 1
}
// 节点实例
childList.splice(index, 1)
childList.splice(existIndex, 0, node)
// 节点数据
parent.nodeData.children.splice(index, 1)
parent.nodeData.children.splice(existIndex, 0, node.nodeData)
this.mindMap.render()
}
@@ -1092,28 +1097,6 @@ class Render {
this.mindMap.render()
}
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 11:46:57
* @Desc: 移动节点到画布中心
*/
moveNodeToCenter(node) {
let halfWidth = this.mindMap.width / 2
let halfHeight = this.mindMap.height / 2
let { left, top, width, height } = node
let nodeCenterX = left + width / 2
let nodeCenterY = top + height / 2
let { state } = this.mindMap.view.getTransformData()
let targetX = halfWidth - state.x
let targetY = halfHeight - state.y
let offsetX = targetX - nodeCenterX
let offsetY = targetY - nodeCenterY
this.mindMap.view.translateX(offsetX)
this.mindMap.view.translateY(offsetY)
this.mindMap.view.setScale(1)
}
}
export default Render

View File

@@ -88,9 +88,6 @@ export default class TextEdit {
this.textEditNode = document.createElement('div')
this.textEditNode.style.cssText = `position:fixed;box-sizing: border-box;background-color:#fff;box-shadow: 0 0 20px rgba(0,0,0,.5);padding: 3px 5px;margin-left: -5px;margin-top: -3px;outline: none;`
this.textEditNode.setAttribute('contenteditable', true)
this.textEditNode.addEventListener('keyup', e => {
e.stopPropagation()
})
document.body.appendChild(this.textEditNode)
}
node.style.domText(this.textEditNode, this.mindMap.view.scale)

View File

@@ -213,18 +213,6 @@ class View {
this.transform()
this.mindMap.emit('scale', this.scale)
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-12-09 16:31:59
* @Desc: 设置缩放
*/
setScale(scale) {
this.scale = scale
this.transform()
this.mindMap.emit('scale', this.scale)
}
}
export default View

View File

@@ -4,7 +4,6 @@ import Vue from 'vue'
const SIMPLE_MIND_MAP_DATA = 'SIMPLE_MIND_MAP_DATA'
const SIMPLE_MIND_MAP_LANG = 'SIMPLE_MIND_MAP_LANG'
const SIMPLE_MIND_MAP_LOCAL_CONFIG = 'SIMPLE_MIND_MAP_LOCAL_CONFIG'
/**
* @Author: 王林
@@ -102,27 +101,3 @@ export const getLang = () => {
storeLang('zh')
return 'zh'
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-11-14 18:57:31
* @Desc: 存储本地配置
*/
export const storeLocalConfig = config => {
localStorage.setItem(SIMPLE_MIND_MAP_LOCAL_CONFIG, JSON.stringify(config))
}
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-11-14 18:57:37
* @Desc: 获取本地配置
*/
export const getLocalConfig = () => {
let config = localStorage.getItem(SIMPLE_MIND_MAP_LOCAL_CONFIG)
if (config) {
return JSON.parse(config)
}
return null
}

View File

@@ -1,15 +1,19 @@
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
font-family: 'iconfont logo';
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix')
format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834')
format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834')
format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont')
format('svg');
}
.logo {
font-family: "iconfont logo";
font-family: 'iconfont logo';
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
@@ -48,7 +52,6 @@
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
@@ -215,35 +218,35 @@
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
.markdown > p,
.markdown > blockquote,
.markdown > .highlight,
.markdown > ol,
.markdown > ul {
width: 80%;
}
.markdown ul>li {
.markdown ul > li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
.markdown > ul li,
.markdown blockquote ul > li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
.markdown > ul li p,
.markdown > ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
.markdown ol > li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
.markdown > ol li,
.markdown blockquote ol > li {
margin-left: 20px;
padding-left: 4px;
}
@@ -260,7 +263,7 @@
font-weight: 600;
}
.markdown>table {
.markdown > table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
@@ -269,21 +272,21 @@
margin-bottom: 24px;
}
.markdown>table th {
.markdown > table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
.markdown > table th,
.markdown > table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
.markdown > table th {
background: #f7f7f7;
}
.markdown blockquote {
@@ -318,12 +321,11 @@
display: inline-block;
}
.markdown>br,
.markdown>p>br {
.markdown > br,
.markdown > p > br {
clear: both;
}
.hljs {
display: block;
background: white;
@@ -399,8 +401,8 @@ https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javasc
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
code[class*='language-'],
pre[class*='language-'] {
color: black;
background: none;
text-shadow: 0 1px white;
@@ -422,46 +424,45 @@ pre[class*="language-"] {
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
pre[class*='language-']::-moz-selection,
pre[class*='language-'] ::-moz-selection,
code[class*='language-']::-moz-selection,
code[class*='language-'] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
pre[class*='language-']::selection,
pre[class*='language-'] ::selection,
code[class*='language-']::selection,
code[class*='language-'] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
code[class*='language-'],
pre[class*='language-'] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
pre[class*='language-'] {
padding: 1em;
margin: .5em 0;
margin: 0.5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
:not(pre) > code[class*='language-'],
pre[class*='language-'] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
:not(pre) > code[class*='language-'] {
padding: 0.1em;
border-radius: 0.3em;
white-space: normal;
}
@@ -477,7 +478,7 @@ pre[class*="language-"] {
}
.namespace {
opacity: .7;
opacity: 0.7;
}
.token.property,
@@ -505,7 +506,7 @@ pre[class*="language-"] {
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
background: hsla(0, 0%, 100%, 0.5);
}
.token.atrule,
@@ -516,7 +517,7 @@ pre[class*="language-"] {
.token.function,
.token.class-name {
color: #DD4A68;
color: #dd4a68;
}
.token.regex,

File diff suppressed because it is too large Load Diff

View File

@@ -1,195 +1,186 @@
@font-face {
font-family: "iconfont"; /* Project id 2479351 */
src: url('iconfont.woff2?t=1668512547595') format('woff2'),
url('iconfont.woff?t=1668512547595') format('woff'),
url('iconfont.ttf?t=1668512547595') format('truetype');
font-family: 'iconfont'; /* Project id 2479351 */
src: url('iconfont.woff2?t=1664005697217') format('woff2'),
url('iconfont.woff?t=1664005697217') format('woff'),
url('iconfont.ttf?t=1664005697217') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-family: 'iconfont' !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.iconchoose1:before {
content: "\e6c5";
}
.iconzhuti:before {
content: "\e7aa";
}
.icondaochu1:before {
content: "\e63e";
content: '\e63e';
}
.iconlingcunwei:before {
content: "\e657";
content: '\e657';
}
.iconexport:before {
content: "\e642";
content: '\e642';
}
.icondakai:before {
content: "\ebdf";
content: '\ebdf';
}
.iconxinjian:before {
content: "\e64e";
content: '\e64e';
}
.iconjianqie:before {
content: "\e601";
content: '\e601';
}
.iconzhengli:before {
content: "\e83b";
content: '\e83b';
}
.iconfuzhi:before {
content: "\e604";
content: '\e604';
}
.iconniantie:before {
content: "\e63f";
content: '\e63f';
}
.iconshangyi:before {
content: "\e6be";
content: '\e6be';
}
.iconxiayi:before {
content: "\e6bf";
content: '\e6bf';
}
.icongaikuozonglan:before {
content: "\e609";
content: '\e609';
}
.iconquanxuan:before {
content: "\f199";
content: '\f199';
}
.icondaoru:before {
content: "\e6a3";
content: '\e6a3';
}
.iconhoutui-shi:before {
content: "\e656";
content: '\e656';
}
.iconqianjin1:before {
content: "\e654";
content: '\e654';
}
.iconwithdraw:before {
content: "\e603";
content: '\e603';
}
.iconqianjin:before {
content: "\e600";
content: '\e600';
}
.iconhuifumoren:before {
content: "\e60e";
content: '\e60e';
}
.iconhuanhang:before {
content: "\e61e";
content: '\e61e';
}
.iconsuoxiao:before {
content: "\ec13";
content: '\ec13';
}
.iconbianji:before {
content: "\e626";
content: '\e626';
}
.iconfangda:before {
content: "\e663";
content: '\e663';
}
.iconquanping1:before {
content: "\e664";
content: '\e664';
}
.icondingwei:before {
content: "\e616";
content: '\e616';
}
.icondaohang:before {
content: "\e611";
content: '\e611';
}
.iconjianpan:before {
content: "\e64d";
content: '\e64d';
}
.iconquanping:before {
content: "\e602";
content: '\e602';
}
.icondaochu:before {
content: "\e63d";
content: '\e63d';
}
.iconbiaoqian:before {
content: "\e63c";
content: '\e63c';
}
.iconflow-Mark:before {
content: "\e65b";
content: '\e65b';
}
.iconchaolianjie:before {
content: "\e6f4";
content: '\e6f4';
}
.iconjingzi:before {
content: "\e610";
content: '\e610';
}
.iconxiaolian:before {
content: "\e60f";
content: '\e60f';
}
.iconimage:before {
content: "\e629";
content: '\e629';
}
.iconjiegou:before {
content: "\e61d";
content: '\e61d';
}
.iconyangshi:before {
content: "\e631";
content: '\e631';
}
.iconfuhao-dagangshu:before {
content: "\e71f";
content: '\e71f';
}
.icontianjiazijiedian:before {
content: "\e622";
content: '\e622';
}
.iconjiedian:before {
content: "\e655";
content: '\e655';
}
.iconshanchu:before {
content: "\e696";
content: '\e696';
}
.iconzhankai:before {
content: "\e64c";
content: '\e64c';
}
.iconzhankai1:before {
content: "\e673";
content: '\e673';
}

File diff suppressed because one or more lines are too long

View File

@@ -5,20 +5,6 @@
"css_prefix_text": "icon",
"description": "思维导图",
"glyphs": [
{
"icon_id": "1009019",
"name": "选择",
"font_class": "choose1",
"unicode": "e6c5",
"unicode_decimal": 59077
},
{
"icon_id": "493507",
"name": "主题",
"font_class": "zhuti",
"unicode": "e7aa",
"unicode_decimal": 59306
},
{
"icon_id": "1305460",
"name": "导出",

View File

@@ -319,37 +319,3 @@ export const shapeList = [
value: 'circle'
}
]
// 侧边栏列表
export const sidebarTriggerList = [
{
name: 'Node style',
value: 'nodeStyle',
icon: 'iconzhuti'
},
{
name: 'Base style',
value: 'baseStyle',
icon: 'iconyangshi'
},
{
name: 'Theme',
value: 'theme',
icon: 'iconjingzi'
},
{
name: 'Structure',
value: 'structure',
icon: 'iconjiegou'
},
{
name: 'Outline',
value: 'outline',
icon: 'iconfuhao-dagangshu'
},
{
name: 'ShortcutKey',
value: 'shortcutKey',
icon: 'iconjianpan'
}
]

View File

@@ -13,8 +13,7 @@ import {
backgroundRepeatList as backgroundRepeatListZh,
backgroundPositionList as backgroundPositionListZh,
shortcutKeyList as shortcutKeyListZh,
shapeList as shapeListZh,
sidebarTriggerList as sidebarTriggerListZh
shapeList as shapeListZh
} from './zh'
import {
fontFamilyList as fontFamilyListEn,
@@ -23,8 +22,7 @@ import {
backgroundRepeatList as backgroundRepeatListEn,
backgroundPositionList as backgroundPositionListEn,
shortcutKeyList as shortcutKeyListEn,
shapeList as shapeListEn,
sidebarTriggerList as sidebarTriggerListEn
shapeList as shapeListEn
} from './en'
const fontFamilyList = {
@@ -62,11 +60,6 @@ const shapeList = {
en: shapeListEn
}
const sidebarTriggerList = {
zh: sidebarTriggerListZh,
en: sidebarTriggerListEn
}
export {
fontSizeList,
lineHeightList,
@@ -82,6 +75,5 @@ export {
backgroundRepeatList,
backgroundPositionList,
shortcutKeyList,
shapeList,
sidebarTriggerList
shapeList
}

View File

@@ -391,37 +391,3 @@ export const langList = [
name: 'English'
}
]
// 侧边栏列表
export const sidebarTriggerList = [
{
name: '节点样式',
value: 'nodeStyle',
icon: 'iconzhuti'
},
{
name: '基础样式',
value: 'baseStyle',
icon: 'iconyangshi'
},
{
name: '主题',
value: 'theme',
icon: 'iconjingzi'
},
{
name: '结构',
value: 'structure',
icon: 'iconjiegou'
},
{
name: '大纲',
value: 'outline',
icon: 'iconfuhao-dagangshu'
},
{
name: '快捷键',
value: 'shortcutKey',
icon: 'iconjianpan'
}
]

View File

@@ -43,8 +43,7 @@ export default {
level3: 'Level3',
level4: 'Level4',
level5: 'Level5',
level6: 'Level6',
zenMode: 'Zen mode'
level6: 'Level6'
},
count: {
words: 'Words',

View File

@@ -43,8 +43,7 @@ export default {
level3: '三级主题',
level4: '四级主题',
level5: '五级主题',
level6: '六级主题',
zenMode: '禅模式'
level6: '六级主题'
},
count: {
words: '字数',

View File

@@ -1,7 +1,7 @@
<template>
<div class="container">
<template v-if="show">
<Toolbar v-if="!isZenMode"></Toolbar>
<Toolbar></Toolbar>
<Edit></Edit>
</template>
</div>
@@ -10,8 +10,7 @@
<script>
import Toolbar from './components/Toolbar'
import Edit from './components/Edit'
import { mapState, mapActions, mapMutations } from 'vuex'
import { getLocalConfig } from '@/api'
import { mapActions } from 'vuex'
export default {
name: 'Index',
@@ -24,13 +23,7 @@ export default {
show: false
}
},
computed: {
...mapState({
isZenMode: state => state.localConfig.isZenMode
})
},
async created() {
this.initLocalConfig()
const loading = this.$loading({
lock: true,
text: '正在加载,请稍后...'
@@ -40,23 +33,7 @@ export default {
loading.close()
},
methods: {
...mapActions(['getUserMindMapData']),
...mapMutations(['setLocalConfig']),
/**
* @Author: 王林25
* @Date: 2022-11-14 19:07:03
* @Desc: 初始化本地配置
*/
initLocalConfig() {
let config = getLocalConfig()
if (config) {
this.setLocalConfig({
...this.$store.state.localConfig,
...config
})
}
}
...mapActions(['getUserMindMapData'])
}
}
</script>

View File

@@ -298,7 +298,6 @@ import Color from './Color'
import { lineWidthList, lineStyleList, backgroundRepeatList } from '@/config'
import ImgUpload from '@/components/ImgUpload'
import { storeConfig } from '@/api'
import { mapState } from 'vuex'
/**
* @Author: 王林
@@ -346,8 +345,6 @@ export default {
}
},
computed: {
...mapState(['activeSidebar']),
lineStyleList() {
return lineStyleList[this.$i18n.locale] || lineStyleList.zh
},
@@ -355,15 +352,14 @@ export default {
return backgroundRepeatList[this.$i18n.locale] || backgroundRepeatList.zh
}
},
watch: {
activeSidebar(val) {
if (val === 'baseStyle') {
created() {
this.$bus.$on('showBaseStyle', () => {
this.$refs.sidebar.show = false
this.$nextTick(() => {
this.$refs.sidebar.show = true
this.initStyle()
} else {
this.$refs.sidebar.show = false
}
}
})
})
},
methods: {
/**

View File

@@ -89,17 +89,11 @@
{{ $t('contextmenu.arrangeLayout') }}
<span class="desc">Ctrl + L</span>
</div>
<div class="item" @click="exec('TOGGLE_ZEN_MODE')">
{{ $t('contextmenu.zenMode') }}
{{ isZenMode ? '' : '' }}
</div>
</template>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
/**
* @Author: 王林
* @Date: 2021-06-24 22:53:10
@@ -126,9 +120,6 @@ export default {
}
},
computed: {
...mapState({
isZenMode: state => state.localConfig.isZenMode
}),
expandList() {
return [
this.$t('contextmenu.level1'),
@@ -190,8 +181,6 @@ export default {
this.mindMap.keyCommand.removeShortcut('Control+x', this.cut)
},
methods: {
...mapMutations(['setLocalConfig']),
/**
* @Author: 王林
* @Date: 2021-07-14 21:38:50
@@ -287,11 +276,6 @@ export default {
case 'RETURN_CENTER':
this.mindMap.view.reset()
break
case 'TOGGLE_ZEN_MODE':
this.setLocalConfig({
isZenMode: !this.isZenMode
})
break
default:
this.$bus.$emit('execCommand', key, ...args)
break

View File

@@ -27,23 +27,13 @@ export default {
}
},
created() {
this.$bus.$on('data_change', this.onDataChange)
},
beforeDestroy() {
this.$bus.$off('data_change', this.onDataChange)
},
methods: {
/**
* @Author: 王林25
* @Date: 2022-11-14 19:20:20
* @Desc: 监听数据变化
*/
onDataChange(data) {
this.$bus.$on('data_change', data => {
this.words = 0
this.num = 0
this.walk(data)
},
})
},
methods: {
/**
* @Author: 王林
* @Date: 2021-06-30 22:13:07

View File

@@ -1,22 +1,18 @@
<template>
<div class="editContainer">
<div class="mindMapContainer" ref="mindMapContainer"></div>
<Count v-if="!isZenMode"></Count>
<Count></Count>
<Navigator :mindMap="mindMap"></Navigator>
<NavigatorToolbar :mindMap="mindMap" v-if="!isZenMode"></NavigatorToolbar>
<Outline :mindMap="mindMap"></Outline>
<Style v-if="!isZenMode"></Style>
<NavigatorToolbar :mindMap="mindMap"></NavigatorToolbar>
<Outline></Outline>
<Style></Style>
<BaseStyle :data="mindMapData" :mindMap="mindMap"></BaseStyle>
<Theme :mindMap="mindMap"></Theme>
<Structure :mindMap="mindMap"></Structure>
<ShortcutKey></ShortcutKey>
<Contextmenu v-if="mindMap" :mindMap="mindMap"></Contextmenu>
<NodeNoteContentShow
v-if="mindMap"
:mindMap="mindMap"
></NodeNoteContentShow>
<NodeNoteContentShow></NodeNoteContentShow>
<NodeImgPreview v-if="mindMap" :mindMap="mindMap"></NodeImgPreview>
<SidebarTrigger v-if="!isZenMode"></SidebarTrigger>
</div>
</template>
@@ -35,8 +31,6 @@ import NodeNoteContentShow from './NodeNoteContentShow.vue'
import { getData, storeData, storeConfig } from '@/api'
import Navigator from './Navigator.vue'
import NodeImgPreview from './NodeImgPreview.vue'
import SidebarTrigger from './SidebarTrigger.vue'
import { mapState } from 'vuex'
/**
* @Author: 王林
@@ -57,8 +51,7 @@ export default {
Contextmenu,
NodeNoteContentShow,
Navigator,
NodeImgPreview,
SidebarTrigger
NodeImgPreview
},
data() {
return {
@@ -68,11 +61,6 @@ export default {
openTest: false
}
},
computed: {
...mapState({
isZenMode: state => state.localConfig.isZenMode
})
},
mounted() {
this.getData()
this.init()
@@ -237,7 +225,7 @@ export default {
this.$bus.$emit('showNoteContent', content, left, top)
},
hide: () => {
// this.$bus.$emit('hideNoteContent')
this.$bus.$emit('hideNoteContent')
}
}
})
@@ -328,11 +316,6 @@ export default {
top: 0px;
width: 100%;
height: 100%;
// left: 100px;
// top: 100px;
// right: 100px;
// bottom: 100px;
}
}
</style>

View File

@@ -11,12 +11,11 @@
v-model="link"
size="mini"
placeholder="http://xxxx.com/"
@keyup.native.stop
></el-input>
</div>
<div class="item">
<span class="name">{{ $t('nodeHyperlink.name') }}</span>
<el-input v-model="linkTitle" size="mini" @keyup.native.stop></el-input>
<el-input v-model="linkTitle" size="mini"></el-input>
</div>
<span slot="footer" class="dialog-footer">
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>

View File

@@ -12,7 +12,7 @@
v-model="note"
>
</el-input> -->
<div class="noteEditor" ref="noteEditor" @keyup.stop></div>
<div class="noteEditor" ref="noteEditor"></div>
<!-- <div class="tip">换行请使用Enter+Shift</div> -->
<span slot="footer" class="dialog-footer">
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>

View File

@@ -7,7 +7,6 @@
top: this.top + 'px',
visibility: show ? 'visible' : 'hidden'
}"
@click.stop
></div>
</template>
@@ -31,42 +30,20 @@ export default {
}
},
created() {
this.$bus.$on('showNoteContent', this.onShowNoteContent)
this.$bus.$on('hideNoteContent', this.hideNoteContent)
document.body.addEventListener('click', this.hideNoteContent)
this.$bus.$on('node_active', this.hideNoteContent)
},
mounted() {
this.initEditor()
},
beforeDestroy() {
this.$bus.$off('showNoteContent', this.onShowNoteContent)
this.$bus.$off('hideNoteContent', this.hideNoteContent)
document.body.removeEventListener('click', this.hideNoteContent)
this.$bus.$off('node_active', this.hideNoteContent)
},
methods: {
/**
* @Author: 王林25
* @Date: 2022-11-14 19:56:08
* @Desc: 显示备注浮层
*/
onShowNoteContent(content, left, top) {
this.$bus.$on('showNoteContent', (content, left, top) => {
this.editor.setMarkdown(content)
this.left = left
this.top = top
this.show = true
},
/**
* @Author: 王林25
* @Date: 2022-11-14 19:56:20
* @Desc: 隐藏备注浮层
*/
hideNoteContent() {
})
this.$bus.$on('hideNoteContent', () => {
this.show = false
},
})
},
mounted() {
this.initEditor()
},
methods: {
/**
* @Author: 王林25
* @Date: 2022-05-09 11:37:05
@@ -89,24 +66,5 @@ export default {
background-color: #fff;
padding: 10px;
border-radius: 5px;
max-height: 300px;
overflow-y: auto;
&::-webkit-scrollbar {
width: 7px;
height: 7px;
}
&::-webkit-scrollbar-thumb {
border-radius: 7px;
background-color: rgba(0, 0, 0, 0.3);
cursor: pointer;
}
&::-webkit-scrollbar-track {
box-shadow: none;
background: transparent;
display: none;
}
}
</style>

View File

@@ -8,7 +8,6 @@
<el-input
v-model="tag"
@keyup.native.enter="add"
@keyup.native.stop
:disabled="tagArr.length >= max"
:placeholder="$t('nodeTag.addTip')"
>

View File

@@ -1,30 +1,11 @@
<template>
<Sidebar ref="sidebar" :title="$t('outline.title')">
<el-tree
class="outlineTree"
:data="data"
:props="defaultProps"
:expand-on-click-node="false"
default-expand-all
>
<span class="customNode" slot-scope="{ node, data }">
<span
class="nodeEdit"
:key="getKey()"
contenteditable="true"
@keydown.stop
@keyup.stop
@blur="onBlur($event, node)"
v-html="node.label"
></span>
</span>
</el-tree>
<el-tree :data="data" :props="defaultProps" default-expand-all></el-tree>
</Sidebar>
</template>
<script>
import Sidebar from './Sidebar'
import { mapState } from 'vuex'
/**
* @Author: 王林
@@ -36,97 +17,28 @@ export default {
components: {
Sidebar
},
props: {
mindMap: {
type: Object
}
},
data() {
return {
data: [],
defaultProps: {
label(data) {
return data.data.text.replaceAll(/\n/g, '</br>')
return data.data.text
}
}
}
},
computed: {
...mapState(['activeSidebar'])
},
watch: {
activeSidebar(val) {
if (val === 'outline') {
this.$refs.sidebar.show = true
} else {
this.$refs.sidebar.show = false
}
}
},
created() {
this.$bus.$on('data_change', data => {
this.data = [this.mindMap.renderer.renderTree]
this.data = [data]
})
this.$bus.$on('showOutline', () => {
this.$refs.sidebar.show = false
this.$nextTick(() => {
this.$refs.sidebar.show = true
})
})
},
methods: {
onBlur(e, node) {
node.data._node.setText(e.target.innerText)
},
getKey() {
return Math.random()
}
}
}
</script>
<style lang="less" scoped>
.customNode {
width: 100%;
overflow-x: auto;
&::-webkit-scrollbar {
width: 7px;
height: 7px;
}
&::-webkit-scrollbar-thumb {
border-radius: 7px;
background-color: rgba(0, 0, 0, 0.3);
cursor: pointer;
}
&::-webkit-scrollbar-track {
box-shadow: none;
background: transparent;
display: none;
}
.nodeEdit {
outline: none;
}
}
.outlineTree {
/deep/ .el-tree-node__content {
height: auto;
margin: 5px 0;
.el-tree-node__expand-icon.is-leaf {
position: relative;
&::after {
position: absolute;
content: '';
width: 5px;
height: 5px;
border-radius: 50%;
background-color: #c0c4cc;
left: 10px;
top: 50%;
transform: translateY(-50%);
}
}
}
}
</style>
<style lang="less" scoped></style>

View File

@@ -22,7 +22,6 @@
<script>
import Sidebar from './Sidebar'
import { shortcutKeyList } from '@/config'
import { mapState } from 'vuex'
/**
* @Author: 王林
@@ -38,20 +37,17 @@ export default {
return {}
},
computed: {
...mapState(['activeSidebar']),
shortcutKeyList() {
return shortcutKeyList[this.$i18n.locale] || shortcutKeyList.zh
}
},
watch: {
activeSidebar(val) {
if (val === 'shortcutKey') {
created() {
this.$bus.$on('showShortcutKey', () => {
this.$refs.sidebar.show = false
this.$nextTick(() => {
this.$refs.sidebar.show = true
} else {
this.$refs.sidebar.show = false
}
}
})
})
}
}
</script>

View File

@@ -5,7 +5,7 @@
:class="{ show: show }"
:style="{ zIndex: zIndex }"
>
<span class="closeBtn el-icon-close" @click="close"></span>
<span class="closeBtn el-icon-close" @click="show = false"></span>
<div class="sidebarHeader" v-if="title">
{{ title }}
</div>
@@ -17,7 +17,6 @@
<script>
import { store } from '@/config'
import { mapState, mapMutations } from 'vuex'
/**
* @Author: 王林
@@ -44,14 +43,6 @@ export default {
this.zIndex = store.sidebarZIndex++
}
}
},
methods: {
...mapMutations(['setActiveSidebar']),
close() {
this.show = false
this.setActiveSidebar('')
}
}
}
</script>

View File

@@ -1,107 +0,0 @@
<template>
<div
class="sidebarTriggerContainer"
@click.stop
:class="{ show: activeSidebar }"
>
<div class="trigger">
<div
class="triggerItem"
v-for="item in triggerList"
:key="item.value"
:class="{ active: activeSidebar === item.value }"
@click="trigger(item)"
>
<div class="triggerIcon iconfont" :class="[item.icon]"></div>
<div class="triggerName">{{ item.name }}</div>
</div>
</div>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex'
import { sidebarTriggerList } from '@/config'
/**
* @Author: 王林
* @Date: 2021-06-24 22:54:25
* @Desc: 侧边栏触发器
*/
export default {
name: 'SidebarTrigger',
data() {
return {
show: false
}
},
computed: {
...mapState(['activeSidebar']),
triggerList() {
return sidebarTriggerList[this.$i18n.locale] || sidebarTriggerList.zh
}
},
methods: {
...mapMutations(['setActiveSidebar']),
trigger(item) {
this.setActiveSidebar(item.value)
}
}
}
</script>
<style lang="less" scoped>
.sidebarTriggerContainer {
position: fixed;
right: 0px;
margin-top: 110px;
transition: all 0.3s;
top: 50%;
transform: translateY(-50%);
&.show {
right: 305px;
}
.trigger {
width: 60px;
border-color: #eee;
background-color: #fff;
box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.06);
border-radius: 6px;
overflow: hidden;
.triggerItem {
height: 60px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
color: #464646;
user-select: none;
white-space: nowrap;
&:hover {
background-color: #ededed;
}
&.active {
color: #409eff;
font-weight: bold;
}
.triggerIcon {
font-size: 18px;
margin-bottom: 5px;
}
.triggerName {
font-size: 13px;
}
}
}
}
</style>

View File

@@ -21,7 +21,6 @@
import Sidebar from './Sidebar'
import { layoutList } from 'simple-mind-map/src/utils/constant'
import { storeConfig } from '@/api'
import { mapState } from 'vuex'
/**
* @Author: 王林
@@ -44,18 +43,14 @@ export default {
layout: ''
}
},
computed: {
...mapState(['activeSidebar'])
},
watch: {
activeSidebar(val) {
if (val === 'structure') {
created() {
this.$bus.$on('showStructure', () => {
this.$refs.sidebar.show = false
this.$nextTick(() => {
this.layout = this.mindMap.getLayout()
this.$refs.sidebar.show = true
} else {
this.$refs.sidebar.show = false
}
}
})
})
},
methods: {
/**

View File

@@ -1,6 +1,6 @@
<template>
<Sidebar ref="sidebar" :title="$t('style.title')">
<div class="styleBox" v-if="activeNodes.length > 0">
<div class="styleBox">
<el-tabs class="tab" v-model="activeTab" @tab-click="handleTabClick">
<el-tab-pane :label="$t('style.normal')" name="normal"></el-tab-pane>
<el-tab-pane :label="$t('style.active')" name="active"></el-tab-pane>
@@ -367,10 +367,6 @@
</div>
</div>
</div>
<div class="tipBox" v-else>
<div class="tipIcon iconfont icontianjiazijiedian"></div>
<div class="tipText">请选择一个节点</div>
</div>
</Sidebar>
</template>
@@ -387,7 +383,6 @@ import {
shapeList
} from '@/config'
import { supportActiveStyle } from 'simple-mind-map/src/themes/default'
import { mapState } from 'vuex'
/**
* @Author: 王林
@@ -434,8 +429,6 @@ export default {
}
},
computed: {
...mapState(['activeSidebar']),
fontFamilyList() {
return fontFamilyList[this.$i18n.locale] || fontFamilyList.zh
},
@@ -446,35 +439,19 @@ export default {
return shapeList[this.$i18n.locale] || shapeList.zh
}
},
watch: {
activeSidebar(val) {
if (val === 'nodeStyle') {
this.$refs.sidebar.show = true
} else {
this.$refs.sidebar.show = false
}
}
},
created() {
this.$bus.$on('node_active', this.onNodeActive)
},
beforeDestroy() {
this.$bus.$off('node_active', this.onNodeActive)
},
methods: {
/**
* @Author: 王林25
* @Date: 2022-11-14 19:16:21
* @Desc: 监听节点激活事件
*/
onNodeActive(...args) {
this.$bus.$on('node_active', (...args) => {
if (this.$refs.sidebar) this.$refs.sidebar.show = false
this.$nextTick(() => {
this.activeTab = 'normal'
this.activeNodes = args[1]
if (this.$refs.sidebar)
this.$refs.sidebar.show = this.activeNodes.length > 0
this.initNodeStyle()
})
},
})
},
methods: {
/**
* @Author: 王林
* @Date: 2021-05-05 11:42:32
@@ -629,20 +606,6 @@ export default {
}
}
.tipBox {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #666;
.tipIcon {
font-size: 100px;
}
}
.sidebarContent {
padding: 20px;
padding-top: 10px;

View File

@@ -21,7 +21,6 @@
import Sidebar from './Sidebar'
import { themeList } from 'simple-mind-map/src/utils/constant'
import { storeConfig } from '@/api'
import { mapState } from 'vuex'
/**
* @Author: 王林
@@ -44,18 +43,14 @@ export default {
theme: ''
}
},
computed: {
...mapState(['activeSidebar'])
},
watch: {
activeSidebar(val) {
if (val === 'theme') {
created() {
this.$bus.$on('showTheme', () => {
this.$refs.sidebar.show = false
this.$nextTick(() => {
this.theme = this.mindMap.getTheme()
this.$refs.sidebar.show = true
} else {
this.$refs.sidebar.show = false
}
}
})
})
},
methods: {
/**

View File

@@ -114,6 +114,25 @@
<span class="text">{{ $t('toolbar.summary') }}</span>
</div>
</div>
<!-- 通用操作 -->
<div class="toolbarBlock">
<div class="toolbarBtn" @click="$bus.$emit('showOutline')">
<span class="icon iconfont iconfuhao-dagangshu"></span>
<span class="text">{{ $t('toolbar.displayOutline') }}</span>
</div>
<div class="toolbarBtn" @click="$bus.$emit('showBaseStyle')">
<span class="icon iconfont iconyangshi"></span>
<span class="text">{{ $t('toolbar.baseStyle') }}</span>
</div>
<div class="toolbarBtn" @click="$bus.$emit('showTheme')">
<span class="icon iconfont iconjingzi"></span>
<span class="text">{{ $t('toolbar.theme') }}</span>
</div>
<div class="toolbarBtn" @click="$bus.$emit('showStructure')">
<span class="icon iconfont iconjiegou"></span>
<span class="text">{{ $t('toolbar.strusture') }}</span>
</div>
</div>
<!-- 导出 -->
<div class="toolbarBlock">
<div class="toolbarBtn" @click="createNewLocalFile">
@@ -136,6 +155,10 @@
<span class="icon iconfont iconexport"></span>
<span class="text">{{ $t('toolbar.export') }}</span>
</div>
<div class="toolbarBtn" @click="$bus.$emit('showShortcutKey')">
<span class="icon iconfont iconjianpan"></span>
<span class="text">{{ $t('toolbar.shortcutKey') }}</span>
</div>
</div>
</div>
<NodeImage></NodeImage>
@@ -213,58 +236,24 @@ export default {
}
},
created() {
this.$bus.$on('mode_change', this.onModeChange)
this.$bus.$on('node_active', this.onNodeActive)
this.$bus.$on('back_forward', this.onBackForward)
this.$bus.$on('write_local_file', this.onWriteLocalFile)
},
beforeDestroy() {
this.$bus.$off('mode_change', this.onModeChange)
this.$bus.$off('node_active', this.onNodeActive)
this.$bus.$off('back_forward', this.onBackForward)
this.$bus.$off('write_local_file', this.onWriteLocalFile)
},
methods: {
/**
* @Author: 王林25
* @Date: 2022-11-14 19:17:40
* @Desc: 监听模式切换
*/
onModeChange(mode) {
this.$bus.$on('mode_change', mode => {
this.readonly = mode === 'readonly'
},
/**
* @Author: 王林25
* @Date: 2022-11-14 19:18:06
* @Desc: 监听节点激活
*/
onNodeActive(...args) {
})
this.$bus.$on('node_active', (...args) => {
this.activeNodes = args[1]
},
/**
* @Author: 王林25
* @Date: 2022-11-14 19:18:31
* @Desc: 监听前进后退
*/
onBackForward(index, len) {
})
this.$bus.$on('back_forward', (index, len) => {
this.backEnd = index <= 0
this.forwardEnd = index >= len - 1
},
/**
* @Author: 王林25
* @Date: 2022-11-14 19:19:14
* @Desc: 监听本地文件读写
*/
onWriteLocalFile(content) {
})
this.$bus.$on('write_local_file', content => {
clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.writeLocalFile(content)
}, 1000)
},
})
},
methods: {
/**
* @Author: 王林
* @Date: 2022-09-24 15:40:09

View File

@@ -1,19 +1,13 @@
import Vue from 'vue'
import Vuex from 'vuex'
import exampleData from 'simple-mind-map/example/exampleData'
import { storeLocalConfig } from '@/api'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
mindMapData: null, // 思维导图数据
isHandleLocalFile: false, // 是否操作的是本地文件
localConfig: {
// 本地配置
isZenMode: false // 是否是禅模式
},
activeSidebar: '' // 当前显示的侧边栏
isHandleLocalFile: false // 是否操作的是本地文件
},
mutations: {
/**
@@ -33,30 +27,6 @@ const store = new Vuex.Store({
*/
setIsHandleLocalFile(state, data) {
state.isHandleLocalFile = data
},
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-11-14 18:42:47
* @Desc: 设置本地配置
*/
setLocalConfig(state, data) {
state.localConfig = {
...state.localConfig,
...data
}
storeLocalConfig(state.localConfig)
},
/**
* javascript comment
* @Author: 王林25
* @Date: 2022-11-15 19:25:26
* @Desc: 设置当前显示的侧边栏
*/
setActiveSidebar(state, data) {
state.activeSidebar = data
}
},
actions: {