Merge branch 'feature' into main

This commit is contained in:
wanglin2 2023-04-05 16:47:06 +08:00
commit 6ccafaa771
17 changed files with 156 additions and 9 deletions

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"><link rel="icon" href="./dist/logo.png"><title>一个简单的web思维导图实现</title><link href="dist/js/chunk-2d0a3179.3b27bed0.js" rel="prefetch"><link href="dist/js/chunk-2d0a514a.64cc7822.js" rel="prefetch"><link href="dist/js/chunk-2d0aa579.61afd8c1.js" rel="prefetch"><link href="dist/js/chunk-2d0aa978.84fc06da.js" rel="prefetch"><link href="dist/js/chunk-2d0ab10b.4d405645.js" rel="prefetch"><link href="dist/js/chunk-2d0abe0f.a9abff6a.js" rel="prefetch"><link href="dist/js/chunk-2d0b1c6f.b8417307.js" rel="prefetch"><link href="dist/js/chunk-2d0b361e.d657e190.js" rel="prefetch"><link href="dist/js/chunk-2d0b91e5.433fdc5c.js" rel="prefetch"><link href="dist/js/chunk-2d0b92c3.9d7f8382.js" rel="prefetch"><link href="dist/js/chunk-2d0ba309.a3915823.js" rel="prefetch"><link href="dist/js/chunk-2d0bd54e.906e86ec.js" rel="prefetch"><link href="dist/js/chunk-2d0be174.0cf53d60.js" rel="prefetch"><link href="dist/js/chunk-2d0c0a44.1d1fb5b5.js" rel="prefetch"><link href="dist/js/chunk-2d0c14fc.7163274e.js" rel="prefetch"><link href="dist/js/chunk-2d0c18d8.108e4f7d.js" rel="prefetch"><link href="dist/js/chunk-2d0c191e.cd5e6df3.js" rel="prefetch"><link href="dist/js/chunk-2d0c1a01.2e73bf0a.js" rel="prefetch"><link href="dist/js/chunk-2d0c20be.dab092ff.js" rel="prefetch"><link href="dist/js/chunk-2d0d5cb9.2e73ab77.js" rel="prefetch"><link href="dist/js/chunk-2d0d9fbc.2d79582e.js" rel="prefetch"><link href="dist/js/chunk-2d0da701.80759043.js" rel="prefetch"><link href="dist/js/chunk-2d0dad5f.5fb896ad.js" rel="prefetch"><link href="dist/js/chunk-2d0db0f2.b5ce4946.js" rel="prefetch"><link href="dist/js/chunk-2d0dd3b1.c4647d07.js" rel="prefetch"><link href="dist/js/chunk-2d0dddce.3eea98de.js" rel="prefetch"><link href="dist/js/chunk-2d0ddf37.d960b122.js" rel="prefetch"><link href="dist/js/chunk-2d0de01b.a2a047cf.js" rel="prefetch"><link href="dist/js/chunk-2d0e2326.f519efd9.js" rel="prefetch"><link href="dist/js/chunk-2d0e268c.7bac07f7.js" rel="prefetch"><link href="dist/js/chunk-2d0e5089.10135360.js" rel="prefetch"><link href="dist/js/chunk-2d0e9742.9abceada.js" rel="prefetch"><link href="dist/js/chunk-2d0f026c.d3d121fa.js" rel="prefetch"><link href="dist/js/chunk-2d2082b9.f52387a2.js" rel="prefetch"><link href="dist/js/chunk-2d208ffa.a944214a.js" rel="prefetch"><link href="dist/js/chunk-2d20ec02.917aff76.js" rel="prefetch"><link href="dist/js/chunk-2d20f68f.e7133ec1.js" rel="prefetch"><link href="dist/js/chunk-2d210a7a.6a4911c4.js" rel="prefetch"><link href="dist/js/chunk-2d216004.75465efa.js" rel="prefetch"><link href="dist/js/chunk-2d217907.32a00939.js" rel="prefetch"><link href="dist/js/chunk-2d226d0a.6b1238d2.js" rel="prefetch"><link href="dist/js/chunk-2d2299c3.8f3151dd.js" rel="prefetch"><link href="dist/js/chunk-2d22bd06.9f7bbd4c.js" rel="prefetch"><link href="dist/js/chunk-2d2308b0.2797f6b4.js" rel="prefetch"><link href="dist/js/chunk-2d238428.7c9ae7c7.js" rel="prefetch"><link href="dist/js/chunk-3a2f3e67.13278516.js" rel="prefetch"><link href="dist/css/app.b091d972.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.c097b26d.css" rel="preload" as="style"><link href="dist/js/app.88eeb1b9.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.d36f5bd6.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.c097b26d.css" rel="stylesheet"><link href="dist/css/app.b091d972.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.d36f5bd6.js"></script><script src="dist/js/app.88eeb1b9.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"><link rel="icon" href="./dist/logo.png"><title>一个简单的web思维导图实现</title><link href="dist/js/chunk-2d0a3179.3b27bed0.js" rel="prefetch"><link href="dist/js/chunk-2d0a514a.64cc7822.js" rel="prefetch"><link href="dist/js/chunk-2d0aa579.61afd8c1.js" rel="prefetch"><link href="dist/js/chunk-2d0aa978.84fc06da.js" rel="prefetch"><link href="dist/js/chunk-2d0ab10b.4d405645.js" rel="prefetch"><link href="dist/js/chunk-2d0abe0f.a9abff6a.js" rel="prefetch"><link href="dist/js/chunk-2d0b1c6f.b8417307.js" rel="prefetch"><link href="dist/js/chunk-2d0b361e.d657e190.js" rel="prefetch"><link href="dist/js/chunk-2d0b91e5.433fdc5c.js" rel="prefetch"><link href="dist/js/chunk-2d0b92c3.9d7f8382.js" rel="prefetch"><link href="dist/js/chunk-2d0ba309.a3915823.js" rel="prefetch"><link href="dist/js/chunk-2d0bd54e.906e86ec.js" rel="prefetch"><link href="dist/js/chunk-2d0be174.0cf53d60.js" rel="prefetch"><link href="dist/js/chunk-2d0c0a44.1d1fb5b5.js" rel="prefetch"><link href="dist/js/chunk-2d0c14fc.7163274e.js" rel="prefetch"><link href="dist/js/chunk-2d0c18d8.108e4f7d.js" rel="prefetch"><link href="dist/js/chunk-2d0c191e.cd5e6df3.js" rel="prefetch"><link href="dist/js/chunk-2d0c1a01.2e73bf0a.js" rel="prefetch"><link href="dist/js/chunk-2d0c20be.dab092ff.js" rel="prefetch"><link href="dist/js/chunk-2d0d5cb9.2e73ab77.js" rel="prefetch"><link href="dist/js/chunk-2d0d9fbc.efe9e903.js" rel="prefetch"><link href="dist/js/chunk-2d0da701.80759043.js" rel="prefetch"><link href="dist/js/chunk-2d0dad5f.8672c102.js" rel="prefetch"><link href="dist/js/chunk-2d0db0f2.b5ce4946.js" rel="prefetch"><link href="dist/js/chunk-2d0dd3b1.c4647d07.js" rel="prefetch"><link href="dist/js/chunk-2d0dddce.3eea98de.js" rel="prefetch"><link href="dist/js/chunk-2d0ddf37.d960b122.js" rel="prefetch"><link href="dist/js/chunk-2d0de01b.a2a047cf.js" rel="prefetch"><link href="dist/js/chunk-2d0e2326.f519efd9.js" rel="prefetch"><link href="dist/js/chunk-2d0e268c.7bac07f7.js" rel="prefetch"><link href="dist/js/chunk-2d0e5089.10135360.js" rel="prefetch"><link href="dist/js/chunk-2d0e9742.9abceada.js" rel="prefetch"><link href="dist/js/chunk-2d0f026c.fcf76481.js" rel="prefetch"><link href="dist/js/chunk-2d2082b9.f52387a2.js" rel="prefetch"><link href="dist/js/chunk-2d208ffa.30f70815.js" rel="prefetch"><link href="dist/js/chunk-2d20ec02.917aff76.js" rel="prefetch"><link href="dist/js/chunk-2d20f68f.e7133ec1.js" rel="prefetch"><link href="dist/js/chunk-2d210a7a.6a4911c4.js" rel="prefetch"><link href="dist/js/chunk-2d216004.75465efa.js" rel="prefetch"><link href="dist/js/chunk-2d217907.32a00939.js" rel="prefetch"><link href="dist/js/chunk-2d226d0a.6b1238d2.js" rel="prefetch"><link href="dist/js/chunk-2d2299c3.8f3151dd.js" rel="prefetch"><link href="dist/js/chunk-2d22bd06.9f7bbd4c.js" rel="prefetch"><link href="dist/js/chunk-2d2308b0.2797f6b4.js" rel="prefetch"><link href="dist/js/chunk-2d238428.7c9ae7c7.js" rel="prefetch"><link href="dist/js/chunk-3a2f3e67.13278516.js" rel="prefetch"><link href="dist/css/app.121b2896.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.c097b26d.css" rel="preload" as="style"><link href="dist/js/app.2baf713e.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.d36f5bd6.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.c097b26d.css" rel="stylesheet"><link href="dist/css/app.121b2896.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.d36f5bd6.js"></script><script src="dist/js/app.2baf713e.js"></script></body></html>

View File

@ -82,7 +82,13 @@ const defaultOpt = {
expandBtnIcon: {
open: '',// svg字符串
close: ''
}
},
// 是否只有当鼠标在画布内才响应快捷键事件
enableShortcutOnlyWhenMouseInSvg: true,
// 是否开启节点动画过渡
enableNodeTransitionMove: true,
// 如果开启节点动画过渡可以通过该属性设置过渡的时间单位ms
nodeTransitionMoveDuration: 300
}
// 思维导图

View File

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

View File

@ -35,6 +35,8 @@ class Event extends EventEmitter {
this.onContextmenu = this.onContextmenu.bind(this)
this.onSvgMousedown = this.onSvgMousedown.bind(this)
this.onKeyup = this.onKeyup.bind(this)
this.onMouseenter = this.onMouseenter.bind(this)
this.onMouseleave = this.onMouseleave.bind(this)
}
// 绑定事件
@ -46,6 +48,8 @@ class Event extends EventEmitter {
window.addEventListener('mouseup', this.onMouseup)
this.mindMap.el.addEventListener('wheel', this.onMousewheel)
this.mindMap.svg.on('contextmenu', this.onContextmenu)
this.mindMap.svg.on('mouseenter', this.onMouseenter)
this.mindMap.svg.on('mouseleave', this.onMouseleave)
window.addEventListener('keyup', this.onKeyup)
}
@ -57,6 +61,8 @@ class Event extends EventEmitter {
window.removeEventListener('mouseup', this.onMouseup)
this.mindMap.el.removeEventListener('wheel', this.onMousewheel)
this.mindMap.svg.off('contextmenu', this.onContextmenu)
this.mindMap.svg.off('mouseenter', this.onMouseenter)
this.mindMap.svg.off('mouseleave', this.onMouseleave)
window.removeEventListener('keyup', this.onKeyup)
}
@ -130,6 +136,16 @@ class Event extends EventEmitter {
onKeyup(e) {
this.emit('keyup', e)
}
// 进入
onMouseenter(e) {
this.emit('svg_mouseenter', e)
}
// 离开
onMouseleave(e) {
this.emit('svg_mouseleave', e)
}
}
export default Event

View File

@ -10,6 +10,7 @@ export default class KeyCommand {
}
this.shortcutMapCache = {}
this.isPause = false
this.isInSvg = false
this.bindEvent()
}
@ -37,8 +38,21 @@ export default class KeyCommand {
// 绑定事件
bindEvent() {
// 只有当鼠标在画布内才响应快捷键
this.mindMap.on('svg_mouseenter', () => {
this.isInSvg = true
})
this.mindMap.on('svg_mouseleave', () => {
if (this.mindMap.richText && this.mindMap.richText.showTextEdit) {
return
}
if (this.mindMap.renderer.textEdit.showTextEdit) {
return
}
this.isInSvg = false
})
window.addEventListener('keydown', e => {
if (this.isPause) {
if (this.isPause || (this.mindMap.opt.enableShortcutOnlyWhenMouseInSvg && !this.isInSvg)) {
return
}
Object.keys(this.shortcutMap).forEach(key => {

View File

@ -414,6 +414,7 @@ class Node {
if (!this.group) {
return
}
let { enableNodeTransitionMove, nodeTransitionMoveDuration } = this.mindMap.opt
// 需要移除展开收缩按钮
if (this._expandBtn && this.nodeData.children.length <= 0) {
this.removeExpandBtn()
@ -425,9 +426,9 @@ class Node {
this.renderGeneralization()
// 更新节点位置
let t = this.group.transform()
if (!isLayout) {
if (!isLayout && enableNodeTransitionMove) {
this.group
.animate(300)
.animate(nodeTransitionMoveDuration)
.translate(
this.left - t.translateX,
this.top - t.translateY
@ -457,10 +458,13 @@ class Node {
// 递归渲染
render(callback = () => {}) {
let { enableNodeTransitionMove, nodeTransitionMoveDuration } = this.mindMap.opt
// 节点
// 重新渲染连线
this.renderLine()
let isLayout = false
if (!this.group) {
isLayout = true
// 创建组
this.group = new G()
this.group.css({
@ -469,7 +473,7 @@ class Node {
this.bindGroupEvent()
this.draw.add(this.group)
this.layout()
this.update(true)
this.update(isLayout)
} else {
this.draw.add(this.group)
if (this.needLayout) {
@ -498,7 +502,13 @@ class Node {
})
)
} else {
callback()
if (enableNodeTransitionMove && !isLayout) {
setTimeout(() => {
callback()
}, nodeTransitionMoveDuration)
} else {
callback()
}
}
// 手动插入的节点立即获得焦点并且开启编辑模式
if (this.nodeData.inserting) {

View File

@ -67,7 +67,7 @@ class Base {
newNode.getSize()
newNode.needLayout = true
}
} else if (this.nodePool[data.data.uid]) {
} else if (this.nodePool[data.data.uid] && !this.renderer.reRender) {
// 数据上没有保存节点引用但是通过uid找到了缓存的节点也可以复用
newNode = this.nodePool[data.data.uid]
// 保存该节点上一次的数据

View File

@ -1,5 +1,11 @@
# Changelog
## 0.5.1
optimization: 1.Only respond to shortcut key events when the mouse is inside the canvas
Fix: 1.Fix the issue of incorrect node position during fast operation
## 0.5.0
This version is mainly about code level changes and optimization, with the core goal of improving rendering performance and reducing stuck issues.

View File

@ -1,6 +1,9 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.5.1</h2>
<p>optimization: 1.Only respond to shortcut key events when the mouse is inside the canvas</p>
<p>Fix: 1.Fix the issue of incorrect node position during fast operation</p>
<h2>0.5.0</h2>
<p>This version is mainly about code level changes and optimization, with the core goal of improving rendering performance and reducing stuck issues.</p>
<p>New: 1.Support custom expansion and collapse node icons and colors;</p>

View File

@ -48,6 +48,9 @@ const mindMap = new MindMap({
| defaultInsertBelowSecondLevelNodeTextv0.4.7+ | String | 分支主题 | Text for nodes below the second level inserted by default | |
| expandBtnStylev0.5.0+ | Object | { color: '#808080', fill: '#fff' } | Expand the color of the stow button | |
| expandBtnIconv0.5.0+ | Object | { open: '', close: '' } | Customize the icon of the expand/collapse button, and you can transfer the svg string of the icon | |
| enableShortcutOnlyWhenMouseInSvgv0.5.1+ | Boolean | true | Only respond to shortcut key events when the mouse is inside the canvas | |
| enableNodeTransitionMovev0.5.1+ | Boolean | true | Whether to enable node animation transition | |
| nodeTransitionMoveDurationv0.5.1+ | Number | 300 | If node animation transition is enabled, the transition time can be set using this attribute, in milliseconds | |
### Watermark config
@ -200,6 +203,8 @@ Listen to an event. Event list:
| node_draggingv0.4.5+ | Triggered when a node is dragged | node(The currently dragged node) |
| node_dragendv0.4.5+ | Triggered when the node is dragged and ends | |
| associative_line_clickv0.4.5+ | Triggered when an associated line is clicked | path(Connector node)、clickPath(Invisible click line node)、node(Start node)、toNode(Target node) |
| svg_mouseenterv0.5.1+ | Triggered when the mouse moves into the SVG canvas | eevent object |
| svg_mouseleavev0.5.1+ | Triggered when the mouse moves out of the SVG canvas | eevent object |
### emit(event, ...args)

View File

@ -196,6 +196,27 @@
<td>Customize the icon of the expand/collapse button, and you can transfer the svg string of the icon</td>
<td></td>
</tr>
<tr>
<td>enableShortcutOnlyWhenMouseInSvgv0.5.1+</td>
<td>Boolean</td>
<td>true</td>
<td>Only respond to shortcut key events when the mouse is inside the canvas</td>
<td></td>
</tr>
<tr>
<td>enableNodeTransitionMovev0.5.1+</td>
<td>Boolean</td>
<td>true</td>
<td>Whether to enable node animation transition</td>
<td></td>
</tr>
<tr>
<td>nodeTransitionMoveDurationv0.5.1+</td>
<td>Number</td>
<td>300</td>
<td>If node animation transition is enabled, the transition time can be set using this attribute, in milliseconds</td>
<td></td>
</tr>
</tbody>
</table>
<h3>Watermark config</h3>
@ -490,6 +511,16 @@ poor performance and should be used sparingly.</p>
<td>Triggered when an associated line is clicked</td>
<td>path(Connector node)clickPath(Invisible click line node)node(Start node)toNode(Target node)</td>
</tr>
<tr>
<td>svg_mouseenterv0.5.1+</td>
<td>Triggered when the mouse moves into the SVG canvas</td>
<td>eevent object</td>
</tr>
<tr>
<td>svg_mouseleavev0.5.1+</td>
<td>Triggered when the mouse moves out of the SVG canvas</td>
<td>eevent object</td>
</tr>
</tbody>
</table>
<h3>emit(event, ...args)</h3>

View File

@ -1,5 +1,11 @@
# Changelog
## 0.5.1
优化1.只有当鼠标在画布内才响应快捷键事件
修复1.修复快速操作时节点位置不正确的问题
## 0.5.0
这个版本主要是代码层面的改动和优化,核心是为了提升渲染性能,减少卡顿问题。

View File

@ -1,6 +1,9 @@
<template>
<div>
<h1>Changelog</h1>
<h2>0.5.1</h2>
<p>优化1.只有当鼠标在画布内才响应快捷键事件</p>
<p>修复1.修复快速操作时节点位置不正确的问题</p>
<h2>0.5.0</h2>
<p>这个版本主要是代码层面的改动和优化核心是为了提升渲染性能减少卡顿问题</p>
<p>新增1.支持自定义展开收起节点图标和颜色</p>

View File

@ -48,6 +48,9 @@ const mindMap = new MindMap({
| defaultInsertBelowSecondLevelNodeTextv0.4.7+ | String | 分支主题 | 默认插入的二级以下节点的文字 | |
| expandBtnStylev0.5.0+ | Object | { color: '#808080', fill: '#fff' } | 展开收起按钮的颜色 | |
| expandBtnIconv0.5.0+ | Object | { open: '', close: '' } | 自定义展开收起按钮的图标可以传图标的svg字符串 | |
| enableShortcutOnlyWhenMouseInSvgv0.5.1+ | Boolean | true | 是否只有当鼠标在画布内才响应快捷键事件 | |
| enableNodeTransitionMovev0.5.1+ | Boolean | true | 是否开启节点动画过渡 | |
| nodeTransitionMoveDurationv0.5.1+ | Number | 300 | 如果开启节点动画过渡可以通过该属性设置过渡的时间单位ms | |
### 水印配置
@ -197,6 +200,8 @@ mindMap.setTheme('主题名称')
| node_draggingv0.4.5+ | 当某个节点被拖拽时触发 | node当前被拖拽的节点 |
| node_dragendv0.4.5+ | 节点被拖拽结束时触发 | |
| associative_line_clickv0.4.5+ | 点击某条关联线时触发 | path连接线节点、clickPath不可见的点击线节点、node起始节点、toNode目标节点 |
| svg_mouseenterv0.5.1+ | 鼠标移入svg画布时触发 | e事件对象 |
| svg_mouseleavev0.5.1+ | 鼠标移出svg画布时触发 | e事件对象 |
### emit(event, ...args)

View File

@ -196,6 +196,27 @@
<td>自定义展开收起按钮的图标可以传图标的svg字符串</td>
<td></td>
</tr>
<tr>
<td>enableShortcutOnlyWhenMouseInSvgv0.5.1+</td>
<td>Boolean</td>
<td>true</td>
<td>是否只有当鼠标在画布内才响应快捷键事件</td>
<td></td>
</tr>
<tr>
<td>enableNodeTransitionMovev0.5.1+</td>
<td>Boolean</td>
<td>true</td>
<td>是否开启节点动画过渡</td>
<td></td>
</tr>
<tr>
<td>nodeTransitionMoveDurationv0.5.1+</td>
<td>Number</td>
<td>300</td>
<td>如果开启节点动画过渡可以通过该属性设置过渡的时间单位ms</td>
<td></td>
</tr>
</tbody>
</table>
<h3>水印配置</h3>
@ -483,6 +504,16 @@ mindMap.setTheme(<span class="hljs-string">&#x27;主题名称&#x27;</span>)
<td>点击某条关联线时触发</td>
<td>path连接线节点clickPath不可见的点击线节点node起始节点toNode目标节点</td>
</tr>
<tr>
<td>svg_mouseenterv0.5.1+</td>
<td>鼠标移入svg画布时触发</td>
<td>e事件对象</td>
</tr>
<tr>
<td>svg_mouseleavev0.5.1+</td>
<td>鼠标移出svg画布时触发</td>
<td>e事件对象</td>
</tr>
</tbody>
</table>
<h3>emit(event, ...args)</h3>

View File

@ -126,6 +126,9 @@ export default {
this.$bus.$on('createAssociativeLine', () => {
this.mindMap.associativeLine.createLineFromActiveNode()
})
window.addEventListener('resize', () => {
this.mindMap.resize()
})
if (this.openTest) {
setTimeout(() => {
this.test()
@ -336,6 +339,7 @@ export default {
} else {
this.mindMap.setData(data)
}
this.mindMap.view.reset()
// this.manualSave()
},

View File

@ -50,6 +50,7 @@ export default {
}
},
notHandleDataChange: false,
isCreateNode: false
}
},
computed: {
@ -76,6 +77,10 @@ export default {
},
methods: {
onBlur(e, node) {
if (this.isCreateNode) {
this.isCreateNode = false
return
}
node.data._node.setText(e.target.innerText)
},
@ -97,12 +102,14 @@ export default {
//
insertNode() {
this.notHandleDataChange = false
this.isCreateNode = true
this.mindMap.execCommand('INSERT_NODE', false)
},
//
insertChildNode() {
this.notHandleDataChange = false
this.isCreateNode = true
this.mindMap.execCommand('INSERT_CHILD_NODE', false)
},