Compare commits

...

26 Commits

Author SHA1 Message Date
街角小林
d7786cd449 update 2024-10-14 17:48:06 +08:00
街角小林
777a9d9047 打包0.12.0 2024-10-14 17:44:48 +08:00
街角小林
0dd7b0ed03 Feat:新增拦截关联线创建的实例化选项 2024-10-14 17:41:35 +08:00
街角小林
b661e8cc92 update 2024-10-14 17:30:01 +08:00
街角小林
1412fb5d09 打包0.12.0 2024-10-14 09:46:53 +08:00
街角小林
ec6a40e381 Feat:同时激活多个节点时编辑某个节点的文本只对该节点生效 2024-10-14 09:33:20 +08:00
街角小林
ca5075d50c 打包0.12.0 2024-10-12 17:35:44 +08:00
街角小林
fa1bf89e70 Feat:非富文本模式下节点文本编辑框增加类名,方便覆盖样式 2024-10-12 17:20:54 +08:00
街角小林
729533b3c1 Feat:mousedownEventPreventDefault选项支持控制节点的mousedown事件是否阻止默认事件 2024-10-12 11:12:03 +08:00
街角小林
6ffd26fd7f Feat:新增拖拽调整图片大小的最小值实例化选项 2024-10-12 10:09:59 +08:00
街角小林
48da6cb642 Feat:支持设置拖拽调整图片大小的最大值 2024-10-11 17:46:47 +08:00
街角小林
0055bbb39d Fix:修复缩放图片工具方法有误的问题;Feat:默认主题的最大图片宽度改为200;Feat:缩放节点图片按钮大小支持配置 2024-10-11 09:16:50 +08:00
街角小林
3349df2183 Fix:修复开启性能模式时拖动子节点在画布外的节点时报错的问题 2024-10-10 17:30:27 +08:00
街角小林
6c4800a6f0 update 2024-10-10 17:15:18 +08:00
街角小林
ca40204d43 Fix:修复某些场景(搜索全部替换等)下节点状态未更新的问题,节点实例新增了数据快照的属性 2024-10-10 11:16:24 +08:00
街角小林
cd28be4b01 Fix:修复非富文本模式下新建节点操作撤回也需要两次的问题 2024-10-10 10:27:40 +08:00
街角小林
af752ea761 Feat:新增添加和删除必要的css样式的方法;Fix:修复富文本模式下节点文本存在连续的数字或字母时导出图片换行失效的问题 2024-10-10 09:28:28 +08:00
街角小林
f2b72830b4 update 2024-10-09 19:14:53 +08:00
街角小林
f5cf7abd4f Feat:抽离库和demo中的主题文件为单独的包 2024-10-09 09:27:51 +08:00
街角小林
29695d1d7e Fix:修改派发节点激活事件的逻辑,去除不必要的判断,避免激活节点没有改变的情况下也会触发事件 2024-09-30 17:35:26 +08:00
街角小林
1510f7a135 打包Demo 2024-09-30 16:56:53 +08:00
街角小林
4b5a691713 Feat:支持拖拽调整节点宽度 2024-09-30 16:43:47 +08:00
街角小林
e9058ed67e Doc: 添加注释 2024-09-29 10:03:31 +08:00
街角小林
fc728ec018 Feat:剪贴板中同时存在文本和图片数据,默认只粘贴文本,可通过实例化选项修改 2024-09-27 17:34:13 +08:00
街角小林
7361df8697 Fix:修复搜索替换时搜索文本是替换文本的子串时搜索结果不正确的问题 2024-09-27 17:20:01 +08:00
街角小林
14e36aa699 Doc: update 2024-09-27 16:49:04 +08:00
137 changed files with 688 additions and 2581 deletions

View File

@@ -103,9 +103,7 @@ const mindMap = new MindMap({
# 微信交流群
一群已满,可以扫描如下二维码进入二群,如已过期,可以微信添加`wanglinguanfang`拉你入群。思维导图相关问题皆可在群里提问,不必私聊作者。
<img src="./qrcode.jpg" style="width: 300px" />
微信添加`wanglinguanfang`拉你入群。根据过往的经验大部分问题都可以通过查看issue列表或文档解决所以提问前请确保你已经阅读完了所有文档文档里没有的可在群里提问,不必私聊作者。
# star
@@ -122,6 +120,8 @@ const mindMap = new MindMap({
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡,你的支持是开发者持续维护的最大动力~
> 推荐使用支付宝,微信获取不到头像。转账请备注【思维导图】。
>
> 也可以通过购买付费插件来支持我们:[付费插件](https://wanglin2.github.io/mind-map-docs/plugins/about.html)。
<p>
<img src="./web/src/assets/img/alipay.jpg" style="width: 300px" />
@@ -477,4 +477,16 @@ const mindMap = new MindMap({
<img src="./web/src/assets/avatar/Joe.jpg" style="width: 50px;height: 50px;" />
<span>Joe</span>
</span>
<span>
<img src="./web/src/assets/avatar/default.png" style="width: 50px;height: 50px;" />
<span>中文网字计划-江夏尧</span>
</span>
<span>
<img src="./web/src/assets/avatar/梁辉.jpg" style="width: 50px;height: 50px;" />
<span>梁辉</span>
</span>
<span>
<img src="./web/src/assets/avatar/海云.jpg" style="width: 50px;height: 50px;" />
<span>海云</span>
</span>
</p>

File diff suppressed because one or more lines are too long

BIN
dist/img/classic10.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
dist/img/classic11.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
dist/img/classic12.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
dist/img/classic13.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

BIN
dist/img/classic14.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
dist/img/classic15.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
dist/img/classic8.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
dist/img/classic9.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
dist/img/dark5.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
dist/img/dark6.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
dist/img/dark7.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

2
dist/js/app.js vendored

File diff suppressed because one or more lines are too long

69
dist/js/chunk-46ea317e.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -9,7 +9,7 @@
})
} catch (error) {
console.log(error)
}</script><link href="dist/css/chunk-vendors.css?9c8ee1f3de5ddc8a450e" rel="stylesheet"><link href="dist/css/app.css?9c8ee1f3de5ddc8a450e" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script>const getDataFromBackend = () => {
}</script><link href="dist/css/chunk-vendors.css?63f5fae2a1a38e74b08f" rel="stylesheet"><link href="dist/css/app.css?63f5fae2a1a38e74b08f" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script>const getDataFromBackend = () => {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve({
@@ -74,4 +74,4 @@
// 可以通过window.$bus.$on()来监听应用的一些事件
// 实例化页面
window.initApp()
}</script><script src="dist/js/chunk-vendors.js?9c8ee1f3de5ddc8a450e"></script><script src="dist/js/app.js?9c8ee1f3de5ddc8a450e"></script></body></html>
}</script><script src="dist/js/chunk-vendors.js?63f5fae2a1a38e74b08f"></script><script src="dist/js/app.js?63f5fae2a1a38e74b08f"></script></body></html>

View File

@@ -22,16 +22,14 @@ import xmind from './src/parse/xmind.js'
import markdown from './src/parse/markdown.js'
import icons from './src/svg/icons.js'
import * as constants from './src/constants/constant.js'
import themes from './src/themes/index.js'
import * as defaultTheme from './src/themes/default.js'
import * as defaultTheme from './src/theme/default.js'
MindMap.xmind = xmind
MindMap.markdown = markdown
MindMap.iconList = icons.nodeIconList
MindMap.constants = constants
MindMap.themes = themes
MindMap.defaultTheme = defaultTheme
MindMap.version = '0.11.2'
MindMap.version = '0.12.0'
MindMap.usePlugin(MiniMap)
.usePlugin(Watermark)

View File

@@ -2,7 +2,7 @@ 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 theme from './src/theme'
import Style from './src/core/render/node/Style'
import KeyCommand from './src/core/command/KeyCommand'
import Command from './src/core/command/Command'
@@ -24,7 +24,7 @@ import {
} from './src/utils'
import defaultTheme, {
checkIsNodeSizeIndependenceConfig
} from './src/themes/default'
} from './src/theme/default'
import { defaultOpt } from './src/constants/defaultOptions'
// 思维导图
@@ -52,9 +52,9 @@ class MindMap {
this.initWidth = this.width
this.initHeight = this.height
// 添加css
// 必要的css样式
this.cssEl = null
this.addCss()
this.cssTextMap = {} // 该样式在实例化时会动态添加到页面同时导出为svg时也会添加到svg源码中
// 画布
this.initContainer()
@@ -98,6 +98,9 @@ class MindMap {
this.initPlugin(plugin)
})
// 添加必要的css样式
this.addCss()
// 初始渲染
this.render(this.opt.fit ? () => this.view.fit() : () => {})
setTimeout(() => {
@@ -170,17 +173,46 @@ class MindMap {
this.otherDraw.clear()
}
// 追加必要的css样式
// 该样式在实例化时会动态添加到页面同时导出为svg时也会添加到svg源码中
appendCss(key, str) {
this.cssTextMap[key] = str
this.removeCss()
this.addCss()
}
// 移除追加的css样式
removeAppendCss(key) {
if (this.cssTextMap[key]) {
delete this.cssTextMap[key]
this.removeCss()
this.addCss()
}
}
// 拼接必要的css样式
joinCss() {
return (
cssContent +
Object.keys(this.cssTextMap)
.map(key => {
return this.cssTextMap[key]
})
.join('\n')
)
}
// 添加必要的css样式到页面
addCss() {
this.cssEl = document.createElement('style')
this.cssEl.type = 'text/css'
this.cssEl.innerHTML = cssContent
this.cssEl.innerHTML = this.joinCss()
document.head.appendChild(this.cssEl)
}
// 移除css
removeCss() {
document.head.removeChild(this.cssEl)
if (this.cssEl) document.head.removeChild(this.cssEl)
}
// 渲染,部分渲染
@@ -254,7 +286,10 @@ class MindMap {
// 设置主题
initTheme() {
// 合并主题配置
this.themeConfig = mergeTheme(theme[this.opt.theme], this.opt.themeConfig)
this.themeConfig = mergeTheme(
theme[this.opt.theme] || theme.default,
this.opt.themeConfig
)
// 设置背景样式
Style.setBackgroundStyle(this.el, this.themeConfig)
}
@@ -511,7 +546,7 @@ class MindMap {
this.watermark.isInExport = false
}
// 添加必要的样式
;[cssContent, ...cssTextList].forEach(s => {
;[this.joinCss(), ...cssTextList].forEach(s => {
clone.add(SVG(`<style>${s}</style>`))
})
// 附加内容
@@ -645,5 +680,11 @@ MindMap.defineTheme = (name, config = {}) => {
}
theme[name] = mergeTheme(defaultTheme, config)
}
// 移除主题
MindMap.removeTheme = name => {
if (theme[name]) {
theme[name] = null
}
}
export default MindMap

View File

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

View File

@@ -1,167 +1,3 @@
// 主题列表
export const themeList = [
{
name: '默认',
value: 'default',
dark: false
},
{
name: '暗色2',
value: 'dark2',
dark: true
},
{
name: '天清绿',
value: 'skyGreen',
dark: false
},
{
name: '脑图经典2',
value: 'classic2',
dark: false
},
{
name: '脑图经典3',
value: 'classic3',
dark: false
},
{
name: '经典绿',
value: 'classicGreen',
dark: false
},
{
name: '经典蓝',
value: 'classicBlue',
dark: false
},
{
name: '天空蓝',
value: 'blueSky',
dark: false
},
{
name: '脑残粉',
value: 'brainImpairedPink',
dark: false
},
{
name: '暗色',
value: 'dark',
dark: true
},
{
name: '泥土黄',
value: 'earthYellow',
dark: false
},
{
name: '清新绿',
value: 'freshGreen',
dark: false
},
{
name: '清新红',
value: 'freshRed',
dark: false
},
{
name: '浪漫紫',
value: 'romanticPurple',
dark: false
},
{
name: '粉红葡萄',
value: 'pinkGrape',
dark: false
},
{
name: '薄荷',
value: 'mint',
dark: false
},
{
name: '金色vip',
value: 'gold',
dark: false
},
{
name: '活力橙',
value: 'vitalityOrange',
dark: false
},
{
name: '绿叶',
value: 'greenLeaf',
dark: false
},
{
name: '脑图经典',
value: 'classic',
dark: true
},
{
name: '脑图经典4',
value: 'classic4',
dark: false
},
{
name: '小黄人',
value: 'minions',
dark: false
},
{
name: '简约黑',
value: 'simpleBlack',
dark: false
},
{
name: '课程绿',
value: 'courseGreen',
dark: false
},
{
name: '咖啡',
value: 'coffee',
dark: false
},
{
name: '红色精神',
value: 'redSpirit',
dark: false
},
{
name: '黑色幽默',
value: 'blackHumour',
dark: true
},
{
name: '深夜办公室',
value: 'lateNightOffice',
dark: true
},
{
name: '黑金',
value: 'blackGold',
dark: true
},
{
name: '牛油果',
value: 'avocado',
dark: false
},
{
name: '秋天',
value: 'autumn',
dark: false
},
{
name: '橙汁',
value: 'orangeJuice',
dark: true
}
]
// 常量
export const CONSTANTS = {
CHANGE_THEME: 'changeTheme',
@@ -330,7 +166,8 @@ export const nodeDataNoStylePropList = [
'number',
'range',
'customLeft',
'customTop'
'customTop',
'customTextWidth'
]
// 错误类型

View File

@@ -7,6 +7,8 @@ export const defaultOpt = {
el: null,
// 思维导图回显数据
data: null,
// 要恢复的视图数据一般通过mindMap.view.getTransformData()方法获取
viewData: null,
// 是否只读
readonly: false,
// 布局
@@ -247,6 +249,14 @@ export const defaultOpt = {
openRealtimeRenderOnNodeTextEdit: false,
// 默认会给容器元素el绑定mousedown事件并且会阻止其默认事件这会带来一定问题比如你聚焦在思维导图外的其他输入框点击画布就不会触发其失焦可以通过该选项关闭阻止。关闭后也会带来一定问题比如鼠标框选节点时可能会选中节点文字看你如何取舍
mousedownEventPreventDefault: true,
// 在激活上粘贴用户剪贴板中的数据时,如果同时存在文本和图片,那么只粘贴文本,忽略图片
onlyPasteTextWhenHasImgAndText: true,
// 是否允许拖拽调整节点的宽度实际上压缩的是节点里面文本内容的宽度当节点文本内容宽度压缩到最小时无法继续压缩。如果节点存在图片那么最小值以图片宽度和文本内容最小宽度的最大值为准目前该特性仅在两种情况下可用1.开启了富文本模式即注册了RichText插件2.自定义节点内容)
enableDragModifyNodeWidth: true,
// 当允许拖拽调整节点的宽度时,可以通过该选项设置节点文本内容允许压缩的最小宽度
minNodeTextModifyWidth: 20,
// 同minNodeTextModifyWidth最大值传-1代表不限制
maxNodeTextModifyWidth: -1,
// 【Select插件】
// 多选节点时鼠标移动到边缘时的画布移动偏移量
@@ -348,6 +358,8 @@ export const defaultOpt = {
},
// 是否允许调整关联线两个端点的位置
enableAdjustAssociativeLinePoints: true,
// 关联线连接即将完成时执行如果要阻止本次连接可以返回true函数接收一个参数node目标节点实例
beforeAssociativeLineConnection: null,
// 【TouchEvent插件】
// 禁止双指缩放你仍旧可以使用api进行缩放
@@ -428,5 +440,15 @@ export const defaultOpt = {
// 【NodeImgAdjust】插件
// 拦截节点图片的删除点击节点图片上的删除按钮删除图片前会调用该函数如果函数返回true则取消删除
beforeDeleteNodeImg: null
beforeDeleteNodeImg: null,
// 删除和调整两个按钮的大小
imgResizeBtnSize: 25,
// 最小允许缩放的尺寸,请传入>=0的数字
minImgResizeWidth: 50,
minImgResizeHeight: 50,
// 最大允许缩放的尺寸依据主题的配置即主题的imgMaxWidth和imgMaxHeight配置如果设置为false那么使用maxImgResizeWidth和maxImgResizeHeight选项
maxImgResizeWidthInheritTheme: false,
// 最大允许缩放的尺寸maxImgResizeWidthInheritTheme选项设置为false时生效不限制最大值可传递Infinity
maxImgResizeWidth: Infinity,
maxImgResizeHeight: Infinity
}

View File

@@ -36,7 +36,7 @@ import {
throttle
} from '../../utils'
import { shapeList } from './node/Shape'
import { lineStyleProps } from '../../themes/default'
import { lineStyleProps } from '../../theme/default'
import { CONSTANTS, ERROR_TYPES } from '../../constants/constant'
import { Polygon } from '@svgdotjs/svg.js'
@@ -102,7 +102,6 @@ class Render {
this.highlightBoxNode = null
this.highlightBoxNodeStyle = null
// 上一次节点激活数据
this.lastActiveNode = null
this.lastActiveNodeList = []
// 布局
this.setLayout()
@@ -125,7 +124,7 @@ class Render {
// 重新设置思维导图数据
setData(data) {
if (this.mindMap.richText) {
if (this.hasRichTextPlugin()) {
this.renderTree = data ? this.mindMap.richText.handleSetData(data) : null
} else {
this.renderTree = data
@@ -435,13 +434,11 @@ class Render {
// 派发节点激活事件
emitNodeActiveEvent(node = null, activeNodeList = [...this.activeNodeList]) {
let isChange = false
isChange = this.lastActiveNode !== node
if (!isChange) {
isChange = !checkNodeListIsEqual(this.lastActiveNodeList, activeNodeList)
}
const isChange = !checkNodeListIsEqual(
this.lastActiveNodeList,
activeNodeList
)
if (!isChange) return
this.lastActiveNode = node
this.lastActiveNodeList = [...activeNodeList]
this.mindMap.batchExecution.push('emitNodeActiveEvent', () => {
this.mindMap.emit('node_active', node, activeNodeList)
@@ -549,7 +546,7 @@ class Render {
}
// 触发一次保存,因为修改了渲染树的数据
if (
this.mindMap.richText &&
this.hasRichTextPlugin() &&
[CONSTANTS.CHANGE_THEME, CONSTANTS.SET_DATA].includes(source)
) {
this.mindMap.command.addHistory()
@@ -563,7 +560,7 @@ class Render {
// 给当前被收起来的节点数据添加文本复位标志
resetUnExpandNodeStyle() {
if (!this.renderTree) return
if (!this.renderTree || !this.hasRichTextPlugin()) return
walk(this.renderTree, null, node => {
if (!node.data.expand) {
walk(node, null, node2 => {
@@ -740,7 +737,7 @@ class Render {
} = this.mindMap.opt
const list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
const handleMultiNodes = list.length > 1
const isRichText = !!this.mindMap.richText
const isRichText = this.hasRichTextPlugin()
const { focusNewNode, inserting } = this.getNewNodeBehavior(
openEdit,
handleMultiNodes
@@ -748,9 +745,9 @@ class Render {
const params = {
expand: true,
richText: isRichText,
resetRichText: isRichText,
isActive: focusNewNode // 如果同时对多个节点插入子节点,那么需要把新增的节点设为激活状态。如果不进入编辑状态,那么也需要手动设为激活状态
}
if (isRichText) params.resetRichText = isRichText
// 动态指定的子节点数据也需要添加相关属性
appointChildren = addDataToAppointNodes(appointChildren, {
...params
@@ -795,14 +792,14 @@ class Render {
}
this.textEdit.hideEditTextBox()
const list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
const isRichText = !!this.mindMap.richText
const isRichText = this.hasRichTextPlugin()
const { focusNewNode } = this.getNewNodeBehavior(false, true)
const params = {
expand: true,
richText: isRichText,
resetRichText: isRichText,
isActive: focusNewNode
}
if (isRichText) params.resetRichText = isRichText
nodeList = addDataToAppointNodes(nodeList, params)
list.forEach(node => {
if (node.isGeneralization || node.isRoot) {
@@ -838,7 +835,7 @@ class Render {
} = this.mindMap.opt
const list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
const handleMultiNodes = list.length > 1
const isRichText = !!this.mindMap.richText
const isRichText = this.hasRichTextPlugin()
const { focusNewNode, inserting } = this.getNewNodeBehavior(
openEdit,
handleMultiNodes
@@ -846,9 +843,9 @@ class Render {
const params = {
expand: true,
richText: isRichText,
resetRichText: isRichText,
isActive: focusNewNode
}
if (isRichText) params.resetRichText = isRichText
// 动态指定的子节点数据也需要添加相关属性
appointChildren = addDataToAppointNodes(appointChildren, {
...params
@@ -895,14 +892,14 @@ class Render {
}
this.textEdit.hideEditTextBox()
const list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
const isRichText = !!this.mindMap.richText
const isRichText = this.hasRichTextPlugin()
const { focusNewNode } = this.getNewNodeBehavior(false, true)
const params = {
expand: true,
richText: isRichText,
resetRichText: isRichText,
isActive: focusNewNode
}
if (isRichText) params.resetRichText = isRichText
childList = addDataToAppointNodes(childList, params)
list.forEach(node => {
if (node.isGeneralization) {
@@ -937,7 +934,7 @@ class Render {
} = this.mindMap.opt
const list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
const handleMultiNodes = list.length > 1
const isRichText = !!this.mindMap.richText
const isRichText = this.hasRichTextPlugin()
const { focusNewNode, inserting } = this.getNewNodeBehavior(
openEdit,
handleMultiNodes
@@ -945,9 +942,9 @@ class Render {
const params = {
expand: true,
richText: isRichText,
resetRichText: isRichText,
isActive: focusNewNode
}
if (isRichText) params.resetRichText = isRichText
list.forEach(node => {
if (node.isGeneralization || node.isRoot) {
return
@@ -966,9 +963,11 @@ class Render {
},
children: [node.nodeData]
}
node.setData({
resetRichText: true
})
if (isRichText) {
node.setData({
resetRichText: true
})
}
const parent = node.parent
// 获取当前节点所在位置
const index = getNodeDataIndex(node)
@@ -1058,7 +1057,7 @@ class Render {
}
})
// 如果是富文本,那么还要处理富文本内容
if (hasCustomStyles && this.mindMap.richText) {
if (hasCustomStyles && this.hasRichTextPlugin()) {
nodeData.resetRichText = true
nodeData.text = removeRichTextStyes(nodeData.text)
}
@@ -1156,7 +1155,8 @@ class Render {
errorHandler,
handleIsSplitByWrapOnPasteCreateNewNode,
handleNodePasteImg,
disabledClipboard
disabledClipboard,
onlyPasteTextWhenHasImgAndText
} = this.mindMap.opt
// 读取剪贴板的文字和图片
let text = ''
@@ -1261,7 +1261,7 @@ class Render {
}
}
// 存在图片,则添加到当前激活节点
if (img) {
if (img && (!text || !onlyPasteTextWhenHasImgAndText)) {
try {
let imgData = null
// 自定义图片处理函数
@@ -1341,7 +1341,7 @@ class Render {
// 如果是富文本模式,那么某些层级变化需要更新样式
checkNodeLayerChange(node, toNode, toNodeIsParent = false) {
if (this.mindMap.richText) {
if (this.hasRichTextPlugin()) {
// 如果设置了自定义样式那么不需要更新
if (this.mindMap.richText.checkNodeHasCustomRichTextStyle(node)) {
return
@@ -1568,7 +1568,7 @@ class Render {
const newData = simpleDeepClone(item)
createUidForAppointNodes([newData], true, node => {
// 可能跨层级复制,那么富文本样式需要更新
if (this.mindMap.richText) {
if (this.hasRichTextPlugin()) {
// 如果设置了自定义样式那么不需要更新
if (
this.mindMap.richText.checkNodeHasCustomRichTextStyle(node.data)
@@ -1591,7 +1591,7 @@ class Render {
[prop]: value
}
// 如果开启了富文本,则需要应用到富文本上
if (this.mindMap.richText) {
if (this.hasRichTextPlugin()) {
this.mindMap.richText.setNotActiveNodeStyle(node, {
[prop]: value
})
@@ -1607,7 +1607,7 @@ class Render {
setNodeStyles(node, style) {
let data = { ...style }
// 如果开启了富文本,则需要应用到富文本上
if (this.mindMap.richText) {
if (this.hasRichTextPlugin()) {
this.mindMap.richText.setNotActiveNodeStyle(node, style)
}
this.setNodeDataRender(node, data)
@@ -1802,7 +1802,7 @@ class Render {
// 设置节点公式
insertFormula(formula, appointNodes = []) {
// 只在富文本模式下可用并且需要注册Formula插件
if (!this.mindMap.richText || !this.mindMap.formula) return
if (!this.hasRichTextPlugin() || !this.mindMap.formula) return
appointNodes = formatDataToArray(appointNodes)
const list = appointNodes.length > 0 ? appointNodes : this.activeNodeList
list.forEach(node => {
@@ -1824,7 +1824,7 @@ class Render {
})
const list = parseAddGeneralizationNodeList(nodeList)
if (list.length <= 0) return
const isRichText = !!this.mindMap.richText
const isRichText = this.hasRichTextPlugin()
const { focusNewNode, inserting } = this.getNewNodeBehavior(
openEdit,
list.length > 1
@@ -1839,9 +1839,9 @@ class Render {
range: item.range || null,
uid: createUid(),
richText: isRichText,
resetRichText: isRichText,
isActive: focusNewNode
}
if (isRichText) newData.resetRichText = isRichText
let generalization = item.node.getData('generalization')
generalization = generalization
? Array.isArray(generalization)
@@ -2171,6 +2171,11 @@ class Render {
if (!this.highlightBoxNode) return
this.highlightBoxNode.remove()
}
// 是否存在富文本插件
hasRichTextPlugin() {
return !!this.mindMap.richText
}
}
export default Render

View File

@@ -216,6 +216,7 @@ export default class TextEdit {
this.registerTmpShortcut()
if (!this.textEditNode) {
this.textEditNode = document.createElement('div')
this.textEditNode.classList.add('smm-node-edit-wrap')
this.textEditNode.style.cssText = `position:fixed;box-sizing: border-box;background-color:#fff;box-shadow: 0 0 20px rgba(0,0,0,.5);padding: ${this.textNodePaddingY}px ${this.textNodePaddingX}px;margin-left: -5px;margin-top: -3px;outline: none; word-break: break-all;`
this.textEditNode.setAttribute('contenteditable', true)
this.textEditNode.addEventListener('keyup', e => {
@@ -333,15 +334,16 @@ export default class TextEdit {
if (!this.showTextEdit) {
return
}
this.renderer.activeNodeList.forEach(node => {
let str = this.getEditText()
this.mindMap.execCommand('SET_NODE_TEXT', node, str)
if (node.isGeneralization) {
// 概要节点
node.generalizationBelongNode.updateGeneralization()
}
this.mindMap.render()
})
this.mindMap.execCommand(
'SET_NODE_TEXT',
this.currentNode,
this.getEditText()
)
if (this.currentNode.isGeneralization) {
// 概要节点
this.currentNode.generalizationBelongNode.updateGeneralization()
}
this.mindMap.render()
const currentNode = this.currentNode
this.currentNode = null
this.textEditNode.style.display = 'none'

View File

@@ -6,6 +6,7 @@ import nodeExpandBtnMethods from './nodeExpandBtn'
import nodeCommandWrapsMethods from './nodeCommandWraps'
import nodeCreateContentsMethods from './nodeCreateContents'
import nodeExpandBtnPlaceholderRectMethods from './nodeExpandBtnPlaceholderRect'
import nodeModifyWidthMethods from './nodeModifyWidth'
import nodeCooperateMethods from './nodeCooperate'
import { CONSTANTS } from '../../../constants/constant'
import {
@@ -22,6 +23,8 @@ class MindMapNode {
this.opt = opt
// 节点数据
this.nodeData = this.handleData(opt.data || {})
// 保存本次更新时的节点数据快照
this.nodeDataSnapshot = ''
// uid
this.uid = opt.uid
// 控制实例
@@ -54,6 +57,8 @@ class MindMapNode {
this.width = opt.width || 0
// 节点高
this.height = opt.height || 0
// 自定义文本的宽度
this.customTextWidth = opt.data.data.customTextWidth || undefined
// left
this._left = opt.left || 0
// top
@@ -150,10 +155,15 @@ class MindMapNode {
proto[item] = nodeCooperateMethods[item]
})
}
// 拖拽调整节点宽度
Object.keys(nodeModifyWidthMethods).forEach(item => {
proto[item] = nodeModifyWidthMethods[item]
})
proto.bindEvent = true
}
// 初始化
this.getSize()
this.initDragHandle()
}
// 支持自定义位置
@@ -197,7 +207,8 @@ class MindMapNode {
}
// 创建节点的各个内容对象数据
createNodeData() {
// recreateTypes[] custom、image、icon、text、hyperlink、tag、note、attachment、numbers、prefix、postfix
createNodeData(recreateTypes) {
// 自定义节点内容
let {
isUseCustomNodeContent,
@@ -205,7 +216,39 @@ class MindMapNode {
createNodePrefixContent,
createNodePostfixContent
} = this.mindMap.opt
if (isUseCustomNodeContent && customCreateNodeContent) {
// 需要创建的内容类型
const typeList = [
'custom',
'image',
'icon',
'text',
'hyperlink',
'tag',
'note',
'attachment',
'numbers',
'prefix',
'postfix'
]
const createTypes = {}
if (Array.isArray(recreateTypes)) {
// 重新创建指定的内容类型
typeList.forEach(item => {
if (recreateTypes.includes(item)) {
createTypes[item] = true
}
})
} else {
// 创建所有类型
typeList.forEach(item => {
createTypes[item] = true
})
}
if (
isUseCustomNodeContent &&
customCreateNodeContent &&
createTypes.custom
) {
this._customNodeContent = customCreateNodeContent(this)
}
// 如果没有返回内容,那么还是使用内置的节点内容
@@ -213,37 +256,42 @@ class MindMapNode {
addXmlns(this._customNodeContent)
return
}
this._imgData = this.createImgNode()
this._iconData = this.createIconNode()
this._textData = this.createTextNode()
this._hyperlinkData = this.createHyperlinkNode()
this._tagData = this.createTagNode()
this._noteData = this.createNoteNode()
this._attachmentData = this.createAttachmentNode()
if (this.mindMap.numbers) {
if (createTypes.image) this._imgData = this.createImgNode()
if (createTypes.icon) this._iconData = this.createIconNode()
if (createTypes.text) this._textData = this.createTextNode()
if (createTypes.hyperlink) this._hyperlinkData = this.createHyperlinkNode()
if (createTypes.tag) this._tagData = this.createTagNode()
if (createTypes.note) this._noteData = this.createNoteNode()
if (createTypes.attachment)
this._attachmentData = this.createAttachmentNode()
if (this.mindMap.numbers && createTypes.numbers) {
this._numberData = this.mindMap.numbers.createNumberContent(this)
}
this._prefixData = createNodePrefixContent
? createNodePrefixContent(this)
: null
if (this._prefixData && this._prefixData.el) {
addXmlns(this._prefixData.el)
if (createTypes.prefix) {
this._prefixData = createNodePrefixContent
? createNodePrefixContent(this)
: null
if (this._prefixData && this._prefixData.el) {
addXmlns(this._prefixData.el)
}
}
this._postfixData = createNodePostfixContent
? createNodePostfixContent(this)
: null
if (this._postfixData && this._postfixData.el) {
addXmlns(this._postfixData.el)
if (createTypes.postfix) {
this._postfixData = createNodePostfixContent
? createNodePostfixContent(this)
: null
if (this._postfixData && this._postfixData.el) {
addXmlns(this._postfixData.el)
}
}
}
// 计算节点的宽高
getSize() {
getSize(recreateTypes) {
this.customLeft = this.getData('customLeft') || undefined
this.customTop = this.getData('customTop') || undefined
// 这里不要更新概要,不然即使概要没修改,每次也会重新渲染
// this.updateGeneralization()
this.createNodeData()
this.createNodeData(recreateTypes)
let { width, height } = this.getNodeRect()
// 判断节点尺寸是否有变化
let changed = this.width !== width || this.height !== height
@@ -258,7 +306,7 @@ class MindMapNode {
if (this.isUseCustomNodeContent()) {
let rect = this.measureCustomNodeContentSize(this._customNodeContent)
return {
width: rect.width,
width: this.hasCustomWidth() ? this.customTextWidth : rect.width,
height: rect.height
}
}
@@ -582,12 +630,15 @@ class MindMapNode {
this.active(e)
})
this.group.on('mousedown', e => {
e.preventDefault()
const {
readonly,
enableCtrlKeyNodeSelection,
useLeftKeySelectionRightKeyDrag
useLeftKeySelectionRightKeyDrag,
mousedownEventPreventDefault
} = this.mindMap.opt
if (mousedownEventPreventDefault) {
e.preventDefault()
}
// 只读模式不需要阻止冒泡
if (!readonly) {
if (this.isRoot) {
@@ -735,15 +786,20 @@ class MindMapNode {
}
}
}
// 更新拖拽手柄的显示与否
this.updateDragHandle()
// 更新概要
this.renderGeneralization(forceRender)
// 更新协同头像
if (this.updateUserListNode) this.updateUserListNode()
// 更新节点位置
let t = this.group.transform()
// 如果节点位置没有变化,则返回
if (this.left === t.translateX && this.top === t.translateY) return
this.group.translate(this.left - t.translateX, this.top - t.translateY)
// 保存一份当前节点数据快照
this.nodeDataSnapshot = JSON.stringify(this.getData())
// 节点位置变化才更新,因为即使值没有变化属性设置操作也是耗时的
if (this.left !== t.translateX || this.top !== t.translateY) {
this.group.translate(this.left - t.translateX, this.top - t.translateY)
}
}
// 获取节点相当于画布的位置
@@ -770,8 +826,8 @@ class MindMapNode {
}
// 重新渲染节点,即重新创建节点内容、计算节点大小、计算节点内容布局、更新展开收起按钮,概要及位置
reRender() {
let sizeChange = this.getSize()
reRender(recreateTypes) {
let sizeChange = this.getSize(recreateTypes)
this.layout()
this.update()
return sizeChange
@@ -794,6 +850,7 @@ class MindMapNode {
this.hideExpandBtn()
}
this.updateNodeActiveClass()
this.updateDragHandle()
}
}
@@ -917,7 +974,7 @@ class MindMapNode {
// 隐藏节点
hide() {
this.group.hide()
if (this.group) this.group.hide()
this.hideGeneralization()
if (this.parent) {
let index = this.parent.children.indexOf(this)
@@ -960,7 +1017,7 @@ class MindMapNode {
// 包括连接线和下级节点
setOpacity(val) {
// 自身及连线
this.group.opacity(val)
if (this.group) this.group.opacity(val)
this._lines.forEach(line => {
line.opacity(val)
})
@@ -999,13 +1056,13 @@ class MindMapNode {
// 被拖拽中
startDrag() {
this.isDrag = true
this.group.addClass('smm-node-dragging')
if (this.group) this.group.addClass('smm-node-dragging')
}
// 拖拽结束
endDrag() {
this.isDrag = false
this.group.removeClass('smm-node-dragging')
if (this.group) this.group.removeClass('smm-node-dragging')
}
// 连线
@@ -1248,7 +1305,7 @@ class MindMapNode {
// 获取节点的尺寸和位置信息,宽高是应用了缩放效果后的实际宽高,位置是相对于浏览器窗口左上角的位置
getRect() {
return this.group.rbox()
return this.group ? this.group.rbox() : null
}
// 获取节点的尺寸和位置信息,宽高是应用了缩放效果后的实际宽高,位置信息相对于画布
@@ -1297,6 +1354,30 @@ class MindMapNode {
createSvgTextNode(text = '') {
return new Text().text(text)
}
// 检查是否支持拖拽调整宽度
// 1.富文本模式
// 2.自定义节点内容
checkEnableDragModifyNodeWidth() {
const {
enableDragModifyNodeWidth,
isUseCustomNodeContent,
customCreateNodeContent
} = this.mindMap.opt
return (
enableDragModifyNodeWidth &&
(this.mindMap.richText ||
(isUseCustomNodeContent && customCreateNodeContent))
)
}
// 是否存在自定义宽度
hasCustomWidth() {
return (
this.checkEnableDragModifyNodeWidth() &&
this.customTextWidth !== undefined
)
}
}
export default MindMapNode

View File

@@ -115,9 +115,11 @@ function createIconNode() {
// 创建富文本节点
function createRichTextNode(specifyText) {
const hasCustomWidth = this.hasCustomWidth()
let text =
typeof specifyText === 'string' ? specifyText : this.getData('text')
const { textAutoWrapWidth, emptyTextMeasureHeightText } = this.mindMap.opt
let { textAutoWrapWidth, emptyTextMeasureHeightText } = this.mindMap.opt
textAutoWrapWidth = hasCustomWidth ? this.customTextWidth : textAutoWrapWidth
let g = new G()
// 重新设置富文本节点内容
let recoverText = false
@@ -172,6 +174,11 @@ function createRichTextNode(specifyText) {
el.classList.add('smm-richtext-node-wrap')
addXmlns(el)
el.style.maxWidth = textAutoWrapWidth + 'px'
if (hasCustomWidth) {
el.style.width = this.customTextWidth + 'px'
} else {
el.style.width = ''
}
let { width, height } = el.getBoundingClientRect()
// 如果文本为空,那么需要计算一个默认高度
if (height <= 0) {

View File

@@ -0,0 +1,151 @@
import { Rect } from '@svgdotjs/svg.js'
// 初始化拖拽
function initDragHandle() {
if (!this.checkEnableDragModifyNodeWidth()) {
return
}
// 拖拽手柄元素
this._dragHandleNodes = null
// 手柄元素的宽度
this.dragHandleWidth = 2
// 鼠标按下时的x坐标
this.dragHandleMousedownX = 0
// 鼠标是否处于按下状态
this.isDragHandleMousedown = false
// 当前拖拽的手柄序号
this.dragHandleIndex = 0
// 鼠标按下时记录当前的customTextWidth值
this.dragHandleMousedownCustomTextWidth = 0
// 鼠标按下时记录当前的手型样式
this.dragHandleMousedownBodyCursor = ''
// 鼠标按下时记录当前节点的left值
this.dragHandleMousedownLeft = 0
this.onDragMousemoveHandle = this.onDragMousemoveHandle.bind(this)
window.addEventListener('mousemove', this.onDragMousemoveHandle)
this.onDragMouseupHandle = this.onDragMouseupHandle.bind(this)
window.addEventListener('mouseup', this.onDragMouseupHandle)
this.mindMap.on('node_mouseup', this.onDragMouseupHandle)
}
// 鼠标移动事件
function onDragMousemoveHandle(e) {
if (!this.isDragHandleMousedown) return
e.stopPropagation()
e.preventDefault()
let {
minNodeTextModifyWidth,
maxNodeTextModifyWidth,
isUseCustomNodeContent,
customCreateNodeContent
} = this.mindMap.opt
const useCustomContent =
isUseCustomNodeContent && customCreateNodeContent && this._customNodeContent
document.body.style.cursor = 'ew-resize'
this.group.css({
cursor: 'ew-resize'
})
const { scaleX } = this.mindMap.draw.transform()
const ox = e.clientX - this.dragHandleMousedownX
let newWidth =
this.dragHandleMousedownCustomTextWidth +
(this.dragHandleIndex === 0 ? -ox : ox) / scaleX
newWidth = Math.max(newWidth, minNodeTextModifyWidth)
if (maxNodeTextModifyWidth !== -1) {
newWidth = Math.min(newWidth, maxNodeTextModifyWidth)
}
// 如果存在图片,那么最小值需要考虑图片宽度
if (!useCustomContent && this.getData('image')) {
const imgSize = this.getImgShowSize()
if (
this._rectInfo.textContentWidth - this.customTextWidth + newWidth <=
imgSize[0]
) {
newWidth =
imgSize[0] + this.customTextWidth - this._rectInfo.textContentWidth
}
}
this.customTextWidth = newWidth
if (this.dragHandleIndex === 0) {
this.left = this.dragHandleMousedownLeft + ox / scaleX
}
// 自定义内容不重新渲染,交给开发者
this.reRender(useCustomContent ? [] : ['text'])
}
// 鼠标松开事件
function onDragMouseupHandle() {
if (!this.isDragHandleMousedown) return
document.body.style.cursor = this.dragHandleMousedownBodyCursor
this.group.css({
cursor: 'default'
})
this.isDragHandleMousedown = false
this.dragHandleMousedownX = 0
this.dragHandleIndex = 0
this.dragHandleMousedownCustomTextWidth = 0
this.setData({
customTextWidth: this.customTextWidth
})
this.mindMap.render()
this.mindMap.emit('dragModifyNodeWidthEnd', this)
}
// 插件拖拽手柄元素
function createDragHandleNode() {
const list = [new Rect(), new Rect()]
list.forEach((node, index) => {
node
.size(this.dragHandleWidth, this.height)
.fill({
color: 'transparent'
})
.css({
cursor: 'ew-resize'
})
node.on('mousedown', e => {
e.stopPropagation()
e.preventDefault()
this.dragHandleMousedownX = e.clientX
this.dragHandleIndex = index
this.dragHandleMousedownCustomTextWidth =
this.customTextWidth === undefined
? this._textData
? this._textData.width
: this.width
: this.customTextWidth
this.dragHandleMousedownBodyCursor = document.body.style.cursor
this.dragHandleMousedownLeft = this.left
this.isDragHandleMousedown = true
})
})
return list
}
// 更新拖拽按钮的显隐和位置尺寸
function updateDragHandle() {
if (!this.checkEnableDragModifyNodeWidth()) return
if (!this._dragHandleNodes) {
this._dragHandleNodes = this.createDragHandleNode()
}
if (this.getData('isActive')) {
this._dragHandleNodes.forEach(node => {
node.height(this.height)
this.group.add(node)
})
this._dragHandleNodes[1].x(this.width - this.dragHandleWidth)
} else {
this._dragHandleNodes.forEach(node => {
node.remove()
})
}
}
export default {
initDragHandle,
onDragMousemoveHandle,
onDragMouseupHandle,
createDragHandleNode,
updateDragHandle
}

View File

@@ -91,6 +91,18 @@ class Base {
}
}
// 节点节点数据是否发生了改变
checkIsNodeDataChange(lastData, curData) {
if (lastData) {
// 对比忽略激活状态和展开收起状态
lastData = typeof lastData === 'string' ? JSON.parse(lastData) : lastData
lastData.isActive = curData.isActive
lastData.expand = curData.expand
lastData = JSON.stringify(lastData)
}
return lastData !== JSON.stringify(curData)
}
// 创建节点实例
createNode(data, parent, isRoot, layerIndex, index, ancestors) {
// 编号
@@ -106,6 +118,7 @@ class Base {
// 数据上保存了节点引用,那么直接复用节点
if (data && data._node && !this.renderer.reRender) {
newNode = data._node
// 节点层级改变了
const isLayerTypeChange = this.checkIsLayerTypeChange(
newNode.layerIndex,
layerIndex
@@ -127,10 +140,17 @@ class Base {
newNumberStr
)
}
// 主题或主题配置改变了、节点层级改变了,需要重新渲染节点文本等情况需要重新计算节点大小和布局
const isNeedResizeSources = this.checkIsNeedResizeSources()
// 主题或主题配置改变了
const isResizeSource = this.checkIsNeedResizeSources()
// 节点数据改变了
const isNodeDataChange = this.checkIsNodeDataChange(
data._node.nodeDataSnapshot,
data.data
)
// 重新计算节点大小和布局
if (
isNeedResizeSources ||
isResizeSource ||
isNodeDataChange ||
isLayerTypeChange ||
newNode.getData('resetRichText') ||
isNumberChange
@@ -138,7 +158,7 @@ class Base {
newNode.getSize()
newNode.needLayout = true
}
this.checkGetGeneralizationChange(newNode, isNeedResizeSources)
this.checkGetGeneralizationChange(newNode, isResizeSource)
} else if (
(this.lru.has(uid) || this.renderer.lastNodeCache[uid]) &&
!this.renderer.reRender
@@ -150,6 +170,7 @@ class Base {
newNode = this.lru.get(uid) || this.renderer.lastNodeCache[uid]
// 保存该节点上一次的数据
const lastData = JSON.stringify(newNode.getData())
// 节点层级改变了
const isLayerTypeChange = this.checkIsLayerTypeChange(
newNode.layerIndex,
layerIndex
@@ -167,8 +188,8 @@ class Base {
data._node = newNode
// 主题或主题配置改变了需要重新计算节点大小和布局
const isResizeSource = this.checkIsNeedResizeSources()
// 主题或主题配置改变了、节点层级改变了,需要重新渲染节点文本,节点数据改变了等情况需要重新计算节点大小和布局
const isNodeDataChange = lastData !== JSON.stringify(data.data)
// 点数据改变了
const isNodeDataChange = this.checkIsNodeDataChange(lastData, data.data)
// 判断编号是否改变
let isNumberChange = false
if (hasNumberPlugin) {
@@ -177,6 +198,7 @@ class Base {
newNumberStr
)
}
// 重新计算节点大小和布局
if (
isResizeSource ||
isNodeDataChange ||

View File

@@ -446,6 +446,12 @@ class AssociativeLine {
// 完成创建连接线
completeCreateLine(node) {
if (this.creatingStartNode.uid === node.uid) return
const { beforeAssociativeLineConnection } = this.mindMap.opt
let stop = false
if (typeof beforeAssociativeLineConnection === 'function') {
stop = beforeAssociativeLineConnection(node)
}
if (stop) return
this.addLine(this.creatingStartNode, node)
if (this.overlapNode && this.overlapNode.getData('isActive')) {
this.mindMap.execCommand('SET_NODE_ACTIVE', this.overlapNode, false)

View File

@@ -93,7 +93,6 @@ class Drag extends Base {
) {
return
}
e.preventDefault()
this.isMousedown = true
// 记录鼠标按下时的节点
this.mousedownNode = node

View File

@@ -6,13 +6,18 @@ class NodeImgAdjust {
// 构造函数
constructor({ mindMap }) {
this.mindMap = mindMap
this.resizeBtnSize = 26 // 调整按钮的大小
this.handleEl = null // 自定义元素,用来渲染临时图片、调整按钮
this.isShowHandleEl = false // 自定义元素是否在显示中
this.node = null // 当前节点实例
this.img = null // 当前节点的图片节点
this.rect = null // 当前图片节点的尺寸信息
this.isMousedown = false // 当前是否是按住调整按钮状态
this.mousedownDrawTransform = null //鼠标按下时对当前画布的变换
this.mousedownOffset = {
// 鼠标按下时位置和图片右下角相差的距离
x: 0,
y: 0
}
this.currentImgWidth = 0 // 当前拖拽实时图片的大小
this.currentImgHeight = 0
this.isAdjusted = false // 是否是拖拽结束后的渲染期间
@@ -78,6 +83,7 @@ class NodeImgAdjust {
// 显示自定义元素
showHandleEl() {
if (this.isShowHandleEl) return
if (!this.handleEl) {
this.createResizeBtnEl()
}
@@ -116,6 +122,7 @@ class NodeImgAdjust {
// 创建调整按钮元素
createResizeBtnEl() {
const { imgResizeBtnSize } = this.mindMap.opt
// 容器元素
this.handleEl = document.createElement('div')
this.handleEl.style.cssText = `
@@ -134,8 +141,8 @@ class NodeImgAdjust {
bottom: 0;
pointer-events: auto;
background-color: rgba(0, 0, 0, 0.3);
width: ${this.resizeBtnSize}px;
height: ${this.resizeBtnSize}px;
width: ${imgResizeBtnSize}px;
height: ${imgResizeBtnSize}px;
display: flex;
justify-content: center;
align-items: center;
@@ -178,8 +185,8 @@ class NodeImgAdjust {
right: 0;top:0;color:#fff;
pointer-events: auto;
background-color: rgba(0, 0, 0, 0.3);
width: ${this.resizeBtnSize}px;
height: ${this.resizeBtnSize}px;
width: ${imgResizeBtnSize}px;
height: ${imgResizeBtnSize}px;
display: flex;
justify-content: center;
align-items: center;
@@ -207,10 +214,13 @@ class NodeImgAdjust {
}
// 鼠标按钮按下事件
onMousedown() {
onMousedown(e) {
this.isMousedown = true
this.mousedownDrawTransform = this.mindMap.draw.transform()
// 隐藏节点实际图片
this.hideNodeImage()
this.mousedownOffset.x = e.clientX - this.rect.x2
this.mousedownOffset.y = e.clientY - this.rect.y2
// 将节点图片渲染到自定义元素上
this.handleEl.style.backgroundImage = `url(${this.node.getData('image')})`
}
@@ -219,13 +229,48 @@ class NodeImgAdjust {
onMousemove(e) {
if (!this.isMousedown) return
e.preventDefault()
// 计算当前拖拽位置对应的图片的实时大小
let { width: imageOriginWidth, height: imageOriginHeight } =
const { scaleX, scaleY } = this.mousedownDrawTransform
// 图片原始大小
const { width: imageOriginWidth, height: imageOriginHeight } =
this.node.getData('imageSize')
let newWidth = e.clientX - this.rect.x
let newHeight = e.clientY - this.rect.y
if (newWidth <= 0 || newHeight <= 0) return
let [actWidth, actHeight] = resizeImgSizeByOriginRatio(
let {
minImgResizeWidth,
minImgResizeHeight,
maxImgResizeWidthInheritTheme,
maxImgResizeWidth,
maxImgResizeHeight
} = this.mindMap.opt
// 主题设置的最小图片宽高
const minRatio = minImgResizeWidth / minImgResizeHeight
const oRatio = imageOriginWidth / imageOriginHeight
if (minRatio > oRatio) {
// 如果最小值比例大于图片原始比例,那么要调整高度最小值
minImgResizeHeight = minImgResizeWidth / oRatio
} else {
// 否则调整宽度最小值
minImgResizeWidth = minImgResizeHeight * oRatio
}
// 主题设置的最大图片宽高
let imgMaxWidth, imgMaxHeight
if (maxImgResizeWidthInheritTheme) {
imgMaxWidth = this.mindMap.getThemeConfig('imgMaxWidth')
imgMaxHeight = this.mindMap.getThemeConfig('imgMaxHeight')
} else {
imgMaxWidth = maxImgResizeWidth
imgMaxHeight = maxImgResizeHeight
}
imgMaxWidth = imgMaxWidth * scaleX
imgMaxHeight = imgMaxHeight * scaleY
// 计算当前拖拽位置对应的图片的实时大小
let newWidth = Math.abs(e.clientX - this.rect.x - this.mousedownOffset.x)
let newHeight = Math.abs(e.clientY - this.rect.y - this.mousedownOffset.y)
// 限制最小值
if (newWidth < minImgResizeWidth) newWidth = minImgResizeWidth
if (newHeight < minImgResizeHeight) newHeight = minImgResizeHeight
// 限制最大值
if (newWidth > imgMaxWidth) newWidth = imgMaxWidth
if (newHeight > imgMaxHeight) newHeight = imgMaxHeight
const [actWidth, actHeight] = resizeImgSizeByOriginRatio(
imageOriginWidth,
imageOriginHeight,
newWidth,
@@ -244,17 +289,24 @@ class NodeImgAdjust {
// 隐藏自定义元素
this.hideHandleEl()
// 更新节点图片为新的大小
let { image, imageTitle } = this.node.getData()
let { scaleX, scaleY } = this.mindMap.draw.transform()
this.mindMap.execCommand('SET_NODE_IMAGE', this.node, {
url: image,
title: imageTitle,
width: this.currentImgWidth / scaleX,
height: this.currentImgHeight / scaleY,
custom: true // 代表自定义了图片大小
})
this.isAdjusted = true
const { image, imageTitle, imageSize } = this.node.getData()
const { scaleX, scaleY } = this.mousedownDrawTransform
const newWidth = this.currentImgWidth / scaleX
const newHeight = this.currentImgHeight / scaleY
if (newWidth !== imageSize.width || newHeight !== imageSize.height) {
this.mindMap.execCommand('SET_NODE_IMAGE', this.node, {
url: image,
title: imageTitle,
width: newWidth,
height: newHeight,
custom: true // 代表自定义了图片大小
})
this.isAdjusted = true
}
this.isMousedown = false
this.mousedownDrawTransform = null
this.mousedownOffset.x = 0
this.mousedownOffset.y = 0
}
// 渲染完成事件

View File

@@ -89,6 +89,18 @@ class RichText {
// 插入样式
appendCss() {
this.mindMap.appendCss(
'richText',
`
.smm-richtext-node-wrap {
word-break: break-all;
}
.smm-richtext-node-wrap p {
font-family: auto;
}
`
)
let cssText = `
.ql-editor {
overflow: hidden;
@@ -107,15 +119,6 @@ class RichText {
border: none;
}
.smm-richtext-node-wrap {
word-break: break-all;
}
.smm-richtext-node-wrap p {
font-family: auto;
}
.smm-richtext-node-edit-wrap p {
font-family: auto;
}
@@ -180,7 +183,7 @@ class RichText {
if (this.showTextEdit) {
return
}
const {
let {
richTextEditFakeInPlace,
customInnerElsAppendTo,
nodeTextEditZIndex,
@@ -188,6 +191,9 @@ class RichText {
selectTextOnEnterEditText,
transformRichTextOnEnterEdit
} = this.mindMap.opt
textAutoWrapWidth = node.hasCustomWidth()
? node.customTextWidth
: textAutoWrapWidth
this.node = node
this.isInserting = isInserting
if (!rect) rect = node._textData.node.node.getBoundingClientRect()
@@ -382,8 +388,7 @@ class RichText {
}
let html = this.getEditText()
html = this.sortHtmlNodeStyles(html)
let list =
nodes && nodes.length > 0 ? nodes : this.mindMap.renderer.activeNodeList
const list = nodes && nodes.length > 0 ? nodes : [this.node]
list.forEach(node => {
this.mindMap.execCommand('SET_NODE_TEXT', node, html, true)
// if (node.isGeneralization) {
@@ -534,6 +539,7 @@ class RichText {
// let style = this.getPasteTextStyle()
// return new Delta().insert(this.formatPasteText(node.data), style)
// })
// 剪贴板里只要存在文本就会走这里,所以当剪贴板里是纯文本,或文本+图片都可以监听到和拦截,但是只有纯图片时不会走这里,所以无法拦截
this.quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
let ops = []
let style = this.getPasteTextStyle()
@@ -549,7 +555,7 @@ class RichText {
delta.ops = ops
return delta
})
// 拦截图片的粘贴
// 拦截图片的粘贴,当剪贴板里是纯图片,或文本+图片都可以拦截到,但是带来的问题是文本+图片时里面的文本也无法粘贴
this.quill.root.addEventListener(
'paste',
e => {
@@ -860,6 +866,7 @@ class RichText {
this.transformAllNodesToNormalNode()
document.head.removeChild(this.styleEl)
this.unbindEvent()
this.mindMap.removeAppendCss('richText')
}
// 插件被卸载前做的事情

View File

@@ -224,9 +224,15 @@ class Search {
replaceText = String(replaceText)
let currentNode = this.matchNodeList[this.currentIndex]
if (!currentNode) return
let text = this.getReplacedText(currentNode, this.searchText, replaceText)
// 如果当前搜索文本是替换文本的子串,那么该节点还是符合搜索结果的
const keep = replaceText.includes(this.searchText)
const text = this.getReplacedText(currentNode, this.searchText, replaceText)
this.notResetSearchText = true
currentNode.setText(text, currentNode.getData('richText'), true)
if (keep) {
this.updateMatchNodeList(this.matchNodeList)
return
}
const newList = this.matchNodeList.filter(node => {
return currentNode !== node
})
@@ -249,25 +255,29 @@ class Search {
)
return
replaceText = String(replaceText)
// 如果当前搜索文本是替换文本的子串,那么该节点还是符合搜索结果的
const keep = replaceText.includes(this.searchText)
const hasRichTextPlugin = this.mindMap.renderer.hasRichTextPlugin()
this.matchNodeList.forEach(node => {
const text = this.getReplacedText(node, this.searchText, replaceText)
if (this.isNodeInstance(node)) {
this.mindMap.renderer.setNodeDataRender(
node,
{
text,
resetRichText: !!node.getData('richText')
},
true
)
const data = {
text
}
if (hasRichTextPlugin) data.resetRichText = !!node.getData('richText')
this.mindMap.renderer.setNodeDataRender(node, data, true)
} else {
node.data.text = text
node.data.resetRichText = !!node.data.richText
if (hasRichTextPlugin) node.data.resetRichText = !!node.data.richText
}
})
this.mindMap.render()
this.mindMap.command.addHistory()
this.endSearch()
if (keep) {
this.updateMatchNodeList(this.matchNodeList)
} else {
this.endSearch()
}
}
// 获取某个节点替换后的文本

View File

@@ -1,11 +1,10 @@
// 默认主题
export default {
// 节点内边距
paddingX: 15,
paddingY: 5,
// 图片显示的最大宽度
imgMaxWidth: 100,
imgMaxWidth: 200,
// 图片显示的最大高度
imgMaxHeight: 100,
// icon的大小

View File

@@ -0,0 +1,5 @@
import defaultTheme from './default'
export default {
default: defaultTheme
}

View File

@@ -1,44 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 秋天
export default mergeTheme(defaultTheme, {
// 背景颜色
backgroundColor: '#fff2df',
// 连线的颜色
lineColor: '#b0bc47',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: '#b0bc47',
// 根节点样式
root: {
fillColor: '#e68112',
color: '#fff',
borderColor: '#e68112',
borderWidth: 0,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: '#ffd683',
color: '#8c5416',
borderColor: '#b0bc47',
borderWidth: 2,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: '#8c5416'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: '#ffd683',
borderColor: '#b0bc47',
borderWidth: 2,
color: '#8c5416'
}
})

View File

@@ -1,44 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 牛油果
export default mergeTheme(defaultTheme, {
// 背景颜色
backgroundColor: '#e6f1de',
// 连线的颜色
lineColor: '#f5ffad',
lineWidth: 4,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: '#749336',
// 根节点样式
root: {
fillColor: '#94c143',
color: '#fff',
borderColor: '#94c143',
borderWidth: 0,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: '#cee498',
color: '#749336',
borderColor: '#aec668',
borderWidth: 2,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: '#749336'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: '#cee498',
borderColor: '#aec668',
borderWidth: 2,
color: '#749336'
}
})

View File

@@ -1,44 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 黑金
export default mergeTheme(defaultTheme, {
// 背景颜色
backgroundColor: 'rgb(18, 20, 20)',
// 连线的颜色
lineColor: 'rgb(205, 186, 156)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(245, 224, 191)',
// 根节点样式
root: {
fillColor: 'rgb(255, 208, 124)',
color: 'rgb(111, 61, 6)',
borderColor: '',
borderWidth: 0,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: 'rgb(66, 57, 46)',
color: 'rgb(225, 201, 158)',
borderColor: 'rgb(245, 224, 191)',
borderWidth: 2,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(231, 203, 155)'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: 'rgb(56, 45, 34)',
borderColor: 'rgb(104, 84, 61)',
borderWidth: 2,
color: 'rgb(242, 216, 176)'
}
})

View File

@@ -1,44 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 黑色幽默
export default mergeTheme(defaultTheme, {
// 背景颜色
backgroundColor: 'rgb(27, 31, 34)',
// 连线的颜色
lineColor: 'rgb(75, 81, 78)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(255, 119, 34)',
// 根节点样式
root: {
fillColor: 'rgb(36, 179, 96)',
color: '#fff',
borderColor: '',
borderWidth: 0,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: 'rgb(254, 199, 13)',
color: 'rgb(0, 0, 0)',
borderColor: '',
borderWidth: 0,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(204, 204, 204)'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: 'rgb(27, 31, 34)',
borderColor: 'rgb(255, 119, 34)',
borderWidth: 2,
color: 'rgb(204, 204, 204)'
}
})

View File

@@ -1,37 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 天空蓝
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(115, 161, 191)',
// 背景颜色
backgroundColor: 'rgb(251, 251, 251)',
// 概要连线的粗细
generalizationLineWidth: 1,
// 概要连线的颜色
generalizationLineColor: '#333',
// 根节点样式
root: {
fillColor: 'rgb(115, 161, 191)'
},
// 二级节点样式
second: {
fillColor: 'rgb(238, 243, 246)',
color: '#333',
borderColor: 'rgb(115, 161, 191)',
borderWidth: 1,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#333'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: '#333',
color: '#333'
}
})

View File

@@ -1,37 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 脑残粉
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(191, 115, 148)',
// 背景颜色
backgroundColor: 'rgb(251, 251, 251)',
// 概要连线的粗细
generalizationLineWidth: 1,
// 概要连线的颜色
generalizationLineColor: '#333',
// 根节点样式
root: {
fillColor: 'rgb(191, 115, 148)'
},
// 二级节点样式
second: {
fillColor: 'rgb(246, 238, 242)',
color: '#333',
borderColor: 'rgb(191, 115, 148)',
borderWidth: 1,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#333'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: '#333',
color: '#333'
}
})

View File

@@ -1,49 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 脑图经典
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: '#fff',
// 连线的粗细
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: '#fff',
// 背景颜色
backgroundColor: 'rgb(58, 65, 68)',
// 背景图片
backgroundImage:
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAIAAAACDbGyAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowQzg5QTQ0NDhENzgxMUUzOENGREE4QTg0RDgzRTZDNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDowQzg5QTQ0NThENzgxMUUzOENGREE4QTg0RDgzRTZDNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkMwOEQ1NDRGOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkMwOEQ1NDUwOEQ3NzExRTM4Q0ZEQThBODREODNFNkM3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+e9P33AAAACVJREFUeNpisXJ0YUACTAyoAMr/+eM7EGGRZ4FQ7BycEAZAgAEAHbEGtkoQm/wAAAAASUVORK5CYII=',
// 背景重复
backgroundRepeat: 'repeat',
backgroundSize: 'auto',
// 根节点样式
root: {
fillColor: 'rgb(233, 223, 152)',
color: '#333',
fontSize: 24,
borderRadius: 21
},
// 二级节点样式
second: {
fillColor: 'rgb(164, 197, 192)',
borderColor: 'transparent',
color: '#333',
fontSize: 16,
borderRadius: 10
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#fff',
fontWeight: 'bold'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: 'transparent',
color: '#333'
}
})

View File

@@ -1,43 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 经典2
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(51, 51, 51)',
// 连线的粗细
lineWidth: 2,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(51, 51, 51)',
// 背景颜色
backgroundColor: '#fff',
// 根节点样式
root: {
fillColor: 'rgb(18, 187, 55)',
color: '#fff',
fontSize: 24,
borderRadius: 10
},
// 二级节点样式
second: {
fillColor: 'rgb(241, 242, 241)',
borderColor: 'transparent',
color: '#1a1a1a',
fontSize: 18,
borderRadius: 10
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: '#1a1a1a'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: 'rgb(51, 51, 51)',
borderWidth: 2,
color: '#1a1a1a'
}
})

View File

@@ -1,46 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 经典3
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(94, 202, 110)',
// 连线的粗细
lineWidth: 2,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: '#1a1a1a',
// 背景颜色
backgroundColor: 'rgb(241, 241, 241)',
// 根节点样式
root: {
fillColor: 'rgb(255, 245, 214)',
color: '#1a1a1a',
fontSize: 24,
borderRadius: 10,
borderColor: 'rgb(249, 199, 84)',
borderWidth: 1
},
// 二级节点样式
second: {
fillColor: 'rgb(255, 245, 214)',
borderColor: 'rgb(249, 199, 84)',
borderWidth: 1,
color: '#1a1a1a',
fontSize: 18,
borderRadius: 10
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: '#1a1a1a'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: '#1a1a1a',
color: '#1a1a1a',
borderWidth: 2
}
})

View File

@@ -1,49 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 经典4
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(30, 53, 86)',
// 连线的粗细
lineWidth: 2,
// 概要连线的粗细
generalizationLineWidth: 2,
// 概要连线的颜色
generalizationLineColor: 'rgb(56, 123, 233)',
// 背景颜色
backgroundColor: 'rgb(241, 241, 241)',
// 根节点样式
root: {
fillColor: 'rgb(30, 53, 86)',
color: '#fff',
fontSize: 24,
borderRadius: 10,
borderColor: 'rgb(189, 197, 201)',
borderWidth: 2
},
// 二级节点样式
second: {
fillColor: 'rgb(169, 218, 218)',
borderColor: 'rgb(30, 53, 86)',
borderWidth: 2,
color: '#fff',
fontSize: 18,
borderRadius: 10
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(30, 53, 86)',
borderColor: 'rgb(30, 53, 86)',
borderWidth: 1,
marginY: 20
},
// 概要节点样式
generalization: {
fillColor: 'rgb(56, 123, 233)',
borderColor: 'rgb(56, 123, 233)',
color: '#fff',
borderWidth: 0
}
})

View File

@@ -1,40 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 经典蓝
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(51, 51, 51)',
// 连线的粗细
lineWidth: 2,
// 概要连线的粗细
generalizationLineWidth: 2,
// 概要连线的颜色
generalizationLineColor: 'rgb(51, 51, 51)',
// 背景颜色
backgroundColor: 'rgb(239, 248, 250)',
// 根节点样式
root: {
fillColor: 'rgb(255, 255, 255)',
color: '#222'
},
// 二级节点样式
second: {
fillColor: 'rgb(255, 255, 255)',
color: '#222',
borderColor: 'rgb(255, 255, 255)',
borderWidth: 1,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#333'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: 'rgb(51, 51, 51)',
color: '#333'
}
})

View File

@@ -1,39 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 经典绿
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(123, 199, 120)',
// 背景颜色
backgroundColor: 'rgb(236, 245, 231)',
// 概要连线的粗细
generalizationLineWidth: 2,
// 概要连线的颜色
generalizationLineColor: 'rgb(123, 199, 120)',
// 根节点样式
root: {
fillColor: 'rgb(253, 244, 217)',
color: '#222'
},
// 二级节点样式
second: {
fillColor: 'rgb(253, 244, 217)',
color: '#222',
borderColor: 'rgb(242, 200, 104)',
borderWidth: 1,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#333'
},
// 概要节点样式
generalization: {
fillColor: 'rgb(123, 199, 120)',
borderColor: 'transparent',
borderWidth: 2,
color: '#fff'
}
})

View File

@@ -1,42 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 咖啡
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(173, 123, 91)',
lineWidth: 4,
// 概要连线的粗细
generalizationLineWidth: 4,
// 概要连线的颜色
generalizationLineColor: 'rgb(173, 123, 91)',
// 根节点样式
root: {
fillColor: 'rgb(202, 117, 79)',
color: '#fff',
borderColor: '',
borderWidth: 0,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: 'rgb(245, 231, 216)',
color: 'rgb(125, 86, 42)',
borderColor: '',
borderWidth: 0,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(96, 71, 47)'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: 'rgb(255, 249, 239)',
borderColor: 'rgb(173, 123, 91)',
borderWidth: 2,
color: 'rgb(122, 83, 44)'
}
})

View File

@@ -1,42 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 课程绿
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(113, 195, 169)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(113, 195, 169)',
// 根节点样式
root: {
fillColor: 'rgb(16, 160, 121)',
color: '#fff',
borderColor: '',
borderWidth: 0,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: 'rgb(240, 252, 249)',
color: 'rgb(50, 113, 96)',
borderColor: 'rgb(113, 195, 169)',
borderWidth: 2,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(10, 59, 43)'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: 'rgb(246, 238, 211)',
borderColor: '',
borderWidth: 0,
color: 'rgb(173, 91, 12)'
}
})

View File

@@ -1,42 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 暗色
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(17, 68, 23)',
// 连线的粗细
lineWidth: 2,
// 概要连线的粗细
generalizationLineWidth: 2,
// 概要连线的颜色
generalizationLineColor: '#fff',
// 背景颜色
backgroundColor: 'rgb(15, 16, 17)',
// 根节点样式
root: {
fillColor: 'rgb(28, 178, 43)',
color: '#fff',
fontSize: 24,
borderRadius: 10
},
// 二级节点样式
second: {
fillColor: 'rgb(55, 56, 58)',
color: 'rgb(147,148,149)',
fontSize: 18,
borderRadius: 10,
borderWidth: 0
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(147, 148, 149)'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: 'transparent',
color: '#333'
}
})

View File

@@ -1,42 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 暗色2
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(75, 81, 78)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(255, 119, 34)',
// 背景颜色
backgroundColor: 'rgb(27, 31, 34)',
// 根节点样式
root: {
fillColor: 'rgb(36, 179, 96)',
color: '#fff',
borderColor: '',
borderWidth: 0
},
// 二级节点样式
second: {
fillColor: 'rgb(254, 199, 13)',
color: 'rgb(0, 0, 0)',
borderColor: '',
borderWidth: 0,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: 'rgb(204, 204, 204)'
},
// 概要节点样式
generalization: {
fillColor: 'transparent',
borderColor: 'rgb(255, 119, 34)',
borderWidth: 2,
color: 'rgb(204, 204, 204)'
}
})

View File

@@ -1,37 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 泥土黄
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(191, 147, 115)',
// 背景颜色
backgroundColor: 'rgb(251, 251, 251)',
// 概要连线的粗细
generalizationLineWidth: 1,
// 概要连线的颜色
generalizationLineColor: '#333',
// 根节点样式
root: {
fillColor: 'rgb(191, 147, 115)'
},
// 二级节点样式
second: {
fillColor: 'rgb(246, 242, 238)',
color: '#333',
borderColor: 'rgb(191, 147, 115)',
borderWidth: 1,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#333'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: '#333',
color: '#333'
}
})

View File

@@ -1,31 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 清新绿
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: '#333',
// 背景颜色
backgroundColor: '#d1f6ec',
// 概要连线的粗细
generalizationLineWidth: 1,
// 概要连线的颜色
generalizationLineColor: '#333',
// 根节点样式
root: {
fillColor: '#1fb27d'
},
// 二级节点样式
second: {
fillColor: '#fff',
color: '#565656',
borderColor: 'transparent',
borderWidth: 0
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: '#333',
color: '#333'
}
})

View File

@@ -1,37 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 清新红
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(191, 115, 115)',
// 背景颜色
backgroundColor: 'rgb(251, 251, 251)',
// 概要连线的粗细
generalizationLineWidth: 1,
// 概要连线的颜色
generalizationLineColor: '#333',
// 根节点样式
root: {
fillColor: 'rgb(191, 115, 115)'
},
// 二级节点样式
second: {
fillColor: 'rgb(246, 238, 238)',
color: '#333',
borderColor: 'rgb(191, 115, 115)',
borderWidth: 1,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#333'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: '#333',
color: '#333'
}
})

View File

@@ -1,41 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 金色vip
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(51, 56, 62)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(127, 93, 64)',
// 背景颜色
backgroundColor: '#fff',
// 根节点样式
root: {
fillColor: 'rgb(51, 56, 62)',
color: 'rgb(247, 208, 160)',
borderColor: '',
borderWidth: 0
},
// 二级节点样式
second: {
fillColor: 'rgb(239, 209, 176)',
color: 'rgb(81, 58, 42)',
borderColor: '',
borderWidth: 0,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#222'
},
// 概要节点样式
generalization: {
fillColor: 'rgb(127, 93, 64)',
borderColor: 'transparent',
color: 'rgb(255, 214, 175)'
}
})

View File

@@ -1,42 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 绿叶
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(40, 193, 84)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(251, 158, 0)',
// 背景颜色
backgroundColor: 'rgb(238, 255, 243)',
// 根节点样式
root: {
fillColor: 'rgb(25, 193, 73)',
color: '#fff',
borderColor: '',
borderWidth: 0
},
// 二级节点样式
second: {
fillColor: '#fff',
color: 'rgb(69, 149, 96)',
borderColor: '',
borderWidth: 0,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#222'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: 'rgb(251, 158, 0)',
borderWidth: 2,
color: 'rgb(51, 51, 51)'
}
})

View File

@@ -1,67 +0,0 @@
import defaultTheme from './default'
import freshGreen from './freshGreen'
import blueSky from './blueSky'
import brainImpairedPink from './brainImpairedPink'
import romanticPurple from './romanticPurple'
import freshRed from './freshRed'
import earthYellow from './earthYellow'
import classic from './classic'
import classic2 from './classic2'
import classic3 from './classic3'
import classic4 from './classic4'
import dark from './dark'
import classicGreen from './classicGreen'
import classicBlue from './classicBlue'
import minions from './minions'
import pinkGrape from './pinkGrape'
import mint from './mint'
import gold from './gold'
import vitalityOrange from './vitalityOrange'
import greenLeaf from './greenLeaf'
import dark2 from './dark2'
import skyGreen from './skyGreen'
import simpleBlack from './simpleBlack'
import courseGreen from './courseGreen'
import coffee from './coffee'
import redSpirit from './redSpirit'
import blackHumour from './blackHumour'
import lateNightOffice from './lateNightOffice'
import blackGold from './blackGold'
import avocado from './avocado'
import autumn from './autumn'
import orangeJuice from './orangeJuice'
export default {
default: defaultTheme,
freshGreen,
blueSky,
brainImpairedPink,
romanticPurple,
freshRed,
earthYellow,
classic,
classic2,
classic3,
classic4,
dark,
classicGreen,
classicBlue,
minions,
pinkGrape,
mint,
gold,
vitalityOrange,
greenLeaf,
dark2,
skyGreen,
simpleBlack,
courseGreen,
coffee,
redSpirit,
blackHumour,
lateNightOffice,
blackGold,
avocado,
autumn,
orangeJuice
}

View File

@@ -1,44 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 深夜办公室
export default mergeTheme(defaultTheme, {
// 背景颜色
backgroundColor: 'rgb(32, 37, 49)',
// 连线的颜色
lineColor: 'rgb(137, 167, 196)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(255, 119, 34)',
// 根节点样式
root: {
fillColor: 'rgb(23, 153, 243)',
color: 'rgb(255, 255, 255)',
borderColor: '',
borderWidth: 0,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: 'rgb(70, 78, 94)',
color: 'rgb(209, 210, 210)',
borderColor: '',
borderWidth: 0,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(204, 204, 204)'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: 'rgb(255, 119, 34)',
borderColor: '',
borderWidth: 2,
color: '#fff'
}
})

View File

@@ -1,40 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 小黄人
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(51, 51, 51)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: '#222',
// 背景颜色
backgroundColor: 'rgb(248, 215, 49)',
// 根节点样式
root: {
fillColor: 'rgb(55, 165, 255)',
borderColor: 'rgb(51, 51, 51)',
borderWidth: 3
},
// 二级节点样式
second: {
fillColor: 'rgb(255, 160, 36)',
color: '#222',
borderColor: 'rgb(51, 51, 51)',
borderWidth: 3,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#222'
},
// 概要节点样式
generalization: {
borderColor: '#222',
borderWidth: 3,
color: '#222'
}
})

View File

@@ -1,40 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 薄荷
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(104, 204, 202)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(90, 206, 241)',
// 背景颜色
backgroundColor: 'rgb(239, 255, 255)',
// 根节点样式
root: {
fillColor: 'rgb(0, 192, 184)',
borderColor: '',
borderWidth: 0
},
// 二级节点样式
second: {
fillColor: '#fff',
color: '#222',
borderColor: 'rgb(184, 235, 233)',
borderWidth: 2,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#222'
},
// 概要节点样式
generalization: {
fillColor: 'rgb(90, 206, 241)',
borderColor: 'transparent',
color: '#fff'
}
})

View File

@@ -1,44 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 橙汁
export default mergeTheme(defaultTheme, {
// 背景颜色
backgroundColor: '#070616',
// 连线的颜色
lineColor: '#fff',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: '#fff',
// 根节点样式
root: {
fillColor: '#ff6811',
color: '#110501',
borderColor: '#ff6811',
borderWidth: 0,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: '#070616',
color: '#a9a4a9',
borderColor: '#ff6811',
borderWidth: 2,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: '#a9a4a9'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: '',
borderColor: '#ff6811',
borderWidth: 2,
color: '#a9a4a9'
}
})

View File

@@ -1,40 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 粉红葡萄
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(166, 101, 106)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: '#fff',
// 背景颜色
backgroundColor: 'rgb(255, 208, 211)',
// 根节点样式
root: {
fillColor: 'rgb(139, 109, 225)',
borderColor: '',
borderWidth: 0
},
// 二级节点样式
second: {
fillColor: 'rgb(243, 104, 138)',
color: '#fff',
borderColor: '',
borderWidth: 0,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#222'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: 'transparent',
color: '#222'
}
})

View File

@@ -1,44 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 红色精神
export default mergeTheme(defaultTheme, {
// 背景颜色
backgroundColor: 'rgb(255, 238, 228)',
// 连线的颜色
lineColor: 'rgb(230, 138, 131)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(222, 101, 85)',
// 根节点样式
root: {
fillColor: 'rgb(207, 44, 44)',
color: 'rgb(255, 233, 157)',
borderColor: '',
borderWidth: 0,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: 'rgb(255, 255, 255)',
color: 'rgb(211, 58, 21)',
borderColor: 'rgb(222, 101, 85)',
borderWidth: 2,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(144, 71, 43)'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: 'rgb(255, 247, 211)',
borderColor: 'rgb(255, 202, 162)',
borderWidth: 2,
color: 'rgb(187, 101, 69)'
}
})

View File

@@ -1,37 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 浪漫紫
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(123, 115, 191)',
// 背景颜色
backgroundColor: 'rgb(251, 251, 251)',
// 概要连线的粗细
generalizationLineWidth: 1,
// 概要连线的颜色
generalizationLineColor: '#333',
// 根节点样式
root: {
fillColor: 'rgb(123, 115, 191)'
},
// 二级节点样式
second: {
fillColor: 'rgb(239, 238, 246)',
color: '#333',
borderColor: 'rgb(123, 115, 191)',
borderWidth: 1,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#333'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: '#333',
color: '#333'
}
})

View File

@@ -1,42 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 简约黑
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(34, 34, 34)',
lineWidth: 4,
// 概要连线的粗细
generalizationLineWidth: 4,
// 概要连线的颜色
generalizationLineColor: 'rgb(34, 34, 34)',
// 根节点样式
root: {
fillColor: '#fff',
color: 'rgb(34, 34, 34)',
borderColor: 'rgb(34, 34, 34)',
borderWidth: 3,
fontSize: 24
},
// 二级节点样式
second: {
fillColor: 'rgb(241, 246, 248)',
color: 'rgb(34, 34, 34)',
borderColor: 'rgb(34, 34, 34)',
borderWidth: 3,
fontSize: 18
},
// 三级及以下节点样式
node: {
fontSize: 14,
color: 'rgb(34, 34, 34)'
},
// 概要节点样式
generalization: {
fontSize: 14,
fillColor: 'transparent',
borderColor: 'rgb(34, 34, 34)',
borderWidth: 2,
color: 'rgb(34, 34, 34)'
}
})

View File

@@ -1,41 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 天清绿
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: '#fff',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: '#fff',
// 背景颜色
backgroundColor: 'rgb(80, 156, 170)',
// 根节点样式
root: {
fillColor: '#fff',
borderColor: '',
borderWidth: 0,
color: 'rgb(65, 89, 158)'
},
// 二级节点样式
second: {
fillColor: 'rgb(251, 227, 188)',
color: 'rgb(65, 89, 158)',
borderColor: '',
borderWidth: 0,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: 'rgb(65, 89, 158)'
},
// 概要节点样式
generalization: {
fillColor: '#fff',
borderColor: 'transparent',
color: 'rgb(65, 89, 158)'
}
})

View File

@@ -1,41 +0,0 @@
import defaultTheme from './default'
import { mergeTheme } from '../utils'
// 活力橙
export default mergeTheme(defaultTheme, {
// 连线的颜色
lineColor: 'rgb(254, 146, 0)',
lineWidth: 3,
// 概要连线的粗细
generalizationLineWidth: 3,
// 概要连线的颜色
generalizationLineColor: 'rgb(255, 222, 69)',
// 背景颜色
backgroundColor: 'rgb(255, 246, 243)',
// 根节点样式
root: {
fillColor: 'rgb(255, 112, 52)',
color: '#fff',
borderColor: '',
borderWidth: 0
},
// 二级节点样式
second: {
fillColor: '#fff',
color: 'rgb(51, 51, 51)',
borderColor: '',
borderWidth: 0,
fontSize: 14
},
// 三级及以下节点样式
node: {
fontSize: 12,
color: '#222'
},
// 概要节点样式
generalization: {
fillColor: 'rgb(255, 222, 69)',
borderColor: 'transparent',
color: 'rgb(51, 51, 51)'
}
})

View File

@@ -76,11 +76,11 @@ export const resizeImgSizeByOriginRatio = (
let nRatio = width / height
let mRatio = newWidth / newHeight
if (nRatio > mRatio) {
// 固定高度
arr = [nRatio * newHeight, newHeight]
} else {
// 固定宽度
arr = [newWidth, newWidth / nRatio]
} else {
// 固定高度
arr = [nRatio * newHeight, newHeight]
}
return arr
}
@@ -95,11 +95,11 @@ export const resizeImgSize = (width, height, maxWidth, maxHeight) => {
} else {
let mRatio = maxWidth / maxHeight
if (nRatio > mRatio) {
// 固定高度
arr = [nRatio * maxHeight, maxHeight]
} else {
// 固定宽度
arr = [maxWidth, maxWidth / nRatio]
} else {
// 固定高度
arr = [nRatio * maxHeight, maxHeight]
}
}
} else if (maxWidth) {

63
web/package-lock.json generated
View File

@@ -14,6 +14,7 @@
"element-ui": "^2.15.1",
"highlight.js": "^10.7.3",
"katex": "^0.16.9",
"simple-mind-map-plugin-themes": "^1.0.0",
"v-viewer": "^1.6.4",
"vue": "^2.6.11",
"vue-i18n": "^8.27.2",
@@ -1812,7 +1813,6 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -1828,7 +1828,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -1844,7 +1843,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"android"
@@ -1860,7 +1858,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -1876,7 +1873,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"darwin"
@@ -1892,7 +1888,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
@@ -1908,7 +1903,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"freebsd"
@@ -1924,7 +1918,6 @@
"cpu": [
"arm"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1940,7 +1933,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1956,7 +1948,6 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1972,7 +1963,6 @@
"cpu": [
"loong64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -1988,7 +1978,6 @@
"cpu": [
"mips64el"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -2004,7 +1993,6 @@
"cpu": [
"ppc64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -2020,7 +2008,6 @@
"cpu": [
"riscv64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -2036,7 +2023,6 @@
"cpu": [
"s390x"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -2052,7 +2038,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"linux"
@@ -2068,7 +2053,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"netbsd"
@@ -2084,7 +2068,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"openbsd"
@@ -2100,7 +2083,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"sunos"
@@ -2116,7 +2098,6 @@
"cpu": [
"arm64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -2132,7 +2113,6 @@
"cpu": [
"ia32"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -2148,7 +2128,6 @@
"cpu": [
"x64"
],
"dev": true,
"optional": true,
"os": [
"win32"
@@ -6847,7 +6826,6 @@
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
"integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
"dev": true,
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@@ -13616,6 +13594,14 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
"node_modules/simple-mind-map-plugin-themes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/simple-mind-map-plugin-themes/-/simple-mind-map-plugin-themes-1.0.0.tgz",
"integrity": "sha512-v+L28HfRK1B+qw+76ueRGbbAxnKmGhVNuHL+oCWTE0qbdvaqSAszI+yOxqeTNXJmBgzrjeJXpJ831/gDiWUKaQ==",
"dependencies": {
"esbuild": "^0.17.15"
}
},
"node_modules/simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@@ -18560,154 +18546,132 @@
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
"integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
"dev": true,
"optional": true
},
"@esbuild/android-arm64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
"integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
"dev": true,
"optional": true
},
"@esbuild/android-x64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
"integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
"dev": true,
"optional": true
},
"@esbuild/darwin-arm64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
"integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==",
"dev": true,
"optional": true
},
"@esbuild/darwin-x64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
"integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
"dev": true,
"optional": true
},
"@esbuild/freebsd-arm64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
"integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
"dev": true,
"optional": true
},
"@esbuild/freebsd-x64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
"integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-arm": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
"integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
"dev": true,
"optional": true
},
"@esbuild/linux-arm64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
"integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
"dev": true,
"optional": true
},
"@esbuild/linux-ia32": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
"integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-loong64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
"integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
"dev": true,
"optional": true
},
"@esbuild/linux-mips64el": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
"integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
"dev": true,
"optional": true
},
"@esbuild/linux-ppc64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
"integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
"dev": true,
"optional": true
},
"@esbuild/linux-riscv64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
"integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
"dev": true,
"optional": true
},
"@esbuild/linux-s390x": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
"integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
"dev": true,
"optional": true
},
"@esbuild/linux-x64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
"integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==",
"dev": true,
"optional": true
},
"@esbuild/netbsd-x64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
"integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
"dev": true,
"optional": true
},
"@esbuild/openbsd-x64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
"integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
"dev": true,
"optional": true
},
"@esbuild/sunos-x64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
"integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
"dev": true,
"optional": true
},
"@esbuild/win32-arm64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
"integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
"dev": true,
"optional": true
},
"@esbuild/win32-ia32": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
"integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
"dev": true,
"optional": true
},
"@esbuild/win32-x64": {
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
"integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
"dev": true,
"optional": true
},
"@hapi/address": {
@@ -22487,7 +22451,6 @@
"version": "0.17.19",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
"integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
"dev": true,
"requires": {
"@esbuild/android-arm": "0.17.19",
"@esbuild/android-arm64": "0.17.19",
@@ -27888,6 +27851,14 @@
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
"dev": true
},
"simple-mind-map-plugin-themes": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/simple-mind-map-plugin-themes/-/simple-mind-map-plugin-themes-1.0.0.tgz",
"integrity": "sha512-v+L28HfRK1B+qw+76ueRGbbAxnKmGhVNuHL+oCWTE0qbdvaqSAszI+yOxqeTNXJmBgzrjeJXpJ831/gDiWUKaQ==",
"requires": {
"esbuild": "^0.17.15"
}
},
"simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",

View File

@@ -17,6 +17,7 @@
"element-ui": "^2.15.1",
"highlight.js": "^10.7.3",
"katex": "^0.16.9",
"simple-mind-map-plugin-themes": "^1.0.0",
"v-viewer": "^1.6.4",
"vue": "^2.6.11",
"vue-i18n": "^8.27.2",

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Some files were not shown because too many files have changed in this diff Show More