diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..318ebe89 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2021-2023 The MindMap Team + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 29f08922..12a304a2 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,12 @@ 在线地址:[https://wanglin2.github.io/mind-map/](https://wanglin2.github.io/mind-map/) +另外也提供了客户端可供下载使用,支持`Windows`、`Mac`及`Linux`,下载地址: + +Github:[releases](https://github.com/wanglin2/mind-map/releases)。 + +百度云盘:[地址](https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3)。 + # 特性 - [x] 插件化架构,除核心功能外,其他功能作为插件提供,按需使用,减小打包体积 @@ -84,4 +90,15 @@ MIT # 微信交流群 -![](./qrcode.jpg) \ No newline at end of file + + +# 请作者喝杯咖啡 + +> 厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds + +> 转账请备注哦~你的头像和名称会出现在[文档页面](https://wanglin2.github.io/mind-map/#/doc/zh/introduction/%E8%AF%B7%E4%BD%9C%E8%80%85%E5%96%9D%E6%9D%AF%E5%92%96%E5%95%A1) + +

+ + +

\ No newline at end of file diff --git a/index.html b/index.html index 4bdd84c3..ffed24e8 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -一个简单的web思维导图实现
\ No newline at end of file +一个简单的web思维导图实现
\ No newline at end of file diff --git a/qrcode.jpg b/qrcode.jpg index 956f3e9e..507f3135 100644 Binary files a/qrcode.jpg and b/qrcode.jpg differ diff --git a/simple-mind-map/full.js b/simple-mind-map/full.js index 80048f10..51ac4c7b 100644 --- a/simple-mind-map/full.js +++ b/simple-mind-map/full.js @@ -1,12 +1,13 @@ import MindMap from './index' -import MiniMap from './src/MiniMap.js' -import Watermark from './src/Watermark.js' -import KeyboardNavigation from './src/KeyboardNavigation.js' -import Export from './src/Export.js' -import Drag from './src/Drag.js' -import Select from './src/Select.js' -import AssociativeLine from './src/AssociativeLine' -import RichText from './src/RichText' +import MiniMap from './src/plugins/MiniMap.js' +import Watermark from './src/plugins/Watermark.js' +import KeyboardNavigation from './src/plugins/KeyboardNavigation.js' +import ExportPDF from './src/plugins/ExportPDF.js' +import Export from './src/plugins/Export.js' +import Drag from './src/plugins/Drag.js' +import Select from './src/plugins/Select.js' +import AssociativeLine from './src/plugins/AssociativeLine' +import RichText from './src/plugins/RichText' import xmind from './src/parse/xmind.js' import markdown from './src/parse/markdown.js' import icons from './src/svg/icons.js' @@ -20,6 +21,7 @@ MindMap .usePlugin(Watermark) .usePlugin(Drag) .usePlugin(KeyboardNavigation) + .usePlugin(ExportPDF) .usePlugin(Export) .usePlugin(Select) .usePlugin(AssociativeLine) diff --git a/simple-mind-map/index.js b/simple-mind-map/index.js index 1b283f4c..3802b389 100644 --- a/simple-mind-map/index.js +++ b/simple-mind-map/index.js @@ -1,13 +1,13 @@ -import View from './src/View' -import Event from './src/Event' -import Render from './src/Render' +import View from './src/core/view/View' +import Event from './src/core/event/Event' +import Render from './src/core/render/Render' import merge from 'deepmerge' import theme from './src/themes' -import Style from './src/Style' -import KeyCommand from './src/KeyCommand' -import Command from './src/Command' -import BatchExecution from './src/BatchExecution' -import { layoutValueList, CONSTANTS } from './src/utils/constant' +import Style from './src/core/render/node/Style' +import KeyCommand from './src/core/command/KeyCommand' +import Command from './src/core/command/Command' +import BatchExecution from './src/utils/BatchExecution' +import { layoutValueList, CONSTANTS } from './src/constants/constant' import { SVG } from '@svgdotjs/svg.js' import { simpleDeepClone } from './src/utils' import defaultTheme, { checkIsNodeSizeIndependenceConfig } from './src/themes/default' @@ -122,7 +122,15 @@ const defaultOpt = { // 节点最大缓存数量 maxNodeCacheCount: 1000, // 关联线默认文字 - defaultAssociativeLineText: '关联' + defaultAssociativeLineText: '关联', + // 思维导图适应画布大小时的内边距 + fitPadding: 50, + // 是否开启按住ctrl键多选节点功能 + enableCtrlKeyNodeSelection: true, + // 设置为左键多选节点,右键拖动画布 + useLeftKeySelectionRightKeyDrag: false, + // 节点即将进入编辑前的回调方法,如果该方法返回true以外的值,那么将取消编辑,函数可以返回一个值,或一个Promise,回调参数为节点实例 + beforeTextEdit: null } // 思维导图 @@ -476,6 +484,21 @@ class MindMap { pluginOpt: plugin.pluginOpt }) } + + // 销毁 + destroy() { + // 移除插件 + [...MindMap.pluginList].forEach((plugin) => { + this[plugin.instanceName] = null + }) + // 解绑事件 + this.event.unbind() + // 移除画布节点 + this.svg.remove() + // 去除给容器元素设置的背景样式 + Style.removeBackgroundStyle(this.el) + this.el = null + } } // 插件列表 diff --git a/simple-mind-map/package-lock.json b/simple-mind-map/package-lock.json index dccb243b..811a8646 100644 --- a/simple-mind-map/package-lock.json +++ b/simple-mind-map/package-lock.json @@ -1,15 +1,14 @@ { "name": "simple-mind-map", - "version": "0.4.7", + "version": "0.6.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "version": "0.4.7", + "version": "0.6.0", "license": "MIT", "dependencies": { "@svgdotjs/svg.js": "^3.0.16", - "canvg": "^3.0.7", "deepmerge": "^1.5.2", "eventemitter3": "^4.0.7", "html2canvas": "^1.4.1", @@ -160,7 +159,8 @@ "node_modules/@types/raf": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz", - "integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==" + "integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==", + "optional": true }, "node_modules/@types/unist": { "version": "2.0.6", @@ -305,6 +305,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz", "integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==", + "optional": true, "dependencies": { "@babel/runtime": "^7.12.5", "@types/raf": "^3.4.0", @@ -381,6 +382,7 @@ "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz", "integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==", "hasInstallScript": true, + "optional": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -1813,7 +1815,8 @@ "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "optional": true }, "node_modules/prelude-ls": { "version": "1.2.1", @@ -1908,6 +1911,7 @@ "version": "3.4.1", "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "optional": true, "dependencies": { "performance-now": "^2.1.0" } @@ -1982,6 +1986,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==", + "optional": true, "engines": { "node": ">= 0.8.15" } @@ -2075,6 +2080,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.5.0.tgz", "integrity": "sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==", + "optional": true, "engines": { "node": ">=0.1.14" } @@ -2127,6 +2133,7 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", + "optional": true, "engines": { "node": ">=12.0.0" } @@ -2386,7 +2393,8 @@ "@types/raf": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.0.tgz", - "integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==" + "integrity": "sha512-taW5/WYqo36N7V39oYyHP9Ipfd5pNFvGTIQsNGj86xV88YQ7GnI30/yMfKDF7Zgin0m3e+ikX88FvImnK4RjGw==", + "optional": true }, "@types/unist": { "version": "2.0.6", @@ -2489,6 +2497,7 @@ "version": "3.0.10", "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz", "integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==", + "optional": true, "requires": { "@babel/runtime": "^7.12.5", "@types/raf": "^3.4.0", @@ -2544,7 +2553,8 @@ "core-js": { "version": "3.27.1", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.27.1.tgz", - "integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==" + "integrity": "sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww==", + "optional": true }, "core-util-is": { "version": "1.0.3", @@ -3511,7 +3521,8 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==", + "optional": true }, "prelude-ls": { "version": "1.2.1", @@ -3576,6 +3587,7 @@ "version": "3.4.1", "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz", "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==", + "optional": true, "requires": { "performance-now": "^2.1.0" } @@ -3630,7 +3642,8 @@ "rgbcolor": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz", - "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==" + "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==", + "optional": true }, "rimraf": { "version": "3.0.2", @@ -3691,7 +3704,8 @@ "stackblur-canvas": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.5.0.tgz", - "integrity": "sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==" + "integrity": "sha512-EeNzTVfj+1In7aSLPKDD03F/ly4RxEuF/EX0YcOG0cKoPXs+SLZxDawQbexQDBzwROs4VKLWTOaZQlZkGBFEIQ==", + "optional": true }, "string_decoder": { "version": "1.1.1", @@ -3728,7 +3742,8 @@ "svg-pathdata": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz", - "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==" + "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==", + "optional": true }, "text-segmentation": { "version": "1.0.3", diff --git a/simple-mind-map/package.json b/simple-mind-map/package.json index a5a08080..9c15737f 100644 --- a/simple-mind-map/package.json +++ b/simple-mind-map/package.json @@ -1,6 +1,6 @@ { "name": "simple-mind-map", - "version": "0.5.11", + "version": "0.6.2", "description": "一个简单的web在线思维导图", "authors": [ { @@ -25,7 +25,6 @@ "__main": "./dist/simpleMindMap.umd.min.js", "dependencies": { "@svgdotjs/svg.js": "^3.0.16", - "canvg": "^3.0.7", "deepmerge": "^1.5.2", "eventemitter3": "^4.0.7", "html2canvas": "^1.4.1", diff --git a/simple-mind-map/src/utils/constant.js b/simple-mind-map/src/constants/constant.js similarity index 93% rename from simple-mind-map/src/utils/constant.js rename to simple-mind-map/src/constants/constant.js index 6505b71d..a441e99d 100644 --- a/simple-mind-map/src/utils/constant.js +++ b/simple-mind-map/src/constants/constant.js @@ -259,4 +259,24 @@ export const layoutValueList = [ CONSTANTS.LAYOUT.TIMELINE, CONSTANTS.LAYOUT.TIMELINE2, CONSTANTS.LAYOUT.FISHBONE +] + +// 节点数据中非样式的字段 +export const nodeDataNoStylePropList = [ + 'text', + 'image', + 'imageTitle', + 'imageSize', + 'icon', + 'tag', + 'hyperlink', + 'hyperlinkTitle', + 'note', + 'expand', + 'isActive', + 'generalization', + 'richText', + 'resetRichText', + 'uid', + 'activeStyle' ] \ No newline at end of file diff --git a/simple-mind-map/src/Command.js b/simple-mind-map/src/core/command/Command.js similarity index 98% rename from simple-mind-map/src/Command.js rename to simple-mind-map/src/core/command/Command.js index b1c35c57..2a5f3115 100644 --- a/simple-mind-map/src/Command.js +++ b/simple-mind-map/src/core/command/Command.js @@ -1,4 +1,4 @@ -import { copyRenderTree, simpleDeepClone, nextTick } from './utils' +import { copyRenderTree, simpleDeepClone, nextTick } from '../../utils' // 命令类 class Command { diff --git a/simple-mind-map/src/KeyCommand.js b/simple-mind-map/src/core/command/KeyCommand.js similarity index 98% rename from simple-mind-map/src/KeyCommand.js rename to simple-mind-map/src/core/command/KeyCommand.js index 579e219a..cc7a772b 100644 --- a/simple-mind-map/src/KeyCommand.js +++ b/simple-mind-map/src/core/command/KeyCommand.js @@ -1,4 +1,4 @@ -import { keyMap } from './utils/keyMap' +import { keyMap } from './keyMap' // 快捷按键、命令处理类 export default class KeyCommand { // 构造函数 diff --git a/simple-mind-map/src/utils/keyMap.js b/simple-mind-map/src/core/command/keyMap.js similarity index 100% rename from simple-mind-map/src/utils/keyMap.js rename to simple-mind-map/src/core/command/keyMap.js diff --git a/simple-mind-map/src/Event.js b/simple-mind-map/src/core/event/Event.js similarity index 87% rename from simple-mind-map/src/Event.js rename to simple-mind-map/src/core/event/Event.js index daac439f..3eb36d51 100644 --- a/simple-mind-map/src/Event.js +++ b/simple-mind-map/src/core/event/Event.js @@ -1,5 +1,5 @@ import EventEmitter from 'eventemitter3' -import { CONSTANTS } from './utils/constant' +import { CONSTANTS } from '../../constants/constant' // 事件类 class Event extends EventEmitter { @@ -9,6 +9,7 @@ class Event extends EventEmitter { this.opt = opt this.mindMap = opt.mindMap this.isLeftMousedown = false + this.isRightMousedown = false this.mousedownPos = { x: 0, y: 0 @@ -89,6 +90,8 @@ class Event extends EventEmitter { // 鼠标左键 if (e.which === 1) { this.isLeftMousedown = true + } else if (e.which === 3) { + this.isRightMousedown = true } this.mousedownPos.x = e.clientX this.mousedownPos.y = e.clientY @@ -97,12 +100,17 @@ class Event extends EventEmitter { // 鼠标移动事件 onMousemove(e) { + let { useLeftKeySelectionRightKeyDrag } = this.mindMap.opt this.mousemovePos.x = e.clientX this.mousemovePos.y = e.clientY this.mousemoveOffset.x = e.clientX - this.mousedownPos.x this.mousemoveOffset.y = e.clientY - this.mousedownPos.y this.emit('mousemove', e, this) - if (this.isLeftMousedown) { + if ( + useLeftKeySelectionRightKeyDrag + ? this.isRightMousedown + : this.isLeftMousedown + ) { e.preventDefault() this.emit('drag', e, this) } @@ -111,6 +119,7 @@ class Event extends EventEmitter { // 鼠标松开事件 onMouseup(e) { this.isLeftMousedown = false + this.isRightMousedown = false this.emit('mouseup', e, this) } @@ -131,7 +140,13 @@ class Event extends EventEmitter { if ((e.wheelDeltaX || e.detail) > 0) dir = CONSTANTS.DIR.LEFT if ((e.wheelDeltaX || e.detail) < 0) dir = CONSTANTS.DIR.RIGHT } - this.emit('mousewheel', e, dir, this) + // 判断是否是触控板 + let isTouchPad = false + // mac、windows + if (e.wheelDeltaY === e.deltaY * -3 || Math.abs(e.wheelDeltaY) <= 10) { + isTouchPad = true + } + this.emit('mousewheel', e, dir, this, isTouchPad) } // 鼠标右键菜单事件 diff --git a/simple-mind-map/src/Render.js b/simple-mind-map/src/core/render/Render.js similarity index 96% rename from simple-mind-map/src/Render.js rename to simple-mind-map/src/core/render/Render.js index 92ea717e..b2e3464a 100644 --- a/simple-mind-map/src/Render.js +++ b/simple-mind-map/src/core/render/Render.js @@ -1,15 +1,15 @@ import merge from 'deepmerge' -import LogicalStructure from './layouts/LogicalStructure' -import MindMap from './layouts/MindMap' -import CatalogOrganization from './layouts/CatalogOrganization' -import OrganizationStructure from './layouts/OrganizationStructure' -import Timeline from './layouts/Timeline' -import Fishbone from './layouts/Fishbone' +import LogicalStructure from '../../layouts/LogicalStructure' +import MindMap from '../../layouts/MindMap' +import CatalogOrganization from '../../layouts/CatalogOrganization' +import OrganizationStructure from '../../layouts/OrganizationStructure' +import Timeline from '../../layouts/Timeline' +import Fishbone from '../../layouts/Fishbone' import TextEdit from './TextEdit' -import { copyNodeTree, simpleDeepClone, walk } from './utils' -import { shapeList } from './Shape' -import { lineStyleProps } from './themes/default' -import { CONSTANTS } from './utils/constant' +import { copyNodeTree, simpleDeepClone, walk } from '../../utils' +import { shapeList } from './node/Shape' +import { lineStyleProps } from '../../themes/default' +import { CONSTANTS } from '../../constants/constant' // 布局列表 const layouts = { @@ -79,9 +79,15 @@ class Render { // 绑定事件 bindEvent() { // 点击事件 - this.mindMap.on('draw_click', () => { + this.mindMap.on('draw_click', (e) => { // 清除激活状态 - if (this.activeNodeList.length > 0) { + let isTrueClick = true + let { useLeftKeySelectionRightKeyDrag } = this.mindMap.opt + if (useLeftKeySelectionRightKeyDrag) { + let mousedownPos = this.mindMap.event.mousedownPos + isTrueClick = Math.abs(e.clientX - mousedownPos.x) <= 5 && Math.abs(e.clientY - mousedownPos.y) <= 5 + } + if (isTrueClick && this.activeNodeList.length > 0) { this.mindMap.execCommand('CLEAR_ACTIVE_NODE') } }) diff --git a/simple-mind-map/src/TextEdit.js b/simple-mind-map/src/core/render/TextEdit.js similarity index 94% rename from simple-mind-map/src/TextEdit.js rename to simple-mind-map/src/core/render/TextEdit.js index 80d7e90b..888ef7e3 100644 --- a/simple-mind-map/src/TextEdit.js +++ b/simple-mind-map/src/core/render/TextEdit.js @@ -1,4 +1,4 @@ -import { getStrWithBrFromHtml, checkNodeOuter } from './utils' +import { getStrWithBrFromHtml, checkNodeOuter } from '../../utils' // 节点文字编辑类 export default class TextEdit { @@ -65,7 +65,16 @@ export default class TextEdit { } // 显示文本编辑框 - show(node) { + async show(node) { + if (typeof this.mindMap.opt.beforeTextEdit === 'function') { + let isShow = false + try { + isShow = await this.mindMap.opt.beforeTextEdit(node) + } catch (error) { + isShow = false + } + if (!isShow) return + } this.currentNode = node let { offsetLeft, offsetTop } = checkNodeOuter(this.mindMap, node) this.mindMap.view.translateXY(offsetLeft, offsetTop) diff --git a/simple-mind-map/src/Node.js b/simple-mind-map/src/core/render/node/Node.js similarity index 97% rename from simple-mind-map/src/Node.js rename to simple-mind-map/src/core/render/node/Node.js index 789c00d5..3d2bab6f 100644 --- a/simple-mind-map/src/Node.js +++ b/simple-mind-map/src/core/render/node/Node.js @@ -1,12 +1,12 @@ import Style from './Style' import Shape from './Shape' -import { asyncRun } from './utils' +import { asyncRun } from '../../../utils' import { G, Rect } from '@svgdotjs/svg.js' -import nodeGeneralizationMethods from './utils/nodeGeneralization' -import nodeExpandBtnMethods from './utils/nodeExpandBtn' -import nodeCommandWrapsMethods from './utils/nodeCommandWraps' -import nodeCreateContentsMethods from './utils/nodeCreateContents' -import { CONSTANTS } from './utils/constant' +import nodeGeneralizationMethods from './nodeGeneralization' +import nodeExpandBtnMethods from './nodeExpandBtn' +import nodeCommandWrapsMethods from './nodeCommandWraps' +import nodeCreateContentsMethods from './nodeCreateContents' +import { CONSTANTS } from '../../../constants/constant' // 节点类 class Node { @@ -343,12 +343,12 @@ class Node { bindGroupEvent() { // 单击事件,选中节点 this.group.on('click', e => { + this.mindMap.emit('node_click', this, e) if (this.isMultipleChoice) { e.stopPropagation() this.isMultipleChoice = false return } - this.mindMap.emit('node_click', this, e) this.active(e) }) this.group.on('mousedown', e => { @@ -359,7 +359,7 @@ class Node { e.stopPropagation() } // 多选和取消多选 - if (e.ctrlKey) { + if (e.ctrlKey && this.mindMap.opt.enableCtrlKeyNodeSelection) { this.isMultipleChoice = true let isActive = this.nodeData.data.isActive if (!isActive) @@ -798,6 +798,11 @@ class Node { getData(key) { return key ? this.nodeData.data[key] || '' : this.nodeData.data } + + // 是否存在自定义样式 + hasCustomStyle() { + return this.style.hasCustomStyle() + } } export default Node diff --git a/simple-mind-map/src/Shape.js b/simple-mind-map/src/core/render/node/Shape.js similarity index 99% rename from simple-mind-map/src/Shape.js rename to simple-mind-map/src/core/render/node/Shape.js index b0df207b..d53d8881 100644 --- a/simple-mind-map/src/Shape.js +++ b/simple-mind-map/src/core/render/node/Shape.js @@ -1,5 +1,5 @@ import { Rect, Polygon, Path } from '@svgdotjs/svg.js' -import { CONSTANTS } from './utils/constant' +import { CONSTANTS } from '../../../constants/constant' // 节点形状类 export default class Shape { diff --git a/simple-mind-map/src/Style.js b/simple-mind-map/src/core/render/node/Style.js similarity index 83% rename from simple-mind-map/src/Style.js rename to simple-mind-map/src/core/render/node/Style.js index 6f10526e..99e7def9 100644 --- a/simple-mind-map/src/Style.js +++ b/simple-mind-map/src/core/render/node/Style.js @@ -1,10 +1,20 @@ -import { tagColorList } from './utils/constant' +import { tagColorList, nodeDataNoStylePropList } from '../../../constants/constant' const rootProp = ['paddingX', 'paddingY'] +const backgroundStyleProps = ['backgroundColor', 'backgroundImage', 'backgroundRepeat', 'backgroundPosition', 'backgroundSize'] // 样式类 class Style { // 设置背景样式 static setBackgroundStyle(el, themeConfig) { + // 缓存容器元素原本的样式 + if (!Style.cacheStyle) { + Style.cacheStyle = {} + let style = window.getComputedStyle(el) + backgroundStyleProps.forEach((prop) => { + Style.cacheStyle[prop] = style[prop] + }) + } + // 设置新样式 let { backgroundColor, backgroundImage, backgroundRepeat, backgroundPosition, backgroundSize } = themeConfig el.style.backgroundColor = backgroundColor if (backgroundImage) { @@ -17,6 +27,15 @@ class Style { } } + // 移除背景样式 + static removeBackgroundStyle(el) { + if (!Style.cacheStyle) return + backgroundStyleProps.forEach((prop) => { + el.style[prop] = Style.cacheStyle[prop] + }) + Style.cacheStyle = null + } + // 构造函数 constructor(ctx) { this.ctx = ctx @@ -190,6 +209,19 @@ class Style { node2.fill({ color: color }) fillNode.fill({ color: fill }) } + + // 是否设置了自定义的样式 + hasCustomStyle() { + let res = false + Object.keys(this.ctx.nodeData.data).forEach((item) => { + if (!nodeDataNoStylePropList.includes(item)) { + res = true + } + }) + return res + } } +Style.cacheStyle = null + export default Style diff --git a/simple-mind-map/src/utils/nodeCommandWraps.js b/simple-mind-map/src/core/render/node/nodeCommandWraps.js similarity index 100% rename from simple-mind-map/src/utils/nodeCommandWraps.js rename to simple-mind-map/src/core/render/node/nodeCommandWraps.js diff --git a/simple-mind-map/src/utils/nodeCreateContents.js b/simple-mind-map/src/core/render/node/nodeCreateContents.js similarity index 94% rename from simple-mind-map/src/utils/nodeCreateContents.js rename to simple-mind-map/src/core/render/node/nodeCreateContents.js index 866a4db3..e175455f 100644 --- a/simple-mind-map/src/utils/nodeCreateContents.js +++ b/simple-mind-map/src/core/render/node/nodeCreateContents.js @@ -1,7 +1,7 @@ -import { measureText, resizeImgSize, getTextFromHtml } from '../utils' +import { measureText, resizeImgSize, getTextFromHtml } from '../../../utils' import { Image, SVG, A, G, Rect, Text, ForeignObject } from '@svgdotjs/svg.js' -import iconsSvg from '../svg/icons' -import { CONSTANTS } from './constant' +import iconsSvg from '../../../svg/icons' +import { CONSTANTS } from '../../../constants/constant' // 创建图片节点 function createImgNode() { @@ -64,8 +64,18 @@ function createIconNode() { function createRichTextNode() { let g = new G() // 重新设置富文本节点内容 - if (this.nodeData.data.resetRichText || [CONSTANTS.CHANGE_THEME].includes(this.mindMap.renderer.renderSource)) { + let recoverText = false + if (this.nodeData.data.resetRichText) { delete this.nodeData.data.resetRichText + recoverText = true + } + if ([CONSTANTS.CHANGE_THEME].includes(this.mindMap.renderer.renderSource)) { + // 如果自定义过样式则不允许覆盖 + if (!this.hasCustomStyle()) { + recoverText = true + } + } + if (recoverText) { let text = getTextFromHtml(this.nodeData.data.text) this.nodeData.data.text = `

${text}

` } diff --git a/simple-mind-map/src/utils/nodeExpandBtn.js b/simple-mind-map/src/core/render/node/nodeExpandBtn.js similarity index 98% rename from simple-mind-map/src/utils/nodeExpandBtn.js rename to simple-mind-map/src/core/render/node/nodeExpandBtn.js index 650417b5..5b2675cd 100644 --- a/simple-mind-map/src/utils/nodeExpandBtn.js +++ b/simple-mind-map/src/core/render/node/nodeExpandBtn.js @@ -1,4 +1,4 @@ -import btnsSvg from '../svg/btns' +import btnsSvg from '../../../svg/btns' import { SVG, Circle, G } from '@svgdotjs/svg.js' // 创建展开收起按钮的内容节点 diff --git a/simple-mind-map/src/utils/nodeGeneralization.js b/simple-mind-map/src/core/render/node/nodeGeneralization.js similarity index 99% rename from simple-mind-map/src/utils/nodeGeneralization.js rename to simple-mind-map/src/core/render/node/nodeGeneralization.js index 6521de97..2a2a585d 100644 --- a/simple-mind-map/src/utils/nodeGeneralization.js +++ b/simple-mind-map/src/core/render/node/nodeGeneralization.js @@ -1,4 +1,4 @@ -import Node from '../Node' +import Node from './Node' // 检查是否存在概要 function checkHasGeneralization () { diff --git a/simple-mind-map/src/View.js b/simple-mind-map/src/core/view/View.js similarity index 65% rename from simple-mind-map/src/View.js rename to simple-mind-map/src/core/view/View.js index ffe2599f..98df7ee0 100644 --- a/simple-mind-map/src/View.js +++ b/simple-mind-map/src/core/view/View.js @@ -1,4 +1,4 @@ -import { CONSTANTS } from './utils/constant' +import { CONSTANTS } from '../../constants/constant' // 视图操作类 class View { @@ -28,6 +28,9 @@ class View { this.mindMap.keyCommand.addShortcut('Control+Enter', () => { this.reset() }) + this.mindMap.keyCommand.addShortcut('Control+i', () => { + this.fit() + }) this.mindMap.svg.on('dblclick', () => { this.reset() }) @@ -56,11 +59,16 @@ class View { this.firstDrag = true }) // 放大缩小视图 - this.mindMap.event.on('mousewheel', (e, dir) => { - if (this.mindMap.opt.customHandleMousewheel && typeof this.mindMap.opt.customHandleMousewheel === 'function') { + this.mindMap.event.on('mousewheel', (e, dir, event, isTouchPad) => { + if ( + this.mindMap.opt.customHandleMousewheel && + typeof this.mindMap.opt.customHandleMousewheel === 'function' + ) { return this.mindMap.opt.customHandleMousewheel(e) } - if (this.mindMap.opt.mousewheelAction === CONSTANTS.MOUSE_WHEEL_ACTION.ZOOM) { + if ( + this.mindMap.opt.mousewheelAction === CONSTANTS.MOUSE_WHEEL_ACTION.ZOOM + ) { switch (dir) { // 鼠标滚轮,向上和向左,都是缩小 case CONSTANTS.DIR.UP: @@ -74,22 +82,26 @@ class View { break } } else { - switch (dir){ + let step = this.mindMap.opt.mousewheelMoveStep + if (isTouchPad) { + step = 5 + } + switch (dir) { // 上移 case CONSTANTS.DIR.DOWN: - this.translateY(-this.mindMap.opt.mousewheelMoveStep) + this.translateY(-step) break // 下移 case CONSTANTS.DIR.UP: - this.translateY(this.mindMap.opt.mousewheelMoveStep) + this.translateY(step) break // 右移 case CONSTANTS.DIR.LEFT: - this.translateX(-this.mindMap.opt.mousewheelMoveStep) + this.translateX(-step) break // 左移 case CONSTANTS.DIR.RIGHT: - this.translateX(this.mindMap.opt.mousewheelMoveStep) + this.translateX(step) break } } @@ -201,6 +213,56 @@ class View { this.transform() this.mindMap.emit('scale', this.scale) } + + // 适应画布大小 + fit() { + let { fitPadding } = this.mindMap.opt + let draw = this.mindMap.draw + let origTransform = draw.transform() + let rect = draw.rbox() + let drawWidth = rect.width / origTransform.scaleX + let drawHeight = rect.height / origTransform.scaleY + let drawRatio = drawWidth / drawHeight + let { width: elWidth, height: elHeight } = + this.mindMap.el.getBoundingClientRect() + elWidth = elWidth - fitPadding * 2 + elHeight = elHeight - fitPadding * 2 + let elRatio = elWidth / elHeight + let newScale = 0 + let flag = '' + if (drawWidth <= elWidth && drawHeight <= elHeight) { + newScale = 1 + flag = 1 + } else { + let newWidth = 0 + let newHeight = 0 + if (drawRatio > elRatio) { + newWidth = elWidth + newHeight = elWidth / drawRatio + flag = 2 + } else { + newHeight = elHeight + newWidth = elHeight * drawRatio + flag = 3 + } + newScale = newWidth / drawWidth + } + this.setScale(newScale) + let newRect = draw.rbox() + let newX = 0 + let newY = 0 + if (flag === 1) { + newX = -newRect.x + fitPadding + (elWidth - newRect.width) / 2 + newY = -newRect.y + fitPadding + (elHeight - newRect.height) / 2 + } else if (flag === 2) { + newX = -newRect.x + fitPadding + newY = -newRect.y + fitPadding + (elHeight - newRect.height) / 2 + } else if (flag === 3) { + newX = -newRect.x + fitPadding + (elWidth - newRect.width) / 2 + newY = -newRect.y + fitPadding + } + this.translateXY(newX, newY) + } } export default View diff --git a/simple-mind-map/src/layouts/Base.js b/simple-mind-map/src/layouts/Base.js index e51b72d5..701fffbf 100644 --- a/simple-mind-map/src/layouts/Base.js +++ b/simple-mind-map/src/layouts/Base.js @@ -1,5 +1,5 @@ -import Node from '../Node' -import { CONSTANTS, initRootNodePositionMap } from '../utils/constant' +import Node from '../core/render/node/Node' +import { CONSTANTS, initRootNodePositionMap } from '../constants/constant' import Lru from '../utils/Lru' // 布局基类 diff --git a/simple-mind-map/src/layouts/Fishbone.js b/simple-mind-map/src/layouts/Fishbone.js index 58e70932..e8581852 100644 --- a/simple-mind-map/src/layouts/Fishbone.js +++ b/simple-mind-map/src/layouts/Fishbone.js @@ -1,6 +1,6 @@ import Base from './Base' import { walk, asyncRun, degToRad } from '../utils' -import { CONSTANTS } from '../utils/constant' +import { CONSTANTS } from '../constants/constant' import utils from './fishboneUtils' // 鱼骨图 diff --git a/simple-mind-map/src/layouts/Timeline.js b/simple-mind-map/src/layouts/Timeline.js index 0e426cf6..60a41db2 100644 --- a/simple-mind-map/src/layouts/Timeline.js +++ b/simple-mind-map/src/layouts/Timeline.js @@ -1,6 +1,6 @@ import Base from './Base' import { walk, asyncRun } from '../utils' -import { CONSTANTS } from '../utils/constant' +import { CONSTANTS } from '../constants/constant' // 时间轴 class Timeline extends Base { diff --git a/simple-mind-map/src/AssociativeLine.js b/simple-mind-map/src/plugins/AssociativeLine.js similarity index 96% rename from simple-mind-map/src/AssociativeLine.js rename to simple-mind-map/src/plugins/AssociativeLine.js index c365a8de..28223265 100644 --- a/simple-mind-map/src/AssociativeLine.js +++ b/simple-mind-map/src/plugins/AssociativeLine.js @@ -1,4 +1,4 @@ -import { walk, bfsWalk, throttle } from './utils/' +import { walk, bfsWalk, throttle } from '../utils' import { v4 as uuid } from 'uuid' import { getAssociativeLineTargetIndex, @@ -7,9 +7,9 @@ import { getNodePoint, computeNodePoints, getNodeLinePath -} from './utils/associativeLineUtils' -import associativeLineControlsMethods from './utils/associativeLineControls' -import associativeLineTextMethods from './utils/associativeLineText' +} from './associativeLine/associativeLineUtils' +import associativeLineControlsMethods from './associativeLine/associativeLineControls' +import associativeLineTextMethods from './associativeLine/associativeLineText' // 关联线类 class AssociativeLine { @@ -91,12 +91,7 @@ class AssociativeLine { this.mindMap.on('node_dragging', this.onNodeDragging.bind(this)) this.mindMap.on('node_dragend', this.onNodeDragend.bind(this)) // 拖拽控制点 - window.addEventListener('mousemove', e => { - this.onControlPointMousemove(e) - }) - window.addEventListener('mouseup', e => { - this.onControlPointMouseup(e) - }) + this.mindMap.on('mouseup', this.onControlPointMouseup.bind(this)) // 缩放事件 this.mindMap.on('scale', this.onScale) } @@ -266,12 +261,13 @@ class AssociativeLine { // 鼠标移动事件 onMousemove(e) { - if (!this.isCreatingLine) return + this.onControlPointMousemove(e) this.updateCreatingLine(e) } // 更新创建过程中的连接线 updateCreatingLine(e) { + if (!this.isCreatingLine) return let { x, y } = this.getTransformedEventPos(e) let startPoint = getNodePoint(this.creatingStartNode) let offsetX = x > startPoint.x ? -10 : 10 diff --git a/simple-mind-map/src/Drag.js b/simple-mind-map/src/plugins/Drag.js similarity index 99% rename from simple-mind-map/src/Drag.js rename to simple-mind-map/src/plugins/Drag.js index ffadf0c5..d85ea667 100644 --- a/simple-mind-map/src/Drag.js +++ b/simple-mind-map/src/plugins/Drag.js @@ -1,5 +1,5 @@ -import { bfsWalk, throttle } from './utils' -import Base from './layouts/Base' +import { bfsWalk, throttle } from '../utils' +import Base from '../layouts/Base' // 节点拖动类 diff --git a/simple-mind-map/src/Export.js b/simple-mind-map/src/plugins/Export.js similarity index 84% rename from simple-mind-map/src/Export.js rename to simple-mind-map/src/plugins/Export.js index cbf3a639..5186ffe8 100644 --- a/simple-mind-map/src/Export.js +++ b/simple-mind-map/src/plugins/Export.js @@ -1,9 +1,7 @@ -import { imgToDataUrl, downloadFile, readBlob } from './utils' -import JsPDF from 'jspdf' +import { imgToDataUrl, downloadFile, readBlob } from '../utils' import { SVG } from '@svgdotjs/svg.js' -import drawBackgroundImageToCanvas from './utils/simulateCSSBackgroundInCanvas' -import { transformToMarkdown } from './parse/toMarkdown' -const URL = window.URL || window.webkitURL || window +import drawBackgroundImageToCanvas from '../utils/simulateCSSBackgroundInCanvas' +import { transformToMarkdown } from '../parse/toMarkdown' // 导出类 class Export { @@ -175,34 +173,11 @@ class Export { // 导出为pdf async pdf(name) { - let img = await this.png() - let pdf = new JsPDF('', 'pt', 'a4') - let a4Width = 595 - let a4Height = 841 - let a4Ratio = a4Width / a4Height - let image = new Image() - image.onload = () => { - let imageWidth = image.width - let imageHeight = image.height - let imageRatio = imageWidth / imageHeight - let w, h - if (imageWidth <= a4Width && imageHeight <= a4Height) { - // 使用图片原始宽高 - w = imageWidth - h = imageHeight - } else if (a4Ratio > imageRatio) { - // 以a4Height为高度,缩放图片宽度 - w = imageRatio * a4Height - h = a4Height - } else { - // 以a4Width为宽度,缩放图片高度 - w = a4Width - h = a4Width / imageRatio - } - pdf.addImage(img, 'PNG', (a4Width - w) / 2, (a4Height - h) / 2, w, h) - pdf.save(name) + if (!this.mindMap.doExportPDF) { + throw new Error('请注册ExportPDF插件') } - image.src = img + let img = await this.png() + this.mindMap.doExportPDF.pdf(name, img) } // 导出为svg diff --git a/simple-mind-map/src/plugins/ExportPDF.js b/simple-mind-map/src/plugins/ExportPDF.js new file mode 100644 index 00000000..2fcc254d --- /dev/null +++ b/simple-mind-map/src/plugins/ExportPDF.js @@ -0,0 +1,44 @@ +import JsPDF from 'jspdf' + +// 导出PDF类,需要通过Export插件使用 +class ExportPDF { + // 构造函数 + constructor(opt) { + this.mindMap = opt.mindMap + } + + // 导出为pdf + pdf(name, img) { + let pdf = new JsPDF('', 'pt', 'a4') + let a4Width = 595 + let a4Height = 841 + let a4Ratio = a4Width / a4Height + let image = new Image() + image.onload = () => { + let imageWidth = image.width + let imageHeight = image.height + let imageRatio = imageWidth / imageHeight + let w, h + if (imageWidth <= a4Width && imageHeight <= a4Height) { + // 使用图片原始宽高 + w = imageWidth + h = imageHeight + } else if (a4Ratio > imageRatio) { + // 以a4Height为高度,缩放图片宽度 + w = imageRatio * a4Height + h = a4Height + } else { + // 以a4Width为宽度,缩放图片高度 + w = a4Width + h = a4Width / imageRatio + } + pdf.addImage(img, 'PNG', (a4Width - w) / 2, (a4Height - h) / 2, w, h) + pdf.save(name) + } + image.src = img + } +} + +ExportPDF.instanceName = 'doExportPDF' + +export default ExportPDF diff --git a/simple-mind-map/src/KeyboardNavigation.js b/simple-mind-map/src/plugins/KeyboardNavigation.js similarity index 98% rename from simple-mind-map/src/KeyboardNavigation.js rename to simple-mind-map/src/plugins/KeyboardNavigation.js index c5adf041..cdbf95f2 100644 --- a/simple-mind-map/src/KeyboardNavigation.js +++ b/simple-mind-map/src/plugins/KeyboardNavigation.js @@ -1,5 +1,5 @@ -import { bfsWalk } from './utils' -import { CONSTANTS } from './utils/constant' +import { bfsWalk } from '../utils' +import { CONSTANTS } from '../constants/constant' // 键盘导航类 class KeyboardNavigation { diff --git a/simple-mind-map/src/MiniMap.js b/simple-mind-map/src/plugins/MiniMap.js similarity index 100% rename from simple-mind-map/src/MiniMap.js rename to simple-mind-map/src/plugins/MiniMap.js diff --git a/simple-mind-map/src/RichText.js b/simple-mind-map/src/plugins/RichText.js similarity index 82% rename from simple-mind-map/src/RichText.js rename to simple-mind-map/src/plugins/RichText.js index 227f701e..47cc9ecd 100644 --- a/simple-mind-map/src/RichText.js +++ b/simple-mind-map/src/plugins/RichText.js @@ -1,8 +1,8 @@ import Quill from 'quill' import 'quill/dist/quill.snow.css' import html2canvas from 'html2canvas' -import { walk, getTextFromHtml } from './utils' -import { CONSTANTS } from './utils/constant' +import { walk, getTextFromHtml } from '../utils' +import { CONSTANTS } from '../constants/constant' let extended = false @@ -41,9 +41,12 @@ class RichText { this.node = null this.styleEl = null this.cacheEditingText = '' + this.lostStyle = false + this.isCompositing = false this.initOpt() this.extendQuill() this.appendCss() + this.bindEvent() // 处理数据,转成富文本格式 if (this.mindMap.opt.data) { @@ -51,6 +54,20 @@ class RichText { } } + // 绑定事件 + bindEvent() { + this.onCompositionStart = this.onCompositionStart.bind(this) + this.onCompositionEnd = this.onCompositionEnd.bind(this) + window.addEventListener('compositionstart', this.onCompositionStart) + window.addEventListener('compositionend', this.onCompositionEnd) + } + + // 解绑事件 + unbindEvent() { + window.removeEventListener('compositionstart', this.onCompositionStart) + window.removeEventListener('compositionend', this.onCompositionEnd) + } + // 插入样式 appendCss() { let cssText = ` @@ -59,6 +76,7 @@ class RichText { padding: 0; height: auto; line-height: normal; + -webkit-user-select: text; } .ql-container { @@ -159,13 +177,15 @@ class RichText { this.textEditNode.style.marginLeft = `-${paddingX * scaleX}px` this.textEditNode.style.marginTop = `-${paddingY * scaleY}px` this.textEditNode.style.zIndex = this.mindMap.opt.nodeTextEditZIndex - this.textEditNode.style.backgroundColor = bgColor === 'transparent' ? '#fff' : bgColor + this.textEditNode.style.backgroundColor = + bgColor === 'transparent' ? '#fff' : bgColor this.textEditNode.style.minWidth = originWidth + paddingX * 2 + 'px' this.textEditNode.style.minHeight = originHeight + 'px' this.textEditNode.style.left = rect.left + 'px' this.textEditNode.style.top = rect.top + 'px' this.textEditNode.style.display = 'block' - this.textEditNode.style.maxWidth = this.mindMap.opt.textAutoWrapWidth + paddingX * 2 + 'px' + this.textEditNode.style.maxWidth = + this.mindMap.opt.textAutoWrapWidth + paddingX * 2 + 'px' this.textEditNode.style.transform = `scale(${scaleX}, ${scaleY})` this.textEditNode.style.transformOrigin = 'left top' if (!node.nodeData.data.richText) { @@ -174,7 +194,8 @@ class RichText { let html = `

${text}

` this.textEditNode.innerHTML = this.cacheEditingText || html } else { - this.textEditNode.innerHTML = this.cacheEditingText || node.nodeData.data.text + this.textEditNode.innerHTML = + this.cacheEditingText || node.nodeData.data.text } this.initQuillEditor() document.querySelector('.ql-editor').style.minHeight = originHeight + 'px' @@ -198,7 +219,7 @@ class RichText { underline: node.style.merge('textDecoration') === 'underline', strike: node.style.merge('textDecoration') === 'line-through' } - this.formatAllText(style) + this.pureFormatAllText(style) } // 获取当前正在编辑的内容 @@ -214,7 +235,8 @@ class RichText { return } let html = this.getEditText() - let list = nodes && nodes.length > 0 ? nodes : this.mindMap.renderer.activeNodeList + let list = + nodes && nodes.length > 0 ? nodes : this.mindMap.renderer.activeNodeList list.forEach(node => { this.mindMap.execCommand('SET_NODE_TEXT', node, html, true) if (node.isGeneralization) { @@ -223,11 +245,7 @@ class RichText { } this.mindMap.render() }) - this.mindMap.emit( - 'hide_text_edit', - this.textEditNode, - list - ) + this.mindMap.emit('hide_text_edit', this.textEditNode, list) this.textEditNode.style.display = 'none' this.showTextEdit = false this.mindMap.emit('rich_text_selection_change', false) @@ -281,6 +299,37 @@ class RichText { ) } }) + this.quill.on('text-change', () => { + let contents = this.quill.getContents() + let len = contents.ops.length + // 如果编辑过程中删除所有字符,那么会丢失主题的样式 + if (len <= 0 || (len === 1 && contents.ops[0].insert === '\n')) { + this.lostStyle = true + // 需要删除节点的样式数据 + this.syncFormatToNodeConfig(null, true) + } else if (this.lostStyle && !this.isCompositing) { + // 如果处于样式丢失状态,那么需要进行格式化加回样式 + this.setTextStyleIfNotRichText(this.node) + this.lostStyle = false + } + }) + } + + // 正则输入中文 + onCompositionStart() { + if (!this.showTextEdit) { + return + } + this.isCompositing = true + } + + // 中文输入结束 + onCompositionEnd() { + if (!this.showTextEdit || !this.lostStyle) { + return + } + this.isCompositing = false + this.setTextStyleIfNotRichText(this.node) } // 选中全部 @@ -300,7 +349,9 @@ class RichText { this.syncFormatToNodeConfig(config, clear) let rangeLost = !this.range let range = rangeLost ? this.lastRange : this.range - clear ? this.quill.removeFormat(range.index, range.length) : this.quill.formatText(range.index, range.length, config) + clear + ? this.quill.removeFormat(range.index, range.length) + : this.quill.formatText(range.index, range.length, config) if (rangeLost) { this.quill.setSelection(this.lastRange.index, this.lastRange.length) } @@ -321,6 +372,11 @@ class RichText { // 格式化所有文本 formatAllText(config = {}) { this.syncFormatToNodeConfig(config) + this.pureFormatAllText(config) + } + + // 纯粹的格式化所有文本 + pureFormatAllText(config = {}) { this.quill.formatText(0, this.quill.getLength(), config) } @@ -329,7 +385,14 @@ class RichText { if (!this.node) return if (clear) { // 清除文本样式 - ['fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'textDecoration', 'color'].forEach((prop) => { + ;[ + 'fontFamily', + 'fontSize', + 'fontWeight', + 'fontStyle', + 'textDecoration', + 'color' + ].forEach(prop => { delete this.node.nodeData.data[prop] }) } else { @@ -412,11 +475,11 @@ class RichText { el.appendChild(node) this.mindMap.el.appendChild(el) // 遍历所有节点,将它们的margin和padding设为0 - let walk = (root) => { + let walk = root => { root.style.margin = 0 root.style.padding = 0 if (root.hasChildNodes()) { - Array.from(root.children).forEach((item) => { + Array.from(root.children).forEach(item => { walk(item) }) } @@ -454,13 +517,13 @@ class RichText { // 处理导入数据 handleSetData(data) { - let walk = (root) => { + let walk = root => { if (!root.data.richText) { root.data.richText = true root.data.resetRichText = true } if (root.children && root.children.length > 0) { - Array.from(root.children).forEach((item) => { + Array.from(root.children).forEach(item => { walk(item) }) } diff --git a/simple-mind-map/src/Select.js b/simple-mind-map/src/plugins/Select.js similarity index 83% rename from simple-mind-map/src/Select.js rename to simple-mind-map/src/plugins/Select.js index a8c847c9..b2a58c14 100644 --- a/simple-mind-map/src/Select.js +++ b/simple-mind-map/src/plugins/Select.js @@ -1,4 +1,4 @@ -import { bfsWalk, throttle } from './utils' +import { bfsWalk, throttle } from '../utils' // 选择节点类 @@ -22,9 +22,14 @@ class Select { if (this.mindMap.opt.readonly) { return } - if (!e.ctrlKey && e.which !== 3) { + let { useLeftKeySelectionRightKeyDrag } = this.mindMap.opt + if ( + !e.ctrlKey && + (useLeftKeySelectionRightKeyDrag ? e.which !== 1 : e.which !== 3) + ) { return } + e.preventDefault() this.isMousedown = true let { x, y } = this.mindMap.toPos(e.clientX, e.clientY) this.mouseDownX = x @@ -146,25 +151,24 @@ class Select { let bottom = (top + height) * scaleY + translateY left = left * scaleX + translateX top = top * scaleY + translateY - if ((left >= minx && left <= maxx || - right >= minx && right <= maxx) && - (top >= miny && top <= maxy || - bottom >= miny && bottom <= maxy) - ) { + if ( + ((left >= minx && left <= maxx) || (right >= minx && right <= maxx)) && + ((top >= miny && top <= maxy) || (bottom >= miny && bottom <= maxy)) + ) { // this.mindMap.batchExecution.push('activeNode' + node.uid, () => { - if (node.nodeData.data.isActive) { - return - } - this.mindMap.renderer.setNodeActive(node, true) - this.mindMap.renderer.addActiveNode(node) + if (node.nodeData.data.isActive) { + return + } + this.mindMap.renderer.setNodeActive(node, true) + this.mindMap.renderer.addActiveNode(node) // }) } else if (node.nodeData.data.isActive) { // this.mindMap.batchExecution.push('activeNode' + node.uid, () => { - if (!node.nodeData.data.isActive) { - return - } - this.mindMap.renderer.setNodeActive(node, false) - this.mindMap.renderer.removeActiveNode(node) + if (!node.nodeData.data.isActive) { + return + } + this.mindMap.renderer.setNodeActive(node, false) + this.mindMap.renderer.removeActiveNode(node) // }) } }) diff --git a/simple-mind-map/src/plugins/TouchEvent.js b/simple-mind-map/src/plugins/TouchEvent.js new file mode 100644 index 00000000..135d6ece --- /dev/null +++ b/simple-mind-map/src/plugins/TouchEvent.js @@ -0,0 +1,122 @@ +// 手势事件支持类 + +class TouchEvent { + // 构造函数 + constructor({ mindMap }) { + this.mindMap = mindMap + this.touchesNum = 0 + this.singleTouchstartEvent = null + this.clickNum = 0 + this.doubleTouchmoveDistance = 0 + this.bindEvent() + } + + // 绑定事件 + bindEvent() { + this.onTouchstart = this.onTouchstart.bind(this) + this.onTouchmove = this.onTouchmove.bind(this) + this.onTouchcancel = this.onTouchcancel.bind(this) + this.onTouchend = this.onTouchend.bind(this) + window.addEventListener('touchstart', this.onTouchstart) + window.addEventListener('touchmove', this.onTouchmove) + window.addEventListener('touchcancel', this.onTouchcancel) + window.addEventListener('touchend', this.onTouchend) + } + + // 解绑事件 + unBindEvent() { + window.removeEventListener('touchstart', this.onTouchstart) + window.removeEventListener('touchmove', this.onTouchmove) + window.removeEventListener('touchcancel', this.onTouchcancel) + window.removeEventListener('touchend', this.onTouchend) + } + + // 手指按下事件 + onTouchstart(e) { + this.touchesNum = e.touches.length + if (this.touchesNum === 1) { + let touch = e.touches[0] + this.singleTouchstartEvent = touch + this.dispatchMouseEvent('mousedown', touch.target, touch) + } + } + + // 手指移动事件 + onTouchmove(e) { + let len = e.touches.length + if (len === 1) { + let touch = e.touches[0] + this.dispatchMouseEvent('mousemove', touch.target, touch) + } else if (len === 2) { + let touch1 = e.touches[0] + let touch2 = e.touches[1] + let distance = Math.sqrt( + Math.pow(touch1.clientX - touch2.clientX, 2) + + Math.pow(touch1.clientY - touch2.clientY, 2) + ) + if (distance > this.doubleTouchmoveDistance) { + // 放大 + this.mindMap.view.enlarge() + } else { + // 缩小 + this.mindMap.view.narrow() + } + this.doubleTouchmoveDistance = distance + } + } + + // 手指取消事件 + onTouchcancel(e) {} + + // 手指松开事件 + onTouchend(e) { + this.dispatchMouseEvent('mouseup', e.target) + if (this.touchesNum === 1) { + // 模拟双击事件 + this.clickNum++ + setTimeout(() => { + this.clickNum = 0 + }, 300) + let ev = this.singleTouchstartEvent + if (this.clickNum > 1) { + this.clickNum = 0 + this.dispatchMouseEvent('dblclick', ev.target, ev) + } else { + this.dispatchMouseEvent('click', ev.target, ev) + } + } + this.touchesNum = 0 + this.singleTouchstartEvent = null + this.doubleTouchmoveDistance = 0 + } + + // 发送鼠标事件 + dispatchMouseEvent(eventName, target, e) { + let opt = {} + if (e) { + opt = { + screenX: e.screenX, + screenY: e.screenY, + clientX: e.clientX, + clientY: e.clientY, + which: 1 + } + } + let event = new MouseEvent(eventName, { + view: window, + bubbles: true, + cancelable: true, + ...opt + }) + target.dispatchEvent(event) + } + + // 插件被移除前做的事情 + beforePluginRemove() { + this.unBindEvent() + } +} + +TouchEvent.instanceName = 'touchEvent' + +export default TouchEvent diff --git a/simple-mind-map/src/Watermark.js b/simple-mind-map/src/plugins/Watermark.js similarity index 98% rename from simple-mind-map/src/Watermark.js rename to simple-mind-map/src/plugins/Watermark.js index 83bec10d..7d2ddaca 100644 --- a/simple-mind-map/src/Watermark.js +++ b/simple-mind-map/src/plugins/Watermark.js @@ -1,5 +1,5 @@ import { Text, G } from '@svgdotjs/svg.js' -import { degToRad, camelCaseToHyphen } from './utils' +import { degToRad, camelCaseToHyphen } from '../utils' import merge from 'deepmerge' // 水印类 diff --git a/simple-mind-map/src/utils/associativeLineControls.js b/simple-mind-map/src/plugins/associativeLine/associativeLineControls.js similarity index 100% rename from simple-mind-map/src/utils/associativeLineControls.js rename to simple-mind-map/src/plugins/associativeLine/associativeLineControls.js diff --git a/simple-mind-map/src/utils/associativeLineText.js b/simple-mind-map/src/plugins/associativeLine/associativeLineText.js similarity index 98% rename from simple-mind-map/src/utils/associativeLineText.js rename to simple-mind-map/src/plugins/associativeLine/associativeLineText.js index f761ab13..9d0722bb 100644 --- a/simple-mind-map/src/utils/associativeLineText.js +++ b/simple-mind-map/src/plugins/associativeLine/associativeLineText.js @@ -1,5 +1,5 @@ import { Text } from '@svgdotjs/svg.js' -import { getStrWithBrFromHtml } from './index' +import { getStrWithBrFromHtml } from '../../utils/index' // 创建文字节点 function createText(data) { diff --git a/simple-mind-map/src/utils/associativeLineUtils.js b/simple-mind-map/src/plugins/associativeLine/associativeLineUtils.js similarity index 100% rename from simple-mind-map/src/utils/associativeLineUtils.js rename to simple-mind-map/src/plugins/associativeLine/associativeLineUtils.js diff --git a/simple-mind-map/src/BatchExecution.js b/simple-mind-map/src/utils/BatchExecution.js similarity index 94% rename from simple-mind-map/src/BatchExecution.js rename to simple-mind-map/src/utils/BatchExecution.js index 4a92fbdc..fcdfb735 100644 --- a/simple-mind-map/src/BatchExecution.js +++ b/simple-mind-map/src/utils/BatchExecution.js @@ -1,4 +1,4 @@ -import { nextTick } from './utils' +import { nextTick } from '.' // 批量执行 class BatchExecution { diff --git a/web/package-lock.json b/web/package-lock.json index d5ed6629..763e71fb 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -40,6 +40,7 @@ "markdown-it": "^13.0.1", "markdown-it-checkbox": "^1.1.0", "prettier": "^1.19.1", + "vconsole": "^3.15.1", "vue-cli-plugin-electron-builder": "~2.1.1", "vue-template-compiler": "^2.6.11", "webpack": "^4.44.2" @@ -2018,9 +2019,9 @@ } }, "node_modules/@npmcli/fs/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -2248,9 +2249,9 @@ } }, "node_modules/@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", + "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", "dev": true, "dependencies": { "@types/ms": "*" @@ -3494,9 +3495,9 @@ } }, "node_modules/app-builder-lib/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -4847,9 +4848,9 @@ } }, "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, "dependencies": { "clone-response": "^1.0.2", @@ -5690,6 +5691,18 @@ "node": ">=8" } }, + "node_modules/configstore/node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, "node_modules/connect-history-api-fallback": { "version": "1.6.0", "dev": true, @@ -5806,6 +5819,17 @@ "node": ">=0.10.0" } }, + "node_modules/copy-text-to-clipboard": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/copy-webpack-plugin": { "version": "5.1.2", "dev": true, @@ -7157,9 +7181,9 @@ } }, "node_modules/electron": { - "version": "23.3.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-23.3.1.tgz", - "integrity": "sha512-N+xGMPwK733BU6xn1qs2t/AE3wKEqhWYLvPqWEu6TRC8yQvf7PNNjtgBTPZ9R0GhtrRgu6kUTX3HSV3UG9r/Dw==", + "version": "23.3.7", + "resolved": "https://registry.npmjs.org/electron/-/electron-23.3.7.tgz", + "integrity": "sha512-irr5yfZQP6dLjIbti+2n82tfBafHC3Ejw+B0EKVY/mSjpgTZ0fNZmfjaRjBl53Y5Mz98++CaeeNJlamcIlP9/w==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -7440,9 +7464,9 @@ } }, "node_modules/electron-devtools-installer/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -7455,9 +7479,9 @@ } }, "node_modules/electron-devtools-installer/node_modules/tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", "dev": true }, "node_modules/electron-devtools-installer/node_modules/yallist": { @@ -7479,16 +7503,6 @@ "write-file-atomic": "^2.4.2" } }, - "node_modules/electron-json-storage/node_modules/write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, "node_modules/electron-osx-sign": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.5.0.tgz", @@ -7676,9 +7690,9 @@ "license": "ISC" }, "node_modules/electron/node_modules/@types/node": { - "version": "16.18.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.25.tgz", - "integrity": "sha512-rUDO6s9Q/El1R1I21HG4qw/LstTHCPO/oQNAwI/4b2f9EWvMnqt4d3HJwPMawfZ3UvodB8516Yg+VAq54YM+eA==", + "version": "16.18.36", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.36.tgz", + "integrity": "sha512-8egDX8dE50XyXWH6C6PRCNkTP106DuUrvdrednFouDSmCi7IOvrqr0frznfZaHifHH/3aq/7a7v9N4wdXMqhBQ==", "dev": true }, "node_modules/element-ui": { @@ -9352,9 +9366,9 @@ } }, "node_modules/global-agent/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "optional": true, "dependencies": { @@ -10964,15 +10978,15 @@ "license": "MIT" }, "node_modules/jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dev": true, "dependencies": { "async": "^3.2.3", "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" + "filelist": "^1.0.4", + "minimatch": "^3.1.2" }, "bin": { "jake": "bin/cli.js" @@ -12077,6 +12091,10 @@ "dev": true, "license": "MIT" }, + "node_modules/mutation-observer": { + "version": "1.0.3", + "dev": true + }, "node_modules/mute-stream": { "version": "0.0.8", "dev": true, @@ -16045,9 +16063,9 @@ } }, "node_modules/tar": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.14.tgz", - "integrity": "sha512-piERznXu0U7/pW7cdSn7hjqySIVTYT6F76icmFk7ptU7dDYlXTm5r9A6K04R2vU3olYgoKeo1Cg3eeu5nhftAw==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", "dev": true, "dependencies": { "chownr": "^2.0.0", @@ -17043,9 +17061,9 @@ } }, "node_modules/update-notifier/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -17296,6 +17314,17 @@ "node": ">= 0.8" } }, + "node_modules/vconsole": { + "version": "3.15.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.17.2", + "copy-text-to-clipboard": "^3.0.1", + "core-js": "^3.11.0", + "mutation-observer": "^1.0.3" + } + }, "node_modules/vendors": { "version": "1.0.4", "dev": true, @@ -17643,9 +17672,9 @@ } }, "node_modules/vue-cli-plugin-electron-builder/node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -18860,15 +18889,13 @@ } }, "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dependencies": { + "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "signal-exit": "^3.0.2" } }, "node_modules/ws": { @@ -20367,9 +20394,9 @@ } }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -20533,9 +20560,9 @@ } }, "@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", + "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", "dev": true, "requires": { "@types/ms": "*" @@ -20799,7 +20826,6 @@ "version": "4.5.19", "dev": true, "requires": { - "@babel/core": "^7.11.0", "@babel/helper-compilation-targets": "^7.9.6", "@babel/helper-module-imports": "^7.8.3", "@babel/plugin-proposal-class-properties": "^7.8.3", @@ -20812,7 +20838,6 @@ "@vue/babel-plugin-jsx": "^1.0.3", "@vue/babel-preset-jsx": "^1.2.4", "babel-plugin-dynamic-import-node": "^2.3.3", - "core-js": "^3.6.5", "core-js-compat": "^3.6.5", "semver": "^6.1.0" } @@ -21480,9 +21505,9 @@ } }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -22453,9 +22478,9 @@ "dev": true }, "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", "dev": true, "requires": { "clone-response": "^1.0.2", @@ -23025,6 +23050,20 @@ "unique-string": "^2.0.0", "write-file-atomic": "^3.0.0", "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } } }, "connect-history-api-fallback": { @@ -23098,6 +23137,10 @@ "version": "0.1.1", "dev": true }, + "copy-text-to-clipboard": { + "version": "3.1.0", + "dev": true + }, "copy-webpack-plugin": { "version": "5.1.2", "dev": true, @@ -24022,9 +24065,9 @@ "dev": true }, "electron": { - "version": "23.3.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-23.3.1.tgz", - "integrity": "sha512-N+xGMPwK733BU6xn1qs2t/AE3wKEqhWYLvPqWEu6TRC8yQvf7PNNjtgBTPZ9R0GhtrRgu6kUTX3HSV3UG9r/Dw==", + "version": "23.3.7", + "resolved": "https://registry.npmjs.org/electron/-/electron-23.3.7.tgz", + "integrity": "sha512-irr5yfZQP6dLjIbti+2n82tfBafHC3Ejw+B0EKVY/mSjpgTZ0fNZmfjaRjBl53Y5Mz98++CaeeNJlamcIlP9/w==", "dev": true, "requires": { "@electron/get": "^2.0.0", @@ -24033,9 +24076,9 @@ }, "dependencies": { "@types/node": { - "version": "16.18.25", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.25.tgz", - "integrity": "sha512-rUDO6s9Q/El1R1I21HG4qw/LstTHCPO/oQNAwI/4b2f9EWvMnqt4d3HJwPMawfZ3UvodB8516Yg+VAq54YM+eA==", + "version": "16.18.36", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.36.tgz", + "integrity": "sha512-8egDX8dE50XyXWH6C6PRCNkTP106DuUrvdrednFouDSmCi7IOvrqr0frznfZaHifHH/3aq/7a7v9N4wdXMqhBQ==", "dev": true } } @@ -24233,18 +24276,18 @@ } }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, "tslib": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz", - "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", + "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==", "dev": true }, "yallist": { @@ -24266,18 +24309,6 @@ "mkdirp": "^0.5.1", "rimraf": "^2.5.1", "write-file-atomic": "^2.4.2" - }, - "dependencies": { - "write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "requires": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - } } }, "electron-osx-sign": { @@ -25587,9 +25618,9 @@ } }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "optional": true, "requires": { @@ -26618,15 +26649,15 @@ "dev": true }, "jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "version": "10.8.7", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", + "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", "dev": true, "requires": { "async": "^3.2.3", "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" + "filelist": "^1.0.4", + "minimatch": "^3.1.2" }, "dependencies": { "ansi-styles": { @@ -27419,6 +27450,10 @@ "version": "1.1.0", "dev": true }, + "mutation-observer": { + "version": "1.0.3", + "dev": true + }, "mute-stream": { "version": "0.0.8", "dev": true @@ -30310,9 +30345,9 @@ "dev": true }, "tar": { - "version": "6.1.14", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.14.tgz", - "integrity": "sha512-piERznXu0U7/pW7cdSn7hjqySIVTYT6F76icmFk7ptU7dDYlXTm5r9A6K04R2vU3olYgoKeo1Cg3eeu5nhftAw==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", "dev": true, "requires": { "chownr": "^2.0.0", @@ -31019,9 +31054,9 @@ } }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -31203,6 +31238,16 @@ "version": "1.1.2", "dev": true }, + "vconsole": { + "version": "3.15.1", + "dev": true, + "requires": { + "@babel/runtime": "^7.17.2", + "copy-text-to-clipboard": "^3.0.1", + "core-js": "^3.11.0", + "mutation-observer": "^1.0.3" + } + }, "vendors": { "version": "1.0.4", "dev": true @@ -31462,9 +31507,9 @@ } }, "semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz", + "integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==", "dev": true, "requires": { "lru-cache": "^6.0.0" @@ -32316,15 +32361,13 @@ } }, "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", + "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "requires": { + "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" + "signal-exit": "^3.0.2" } }, "ws": { diff --git a/web/package.json b/web/package.json index 54fa1463..0f73b57e 100644 --- a/web/package.json +++ b/web/package.json @@ -58,6 +58,7 @@ "markdown-it": "^13.0.1", "markdown-it-checkbox": "^1.1.0", "prettier": "^1.19.1", + "vconsole": "^3.15.1", "vue-cli-plugin-electron-builder": "~2.1.1", "vue-template-compiler": "^2.6.11", "webpack": "^4.44.2" diff --git a/web/public/index.html b/web/public/index.html index 10932fe8..294e768a 100644 --- a/web/public/index.html +++ b/web/public/index.html @@ -3,7 +3,7 @@ - + 一个简单的web思维导图实现 diff --git a/web/src/assets/avatar/志斌.jpg b/web/src/assets/avatar/志斌.jpg new file mode 100644 index 00000000..a665ada3 Binary files /dev/null and b/web/src/assets/avatar/志斌.jpg differ diff --git a/web/src/assets/icon-font/iconfont.css b/web/src/assets/icon-font/iconfont.css index 5193dd1c..32a38dce 100644 --- a/web/src/assets/icon-font/iconfont.css +++ b/web/src/assets/icon-font/iconfont.css @@ -1,8 +1,8 @@ @font-face { font-family: "iconfont"; /* Project id 2479351 */ - src: url('iconfont.woff2?t=1679621707211') format('woff2'), - url('iconfont.woff?t=1679621707211') format('woff'), - url('iconfont.ttf?t=1679621707211') format('truetype'); + src: url('iconfont.woff2?t=1686298427624') format('woff2'), + url('iconfont.woff?t=1686298427624') format('woff'), + url('iconfont.ttf?t=1686298427624') format('truetype'); } .iconfont { @@ -13,6 +13,14 @@ -moz-osx-font-smoothing: grayscale; } +.iconmouseR:before { + content: "\e6bd"; +} + +.iconmouseL:before { + content: "\e6c0"; +} + .iconwenjian:before { content: "\e607"; } diff --git a/web/src/assets/icon-font/iconfont.ttf b/web/src/assets/icon-font/iconfont.ttf index 2311cfcd..9ab744d3 100644 Binary files a/web/src/assets/icon-font/iconfont.ttf and b/web/src/assets/icon-font/iconfont.ttf differ diff --git a/web/src/assets/icon-font/iconfont.woff b/web/src/assets/icon-font/iconfont.woff index 1bdad3ba..a4e57c87 100644 Binary files a/web/src/assets/icon-font/iconfont.woff and b/web/src/assets/icon-font/iconfont.woff differ diff --git a/web/src/assets/icon-font/iconfont.woff2 b/web/src/assets/icon-font/iconfont.woff2 index f3c1c366..487c6d0d 100644 Binary files a/web/src/assets/icon-font/iconfont.woff2 and b/web/src/assets/icon-font/iconfont.woff2 differ diff --git a/web/src/config/en.js b/web/src/config/en.js index f813eb63..e0a8136d 100644 --- a/web/src/config/en.js +++ b/web/src/config/en.js @@ -291,6 +291,11 @@ export const shortcutKeyList = [ icon: 'icondingwei', name: 'Reset', value: 'Ctrl + Enter' + }, + { + icon: 'iconquanping1', + name: 'fit canvas', + value: 'Ctrl + i' } ] } diff --git a/web/src/config/zh.js b/web/src/config/zh.js index 07080b96..db06f4c5 100644 --- a/web/src/config/zh.js +++ b/web/src/config/zh.js @@ -351,6 +351,11 @@ export const shortcutKeyList = [ icon: 'icondingwei', name: '恢复默认', value: 'Ctrl + Enter' + }, + { + icon: 'iconquanping1', + name: '适应画布', + value: 'Ctrl + i' } ] } diff --git a/web/src/lang/en_us.js b/web/src/lang/en_us.js index f66a24ea..7ea75351 100644 --- a/web/src/lang/en_us.js +++ b/web/src/lang/en_us.js @@ -69,7 +69,8 @@ export default { level4: 'Level4', level5: 'Level5', level6: 'Level6', - zenMode: 'Zen mode' + zenMode: 'Zen mode', + fitCanvas: 'Fit canvas' }, count: { words: 'Words', @@ -201,5 +202,9 @@ export default { edit: { newFeatureNoticeTitle: 'New feature reminder', newFeatureNoticeMessage: 'This update supports node rich text editing, But there are some defects, The most important impact is that the time to export the image is proportional to the number of nodes, Therefore, if you are more dependent on export requirements, you can use【Base style】-【Other config】-【Enable node rich text editing】Set to turn off rich text editing mode.' + }, + mouseAction: { + tip1: 'Current: Left click to drag the canvas, right click to box select nodes', + tip2: 'Current: Left click to box select nodes, right click to drag the canvas', } } diff --git a/web/src/lang/zh_cn.js b/web/src/lang/zh_cn.js index 407866ef..858de591 100644 --- a/web/src/lang/zh_cn.js +++ b/web/src/lang/zh_cn.js @@ -69,7 +69,8 @@ export default { level4: '四级主题', level5: '五级主题', level6: '六级主题', - zenMode: '禅模式' + zenMode: '禅模式', + fitCanvas: '适应画布' }, count: { words: '字数', @@ -201,5 +202,9 @@ export default { edit: { newFeatureNoticeTitle: '新特性提醒', newFeatureNoticeMessage: '本次更新支持了节点富文本编辑,但是存在一定缺陷,最主要的影响是导出为图片的时间和节点数量成正比,所以对导出需求比较依赖的话可以通过【基础样式】-【其他配置】-【是否开启节点富文本编辑】设置关掉富文本编辑模式。' + }, + mouseAction: { + tip1: '当前:左键拖动画布,右键框选节点', + tip2: '当前:左键框选节点,右键拖动画布', } } diff --git a/web/src/main.js b/web/src/main.js index 44d3cc03..e43b329b 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -9,6 +9,8 @@ import 'viewerjs/dist/viewer.css' import VueViewer from 'v-viewer' import i18n from './i18n' import './css/global.css' +// import VConsole from 'vconsole' +// const vConsole = new VConsole() Vue.config.productionTip = false Vue.prototype.$bus = new Vue() diff --git a/web/src/pages/Doc/catalogList.js b/web/src/pages/Doc/catalogList.js index a8c12225..cdc0ec6f 100644 --- a/web/src/pages/Doc/catalogList.js +++ b/web/src/pages/Doc/catalogList.js @@ -10,7 +10,7 @@ let langList = [ path: 'en' } ] -let StartList = ['introduction', 'start', 'deploy', 'translate', 'changelog'] +let StartList = ['introduction', 'start', 'deploy', 'client', 'translate', 'changelog'] let CourseList = new Array(19).fill(0).map((_, index) => { return 'course' + (index + 1) }) @@ -30,6 +30,7 @@ let APIList = [ 'miniMap', 'watermark', 'associativeLine', + 'touchEvent', 'xmind', 'markdown', 'utils' diff --git a/web/src/pages/Doc/en/associativeLine/index.md b/web/src/pages/Doc/en/associativeLine/index.md index 9a726858..06685ee1 100644 --- a/web/src/pages/Doc/en/associativeLine/index.md +++ b/web/src/pages/Doc/en/associativeLine/index.md @@ -12,7 +12,8 @@ This plugin is used to support the addition of associative lines. ```js import MindMap from 'simple-mind-map' -import AssociativeLine from 'simple-mind-map/src/AssociativeLine.js' +import AssociativeLine from 'simple-mind-map/src/plugins/AssociativeLine.js' +// import AssociativeLine from 'simple-mind-map/src/AssociativeLine.js' Use this path for versions below v0.6.0 MindMap.usePlugin(AssociativeLine) ``` diff --git a/web/src/pages/Doc/en/associativeLine/index.vue b/web/src/pages/Doc/en/associativeLine/index.vue index 4981edcc..bc39c6cf 100644 --- a/web/src/pages/Doc/en/associativeLine/index.vue +++ b/web/src/pages/Doc/en/associativeLine/index.vue @@ -13,7 +13,8 @@

This plugin is used to support the addition of associative lines.

Register

import MindMap from 'simple-mind-map'
-import AssociativeLine from 'simple-mind-map/src/AssociativeLine.js'
+import AssociativeLine from 'simple-mind-map/src/plugins/AssociativeLine.js'
+// import AssociativeLine from 'simple-mind-map/src/AssociativeLine.js' Use this path for versions below v0.6.0
 
 MindMap.usePlugin(AssociativeLine)
 
diff --git a/web/src/pages/Doc/en/changelog/index.md b/web/src/pages/Doc/en/changelog/index.md index 42236e0b..b2ec82a8 100644 --- a/web/src/pages/Doc/en/changelog/index.md +++ b/web/src/pages/Doc/en/changelog/index.md @@ -1,5 +1,25 @@ # Changelog +## 0.6.2 + +Fix: 1.Fixed the problem that the new node does not change with the theme in rich Text mode. + +## 0.6.1 + +Fix: 1.Fixed the issue of high movement sensitivity when using the touchpad when changing mouse scrolling to moving the canvas behavior. + +## 0.6.0-fix.1 + +Fix: 1.Fixed the issue of destroying mind maps without setting a background style and reporting errors. + +## 0.6.0 + +Breaking change: Adjusted the directory structure of the simple-mind-map source code, Main impact: 1. The introduction path of the plugin needs to be modified. The constant file path needs to be modified. + +New: 1.Supports one click zoom to fit the canvas function. 2.Press and hold the Ctrl key to activate the multi selection function on demand through configuration. 3.Support setting to left click to select multiple nodes and right click to drag the canvas. 4. Support controlling whether nodes are allowed to be edited. 5.Add a method for destroying mind maps. 6.Added touch event support plugin. + +Fix: 1.Fix the issue where holding down the Ctrl key to select multiple nodes does not trigger the click event for the node. 2.Fixed the issue of node style loss when clearing a node and then entering text. + ## 0.5.11 New: Supports associative text editing. diff --git a/web/src/pages/Doc/en/changelog/index.vue b/web/src/pages/Doc/en/changelog/index.vue index 6ae87866..f75ec873 100644 --- a/web/src/pages/Doc/en/changelog/index.vue +++ b/web/src/pages/Doc/en/changelog/index.vue @@ -1,6 +1,16 @@ diff --git a/web/src/pages/Doc/en/keyCommand/index.md b/web/src/pages/Doc/en/keyCommand/index.md index d47f5186..2ea06cc9 100644 --- a/web/src/pages/Doc/en/keyCommand/index.md +++ b/web/src/pages/Doc/en/keyCommand/index.md @@ -11,7 +11,7 @@ includes some built-in shortcuts and can also be added manually. The Add a shortcut `key`: Shortcut key, key values can be viewed at -[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js) +[keyMap.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/command/keyMap.js) Example: ```js diff --git a/web/src/pages/Doc/en/keyCommand/index.vue b/web/src/pages/Doc/en/keyCommand/index.vue index 0c9643c2..48d83d0d 100644 --- a/web/src/pages/Doc/en/keyCommand/index.vue +++ b/web/src/pages/Doc/en/keyCommand/index.vue @@ -8,7 +8,7 @@ includes some built-in shortcuts and can also be added manually. The

addShortcut(key, fn)

Add a shortcut

key: Shortcut key, key values can be viewed at -https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js +keyMap.js Example:

// Single key
 mindMap.keyCommand.addShortcut("Enter", () => {});
diff --git a/web/src/pages/Doc/en/keyboardNavigation/index.md b/web/src/pages/Doc/en/keyboardNavigation/index.md
index 09bb5f2d..dae4cd05 100644
--- a/web/src/pages/Doc/en/keyboardNavigation/index.md
+++ b/web/src/pages/Doc/en/keyboardNavigation/index.md
@@ -8,7 +8,8 @@
 
 ```js
 import MindMap from 'simple-mind-map'
-import KeyboardNavigation from 'simple-mind-map/src/KeyboardNavigation.js'
+import KeyboardNavigation from 'simple-mind-map/src/plugins/KeyboardNavigation.js'
+// import KeyboardNavigation from 'simple-mind-map/src/KeyboardNavigation.js' Use this path for versions below v0.6.0
 
 MindMap.usePlugin(KeyboardNavigation)
 ```
diff --git a/web/src/pages/Doc/en/keyboardNavigation/index.vue b/web/src/pages/Doc/en/keyboardNavigation/index.vue
index c45ae94f..a3a918bb 100644
--- a/web/src/pages/Doc/en/keyboardNavigation/index.vue
+++ b/web/src/pages/Doc/en/keyboardNavigation/index.vue
@@ -7,7 +7,8 @@
 

KeyboardNavigation plugin provides keyboard navigation function, that is, when you press the direction key, it will automatically find the next node and activate it.

Register

import MindMap from 'simple-mind-map'
-import KeyboardNavigation from 'simple-mind-map/src/KeyboardNavigation.js'
+import KeyboardNavigation from 'simple-mind-map/src/plugins/KeyboardNavigation.js'
+// import KeyboardNavigation from 'simple-mind-map/src/KeyboardNavigation.js' Use this path for versions below v0.6.0
 
 MindMap.usePlugin(KeyboardNavigation)
 
diff --git a/web/src/pages/Doc/en/miniMap/index.md b/web/src/pages/Doc/en/miniMap/index.md index 495ab5f8..1c42d08d 100644 --- a/web/src/pages/Doc/en/miniMap/index.md +++ b/web/src/pages/Doc/en/miniMap/index.md @@ -12,7 +12,8 @@ viewport location, and can be quickly positioned by dragging on the small map. ```js import MindMap from 'simple-mind-map' -import MiniMap from 'simple-mind-map/src/MiniMap.js' +import MiniMap from 'simple-mind-map/src/plugins/MiniMap.js' +// import MiniMap from 'simple-mind-map/src/MiniMap.js' Use this path for versions below v0.6.0 MindMap.usePlugin(MiniMap) ``` diff --git a/web/src/pages/Doc/en/miniMap/index.vue b/web/src/pages/Doc/en/miniMap/index.vue index 75b18097..c5946cb9 100644 --- a/web/src/pages/Doc/en/miniMap/index.vue +++ b/web/src/pages/Doc/en/miniMap/index.vue @@ -11,7 +11,8 @@ part of the mind map content. The viewport frame can be used to view the current viewport location, and can be quickly positioned by dragging on the small map.

Register

import MindMap from 'simple-mind-map'
-import MiniMap from 'simple-mind-map/src/MiniMap.js'
+import MiniMap from 'simple-mind-map/src/plugins/MiniMap.js'
+// import MiniMap from 'simple-mind-map/src/MiniMap.js' Use this path for versions below v0.6.0
 
 MindMap.usePlugin(MiniMap)
 
diff --git a/web/src/pages/Doc/en/node/index.md b/web/src/pages/Doc/en/node/index.md index 9fb7aa24..809ae16b 100644 --- a/web/src/pages/Doc/en/node/index.md +++ b/web/src/pages/Doc/en/node/index.md @@ -56,6 +56,12 @@ Whether the node is currently being dragged ## Methods +### hasCustomStyle() + +> v0.6.2+ + +Gets whether a custom style has been set. + ### getSize() Update the width and height of the node by recreating the node content, and return a Boolean value indicating whether the width and height have changed diff --git a/web/src/pages/Doc/en/node/index.vue b/web/src/pages/Doc/en/node/index.vue index eaf4611d..bac896da 100644 --- a/web/src/pages/Doc/en/node/index.vue +++ b/web/src/pages/Doc/en/node/index.vue @@ -31,6 +31,11 @@

Whether the node is currently being dragged

Methods

+

hasCustomStyle()

+
+

v0.6.2+

+
+

Gets whether a custom style has been set.

getSize()

Update the width and height of the node by recreating the node content, and return a Boolean value indicating whether the width and height have changed

render()

diff --git a/web/src/pages/Doc/en/richText/index.md b/web/src/pages/Doc/en/richText/index.md index e4f09294..2223ce35 100644 --- a/web/src/pages/Doc/en/richText/index.md +++ b/web/src/pages/Doc/en/richText/index.md @@ -20,7 +20,8 @@ The version of `v0.5.7+` directly uses `html2canvas` to convert the entire `svg` ```js import MindMap from 'simple-mind-map' -import RichText from 'simple-mind-map/src/RichText.js' +import RichText from 'simple-mind-map/src/plugins/RichText.js' +// import RichText from 'simple-mind-map/src/RichText.js' Use this path for versions below v0.6.0 MindMap.usePlugin(RichText, opt?) ``` diff --git a/web/src/pages/Doc/en/richText/index.vue b/web/src/pages/Doc/en/richText/index.vue index 43db5c80..7b645bd8 100644 --- a/web/src/pages/Doc/en/richText/index.vue +++ b/web/src/pages/Doc/en/richText/index.vue @@ -17,7 +17,8 @@

The version of v0.5.7+ directly uses html2canvas to convert the entire svg, which is no longer an issue with speed. However, there is currently a bug where the color of the node does not take effect after export.

Register

import MindMap from 'simple-mind-map'
-import RichText from 'simple-mind-map/src/RichText.js'
+import RichText from 'simple-mind-map/src/plugins/RichText.js'
+// import RichText from 'simple-mind-map/src/RichText.js' Use this path for versions below v0.6.0
 
 MindMap.usePlugin(RichText, opt?)
 
diff --git a/web/src/pages/Doc/en/select/index.md b/web/src/pages/Doc/en/select/index.md index 1761d1d5..6eb7a088 100644 --- a/web/src/pages/Doc/en/select/index.md +++ b/web/src/pages/Doc/en/select/index.md @@ -6,7 +6,8 @@ The `Select` plugin provides the function of right-clicking to select multiple n ```js import MindMap from 'simple-mind-map' -import Select from 'simple-mind-map/src/Select.js' +import Select from 'simple-mind-map/src/plugins/Select.js' +// import Select from 'simple-mind-map/src/Select.js' Use this path for versions below v0.6.0 MindMap.usePlugin(Select) ``` diff --git a/web/src/pages/Doc/en/select/index.vue b/web/src/pages/Doc/en/select/index.vue index d174955d..aecb9235 100644 --- a/web/src/pages/Doc/en/select/index.vue +++ b/web/src/pages/Doc/en/select/index.vue @@ -4,7 +4,8 @@

The Select plugin provides the function of right-clicking to select multiple nodes.

Register

import MindMap from 'simple-mind-map'
-import Select from 'simple-mind-map/src/Select.js'
+import Select from 'simple-mind-map/src/plugins/Select.js'
+// import Select from 'simple-mind-map/src/Select.js' Use this path for versions below v0.6.0
 
 MindMap.usePlugin(Select)
 
diff --git a/web/src/pages/Doc/en/start/index.md b/web/src/pages/Doc/en/start/index.md index b89c6a41..cf7bf663 100644 --- a/web/src/pages/Doc/en/start/index.md +++ b/web/src/pages/Doc/en/start/index.md @@ -91,6 +91,7 @@ If you only use library, you don't need to read this section. ```bash git clone https://github.com/wanglin2/mind-map.git +cd mind-map cd simple-mind-map npm i npm link diff --git a/web/src/pages/Doc/en/start/index.vue b/web/src/pages/Doc/en/start/index.vue index e91ada19..ae5c83d0 100644 --- a/web/src/pages/Doc/en/start/index.vue +++ b/web/src/pages/Doc/en/start/index.vue @@ -64,6 +64,7 @@ compile this dependency:

If you only use library, you don't need to read this section.

Local Development

git clone https://github.com/wanglin2/mind-map.git
+cd mind-map
 cd simple-mind-map
 npm i
 npm link
diff --git a/web/src/pages/Doc/en/touchEvent/index.md b/web/src/pages/Doc/en/touchEvent/index.md
new file mode 100644
index 00000000..7b65cd6b
--- /dev/null
+++ b/web/src/pages/Doc/en/touchEvent/index.md
@@ -0,0 +1,18 @@
+# TouchEvent plugin
+
+> v0.6.0+
+
+This plugin supports mobile touch events for users. The principle is to listen for 'touchstart', 'touchmove', and 'touchend' events on the mobile end, and then dispatch corresponding mouse events.
+
+Currently, it supports single finger touch to move the canvas, click to activate nodes, double finger zoom the canvas, single finger double-click to reset and edit nodes.
+
+## Register
+
+```js
+import MindMap from 'simple-mind-map'
+import TouchEvent from 'simple-mind-map/src/plugins/TouchEvent.js'
+
+MindMap.usePlugin(TouchEvent)
+```
+
+After registration and instantiation of `MindMap`, the instance can be obtained through `mindMap.touchEvent`.
\ No newline at end of file
diff --git a/web/src/pages/Doc/en/touchEvent/index.vue b/web/src/pages/Doc/en/touchEvent/index.vue
new file mode 100644
index 00000000..e1fedd45
--- /dev/null
+++ b/web/src/pages/Doc/en/touchEvent/index.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/pages/Doc/en/view/index.md b/web/src/pages/Doc/en/view/index.md
index 4c77956c..f11130be 100644
--- a/web/src/pages/Doc/en/view/index.md
+++ b/web/src/pages/Doc/en/view/index.md
@@ -5,6 +5,12 @@ through `mindMap.view`
 
 ## Methods
 
+### fit()
+
+> v0.6.0+
+
+Zoom the mind map to fit the canvas.
+
 ### translateX(step)
 
 Translate in the `x` direction, `step`: number of pixels to translate
diff --git a/web/src/pages/Doc/en/view/index.vue b/web/src/pages/Doc/en/view/index.vue
index 90f077fd..085f4f1e 100644
--- a/web/src/pages/Doc/en/view/index.vue
+++ b/web/src/pages/Doc/en/view/index.vue
@@ -4,6 +4,11 @@
 

The view instance is responsible for view operations, and can be obtained through mindMap.view

Methods

+

fit()

+
+

v0.6.0+

+
+

Zoom the mind map to fit the canvas.

translateX(step)

Translate in the x direction, step: number of pixels to translate

translateY(step)

diff --git a/web/src/pages/Doc/en/watermark/index.md b/web/src/pages/Doc/en/watermark/index.md index 08e11aad..5c39043d 100644 --- a/web/src/pages/Doc/en/watermark/index.md +++ b/web/src/pages/Doc/en/watermark/index.md @@ -10,7 +10,8 @@ Please refer to the [Instantiation Options](/mind-map/#/doc/zh/constructor) of t ```js import MindMap from 'simple-mind-map' -import Watermark from 'simple-mind-map/src/Watermark.js' +import Watermark from 'simple-mind-map/src/plugins/Watermark.js' +// import Watermark from 'simple-mind-map/src/Watermark.js' Use this path for versions below v0.6.0 MindMap.usePlugin(Watermark) ``` diff --git a/web/src/pages/Doc/en/watermark/index.vue b/web/src/pages/Doc/en/watermark/index.vue index 8daf838b..19c899ec 100644 --- a/web/src/pages/Doc/en/watermark/index.vue +++ b/web/src/pages/Doc/en/watermark/index.vue @@ -8,7 +8,8 @@

Please refer to the Instantiation Options of the MindMap class for configuration.

Register

import MindMap from 'simple-mind-map'
-import Watermark from 'simple-mind-map/src/Watermark.js'
+import Watermark from 'simple-mind-map/src/plugins/Watermark.js'
+// import Watermark from 'simple-mind-map/src/Watermark.js' Use this path for versions below v0.6.0
 
 MindMap.usePlugin(Watermark)
 
diff --git a/web/src/pages/Doc/routerList.js b/web/src/pages/Doc/routerList.js index 4ee8063a..d024d5e5 100644 --- a/web/src/pages/Doc/routerList.js +++ b/web/src/pages/Doc/routerList.js @@ -43,7 +43,9 @@ export default [ { path: 'view', title: 'View实例' }, { path: 'watermark', title: 'Watermark插件' }, { path: 'xmind', title: 'XMind解析' }, - { path: 'deploy', title: '部署' } + { path: 'deploy', title: '部署' }, + { path: 'client', title: '客户端' }, + { path: 'touchEvent', title: 'TouchEvent插件' } ] }, { @@ -71,7 +73,8 @@ export default [ { path: 'view', title: 'View instance' }, { path: 'watermark', title: 'Watermark plugin' }, { path: 'xmind', title: 'XMind parse' }, - { path: 'deploy', title: 'Deploy' } + { path: 'deploy', title: 'Deploy' }, + { path: 'touchEvent', title: 'TouchEvent plugin' } ] } ] diff --git a/web/src/pages/Doc/zh/associativeLine/index.md b/web/src/pages/Doc/zh/associativeLine/index.md index 72f692d3..1507e037 100644 --- a/web/src/pages/Doc/zh/associativeLine/index.md +++ b/web/src/pages/Doc/zh/associativeLine/index.md @@ -12,7 +12,8 @@ ```js import MindMap from 'simple-mind-map' -import AssociativeLine from 'simple-mind-map/src/AssociativeLine.js' +import AssociativeLine from 'simple-mind-map/src/plugins/AssociativeLine.js' +// import AssociativeLine from 'simple-mind-map/src/AssociativeLine.js' v0.6.0以下版本使用该路径 MindMap.usePlugin(AssociativeLine) ``` diff --git a/web/src/pages/Doc/zh/associativeLine/index.vue b/web/src/pages/Doc/zh/associativeLine/index.vue index 4e5cda2b..8f4b704b 100644 --- a/web/src/pages/Doc/zh/associativeLine/index.vue +++ b/web/src/pages/Doc/zh/associativeLine/index.vue @@ -13,7 +13,8 @@

该插件用于支持添加关联线。

注册

import MindMap from 'simple-mind-map'
-import AssociativeLine from 'simple-mind-map/src/AssociativeLine.js'
+import AssociativeLine from 'simple-mind-map/src/plugins/AssociativeLine.js'
+// import AssociativeLine from 'simple-mind-map/src/AssociativeLine.js' v0.6.0以下版本使用该路径
 
 MindMap.usePlugin(AssociativeLine)
 
diff --git a/web/src/pages/Doc/zh/changelog/index.md b/web/src/pages/Doc/zh/changelog/index.md index 3fc6fc2d..40ce409c 100644 --- a/web/src/pages/Doc/zh/changelog/index.md +++ b/web/src/pages/Doc/zh/changelog/index.md @@ -1,5 +1,25 @@ # Changelog +## 0.6.2 + +修复:1.修复富文本模式下,新建节点不随主题变化而变化的问题。 + +## 0.6.1 + +修复:1.修复将鼠标滚动改为移动画布行为后,使用触控板操作时移动灵敏度过高的问题。 + +## 0.6.0-fix.1 + +修复:1.修复没有设置过背景样式的情况下销毁思维导图报错的问题。 + +## 0.6.0 + +破坏性更新:调整了simple-mind-map源码的目录结构,主要影响:1.插件的引入路径需要修改。2.constant文件路径需要修改。 + +新增:1.支持一键缩放至适应画布功能。 2.按住Ctrl键多选功能可通过配置按需开启。 3.支持设置为左键多选节点,右键拖动画布。 4.支持控制节点是否允许编辑。 5.新增销毁思维导图的方法。 6.新增触摸事件支持插件。 + +修复:1.修复按住ctrl键多选节点时不会触发节点的click事件的问题。 2.修复清空一个节点后再输入文字时节点样式丢失的问题。 + ## 0.5.11 新增:支持关联性文本编辑。 diff --git a/web/src/pages/Doc/zh/changelog/index.vue b/web/src/pages/Doc/zh/changelog/index.vue index e4e59f09..8ae12e9c 100644 --- a/web/src/pages/Doc/zh/changelog/index.vue +++ b/web/src/pages/Doc/zh/changelog/index.vue @@ -1,6 +1,16 @@ diff --git a/web/src/pages/Doc/zh/keyCommand/index.md b/web/src/pages/Doc/zh/keyCommand/index.md index 8de93543..c332bff0 100644 --- a/web/src/pages/Doc/zh/keyCommand/index.md +++ b/web/src/pages/Doc/zh/keyCommand/index.md @@ -8,7 +8,7 @@ 添加快捷键 -`key`:快捷键按键,按键值可以通过[https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js)查看。示例: +`key`:快捷键按键,按键值可以通过[keyMap.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/command/keyMap.js)查看。示例: ```js // 单个按键 diff --git a/web/src/pages/Doc/zh/keyCommand/index.vue b/web/src/pages/Doc/zh/keyCommand/index.vue index 7b6b7efd..163180d4 100644 --- a/web/src/pages/Doc/zh/keyCommand/index.vue +++ b/web/src/pages/Doc/zh/keyCommand/index.vue @@ -5,7 +5,7 @@

方法

addShortcut(key, fn)

添加快捷键

-

key:快捷键按键,按键值可以通过https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/utils/keyMap.js查看。示例:

+

key:快捷键按键,按键值可以通过keyMap.js查看。示例:

// 单个按键
 mindMap.keyCommand.addShortcut('Enter', () => {})
 // 或
diff --git a/web/src/pages/Doc/zh/keyboardNavigation/index.md b/web/src/pages/Doc/zh/keyboardNavigation/index.md
index abe83fdd..5a7cd801 100644
--- a/web/src/pages/Doc/zh/keyboardNavigation/index.md
+++ b/web/src/pages/Doc/zh/keyboardNavigation/index.md
@@ -8,7 +8,8 @@
 
 ```js
 import MindMap from 'simple-mind-map'
-import KeyboardNavigation from 'simple-mind-map/src/KeyboardNavigation.js'
+import KeyboardNavigation from 'simple-mind-map/src/plugins/KeyboardNavigation.js'
+// import KeyboardNavigation from 'simple-mind-map/src/KeyboardNavigation.js' v0.6.0以下版本使用该路径
 
 MindMap.usePlugin(KeyboardNavigation)
 ```
diff --git a/web/src/pages/Doc/zh/keyboardNavigation/index.vue b/web/src/pages/Doc/zh/keyboardNavigation/index.vue
index ea38b890..b51a9964 100644
--- a/web/src/pages/Doc/zh/keyboardNavigation/index.vue
+++ b/web/src/pages/Doc/zh/keyboardNavigation/index.vue
@@ -7,7 +7,8 @@
 

KeyboardNavigation插件提供键盘导航的功能,也就是当你按下方向键时会自动寻找下一个节点并激活

注册

import MindMap from 'simple-mind-map'
-import KeyboardNavigation from 'simple-mind-map/src/KeyboardNavigation.js'
+import KeyboardNavigation from 'simple-mind-map/src/plugins/KeyboardNavigation.js'
+// import KeyboardNavigation from 'simple-mind-map/src/KeyboardNavigation.js' v0.6.0以下版本使用该路径
 
 MindMap.usePlugin(KeyboardNavigation)
 
diff --git a/web/src/pages/Doc/zh/miniMap/index.md b/web/src/pages/Doc/zh/miniMap/index.md index 3c6939d7..ebd00303 100644 --- a/web/src/pages/Doc/zh/miniMap/index.md +++ b/web/src/pages/Doc/zh/miniMap/index.md @@ -8,7 +8,8 @@ ```js import MindMap from 'simple-mind-map' -import MiniMap from 'simple-mind-map/src/MiniMap.js' +import MiniMap from 'simple-mind-map/src/plugins/MiniMap.js' +// import MiniMap from 'simple-mind-map/src/MiniMap.js' v0.6.0以下版本使用该路径 MindMap.usePlugin(MiniMap) ``` diff --git a/web/src/pages/Doc/zh/miniMap/index.vue b/web/src/pages/Doc/zh/miniMap/index.vue index ba3b686c..a5ed0271 100644 --- a/web/src/pages/Doc/zh/miniMap/index.vue +++ b/web/src/pages/Doc/zh/miniMap/index.vue @@ -7,7 +7,8 @@

用于帮助快速开发小地图功能,小地图由两部分组成,一个是当前的画布内容,一个是视口框,当缩放、移动、元素过多时画布上可能只显示了思维导图的部分内容,可以通过视口框来查看当前视口所在位置,以及可以通过在小地图上拖动来快速定位。

注册

import MindMap from 'simple-mind-map'
-import MiniMap from 'simple-mind-map/src/MiniMap.js'
+import MiniMap from 'simple-mind-map/src/plugins/MiniMap.js'
+// import MiniMap from 'simple-mind-map/src/MiniMap.js' v0.6.0以下版本使用该路径
 
 MindMap.usePlugin(MiniMap)
 
diff --git a/web/src/pages/Doc/zh/node/index.md b/web/src/pages/Doc/zh/node/index.md index 0c25c4de..851f5905 100644 --- a/web/src/pages/Doc/zh/node/index.md +++ b/web/src/pages/Doc/zh/node/index.md @@ -56,6 +56,12 @@ ## 方法 +### hasCustomStyle() + +> v0.6.2+ + +获取是否设置了自定义样式。 + ### getSize() 通过重新创建节点内容更新节点的宽高,返回一个布尔值,代表是否宽高发生了变化 diff --git a/web/src/pages/Doc/zh/node/index.vue b/web/src/pages/Doc/zh/node/index.vue index bdc643fc..7d6e31ce 100644 --- a/web/src/pages/Doc/zh/node/index.vue +++ b/web/src/pages/Doc/zh/node/index.vue @@ -31,6 +31,11 @@

节点是否正在拖拽中

方法

+

hasCustomStyle()

+
+

v0.6.2+

+
+

获取是否设置了自定义样式。

getSize()

通过重新创建节点内容更新节点的宽高,返回一个布尔值,代表是否宽高发生了变化

render()

diff --git a/web/src/pages/Doc/zh/richText/index.md b/web/src/pages/Doc/zh/richText/index.md index fe1496c0..dcca3e9d 100644 --- a/web/src/pages/Doc/zh/richText/index.md +++ b/web/src/pages/Doc/zh/richText/index.md @@ -20,7 +20,8 @@ ```js import MindMap from 'simple-mind-map' -import RichText from 'simple-mind-map/src/RichText.js' +import RichText from 'simple-mind-map/src/plugins/RichText.js' +// import RichText from 'simple-mind-map/src/RichText.js' v0.6.0以下版本使用该路径 MindMap.usePlugin(RichText, opt?) ``` diff --git a/web/src/pages/Doc/zh/richText/index.vue b/web/src/pages/Doc/zh/richText/index.vue index 4fe77a03..510f1184 100644 --- a/web/src/pages/Doc/zh/richText/index.vue +++ b/web/src/pages/Doc/zh/richText/index.vue @@ -17,7 +17,8 @@

v0.5.7+的版本直接使用html2canvas转换整个svg,速度不再是问题,但是目前存在一个bug,就是节点的颜色导出后不生效。

注册

import MindMap from 'simple-mind-map'
-import RichText from 'simple-mind-map/src/RichText.js'
+import RichText from 'simple-mind-map/src/plugins/RichText.js'
+// import RichText from 'simple-mind-map/src/RichText.js' v0.6.0以下版本使用该路径
 
 MindMap.usePlugin(RichText, opt?)
 
diff --git a/web/src/pages/Doc/zh/select/index.md b/web/src/pages/Doc/zh/select/index.md index 1e725c67..a1767936 100644 --- a/web/src/pages/Doc/zh/select/index.md +++ b/web/src/pages/Doc/zh/select/index.md @@ -6,7 +6,8 @@ ```js import MindMap from 'simple-mind-map' -import Select from 'simple-mind-map/src/Select.js' +import Select from 'simple-mind-map/src/plugins/Select.js' +// import Select from 'simple-mind-map/src/Select.js' v0.6.0以下版本使用该路径 MindMap.usePlugin(Select) ``` diff --git a/web/src/pages/Doc/zh/select/index.vue b/web/src/pages/Doc/zh/select/index.vue index 4360db88..ddc0852e 100644 --- a/web/src/pages/Doc/zh/select/index.vue +++ b/web/src/pages/Doc/zh/select/index.vue @@ -4,7 +4,8 @@

Select插件提供鼠标右键多选节点的功能。

注册

import MindMap from 'simple-mind-map'
-import Select from 'simple-mind-map/src/Select.js'
+import Select from 'simple-mind-map/src/plugins/Select.js'
+// import Select from 'simple-mind-map/src/Select.js' v0.6.0以下版本使用该路径
 
 MindMap.usePlugin(Select)
 
diff --git a/web/src/pages/Doc/zh/start/index.md b/web/src/pages/Doc/zh/start/index.md index 8b0bc883..97087456 100644 --- a/web/src/pages/Doc/zh/start/index.md +++ b/web/src/pages/Doc/zh/start/index.md @@ -86,6 +86,7 @@ const mindMap = new MindMap({ ```bash git clone https://github.com/wanglin2/mind-map.git +cd mind-map cd simple-mind-map npm i npm link diff --git a/web/src/pages/Doc/zh/start/index.vue b/web/src/pages/Doc/zh/start/index.vue index 11e5cebd..826934db 100644 --- a/web/src/pages/Doc/zh/start/index.vue +++ b/web/src/pages/Doc/zh/start/index.vue @@ -58,6 +58,7 @@

如果你只是使用库的话可以不用阅读此小节。

本地开发

git clone https://github.com/wanglin2/mind-map.git
+cd mind-map
 cd simple-mind-map
 npm i
 npm link
diff --git a/web/src/pages/Doc/zh/touchEvent/index.md b/web/src/pages/Doc/zh/touchEvent/index.md
new file mode 100644
index 00000000..cd0dabb5
--- /dev/null
+++ b/web/src/pages/Doc/zh/touchEvent/index.md
@@ -0,0 +1,18 @@
+# TouchEvent插件
+
+> v0.6.0+
+
+该插件用户支持移动端触摸事件。原理是监听移动端的`touchstart`、`touchmove`、`touchend`事件,然后派发对应的鼠标事件。
+
+目前支持单指触摸移动画布、点击激活节点,双指缩放画布,单指双击复位和编辑节点。
+
+## 注册
+
+```js
+import MindMap from 'simple-mind-map'
+import TouchEvent from 'simple-mind-map/src/plugins/TouchEvent.js'
+
+MindMap.usePlugin(TouchEvent)
+```
+
+注册完且实例化`MindMap`后可通过`mindMap.touchEvent`获取到该实例。
\ No newline at end of file
diff --git a/web/src/pages/Doc/zh/touchEvent/index.vue b/web/src/pages/Doc/zh/touchEvent/index.vue
new file mode 100644
index 00000000..02df092f
--- /dev/null
+++ b/web/src/pages/Doc/zh/touchEvent/index.vue
@@ -0,0 +1,28 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/web/src/pages/Doc/zh/view/index.md b/web/src/pages/Doc/zh/view/index.md
index a53ecad9..218b318c 100644
--- a/web/src/pages/Doc/zh/view/index.md
+++ b/web/src/pages/Doc/zh/view/index.md
@@ -4,6 +4,12 @@
 
 ## 方法
 
+### fit()
+
+> v0.6.0+
+
+缩放思维导图至适应画布。
+
 ### translateX(step)
 
 `x`方向进行平移,`step`:要平移的像素
diff --git a/web/src/pages/Doc/zh/view/index.vue b/web/src/pages/Doc/zh/view/index.vue
index 101af875..d994036a 100644
--- a/web/src/pages/Doc/zh/view/index.vue
+++ b/web/src/pages/Doc/zh/view/index.vue
@@ -3,6 +3,11 @@
     

View实例

view实例负责视图操作,可通过mindMap.view获取到该实例

方法

+

fit()

+
+

v0.6.0+

+
+

缩放思维导图至适应画布。

translateX(step)

x方向进行平移,step:要平移的像素

translateY(step)

diff --git a/web/src/pages/Doc/zh/watermark/index.md b/web/src/pages/Doc/zh/watermark/index.md index b4831109..46131553 100644 --- a/web/src/pages/Doc/zh/watermark/index.md +++ b/web/src/pages/Doc/zh/watermark/index.md @@ -10,7 +10,8 @@ ```js import MindMap from 'simple-mind-map' -import Watermark from 'simple-mind-map/src/Watermark.js' +import Watermark from 'simple-mind-map/src/plugins/Watermark.js' +// import Watermark from 'simple-mind-map/src/Watermark.js' v0.6.0以下版本使用该路径 MindMap.usePlugin(Watermark) ``` diff --git a/web/src/pages/Doc/zh/watermark/index.vue b/web/src/pages/Doc/zh/watermark/index.vue index a5bf7884..5b193f53 100644 --- a/web/src/pages/Doc/zh/watermark/index.vue +++ b/web/src/pages/Doc/zh/watermark/index.vue @@ -8,7 +8,8 @@

配置请参考MindMap类的实例化选项

注册

import MindMap from 'simple-mind-map'
-import Watermark from 'simple-mind-map/src/Watermark.js'
+import Watermark from 'simple-mind-map/src/plugins/Watermark.js'
+// import Watermark from 'simple-mind-map/src/Watermark.js' v0.6.0以下版本使用该路径
 
 MindMap.usePlugin(Watermark)
 
diff --git a/web/src/pages/Edit/components/Contextmenu.vue b/web/src/pages/Edit/components/Contextmenu.vue index 552fb0d9..db045bf5 100644 --- a/web/src/pages/Edit/components/Contextmenu.vue +++ b/web/src/pages/Edit/components/Contextmenu.vue @@ -65,6 +65,7 @@