From 11bb519db86d159e08cb8ad233dfc4364d749004 Mon Sep 17 00:00:00 2001 From: wanglin2 <1013335014@qq.com> Date: Thu, 3 Aug 2023 16:50:07 +0800 Subject: [PATCH] =?UTF-8?q?Feat=EF=BC=9A=E6=94=AF=E6=8C=81=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E5=88=B7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- simple-mind-map/src/constants/constant.js | 4 +- simple-mind-map/src/core/render/Render.js | 41 +++++++++- .../src/core/render/node/nodeCommandWraps.js | 8 +- simple-mind-map/src/plugins/Painter.js | 76 +++++++++++++++++++ web/src/lang/en_us.js | 1 + web/src/lang/zh_cn.js | 1 + web/src/pages/Edit/components/Edit.vue | 9 ++- web/src/pages/Edit/components/Toolbar.vue | 32 +++++++- 8 files changed, 167 insertions(+), 5 deletions(-) create mode 100644 simple-mind-map/src/plugins/Painter.js diff --git a/simple-mind-map/src/constants/constant.js b/simple-mind-map/src/constants/constant.js index 9490ff9b..3b991fe4 100644 --- a/simple-mind-map/src/constants/constant.js +++ b/simple-mind-map/src/constants/constant.js @@ -323,7 +323,9 @@ export const nodeDataNoStylePropList = [ 'richText', 'resetRichText', 'uid', - 'activeStyle' + 'activeStyle', + 'associativeLineTargets', + 'associativeLineTargetControlOffsets' ] // 数据缓存 diff --git a/simple-mind-map/src/core/render/Render.js b/simple-mind-map/src/core/render/Render.js index bc2c4439..6691042f 100644 --- a/simple-mind-map/src/core/render/Render.js +++ b/simple-mind-map/src/core/render/Render.js @@ -153,9 +153,12 @@ class Render { // 剪切节点 this.cutNode = this.cutNode.bind(this) this.mindMap.command.add('CUT_NODE', this.cutNode) - // 修改节点样式 + // 修改节点单个样式 this.setNodeStyle = this.setNodeStyle.bind(this) this.mindMap.command.add('SET_NODE_STYLE', this.setNodeStyle) + // 修改节点多个样式 + this.setNodeStyles = this.setNodeStyles.bind(this) + this.mindMap.command.add('SET_NODE_STYLES', this.setNodeStyles) // 切换节点是否激活 this.setNodeActive = this.setNodeActive.bind(this) this.mindMap.command.add('SET_NODE_ACTIVE', this.setNodeActive) @@ -859,6 +862,42 @@ class Render { } } + // 设置节点多个样式 + setNodeStyles(node, style, isActive) { + let data = {} + if (isActive) { + data = { + activeStyle: { + ...(node.nodeData.data.activeStyle || {}), + ...style + } + } + } else { + data = style + } + // 如果开启了富文本,则需要应用到富文本上 + if (this.mindMap.richText) { + let config = this.mindMap.richText.normalStyleToRichTextStyle(style) + if (Object.keys(config).length > 0) { + this.mindMap.richText.showEditText(node) + this.mindMap.richText.formatAllText(config) + this.mindMap.richText.hideEditText([node]) + } + } + this.setNodeDataRender(node, data) + // 更新了连线的样式 + let props = Object.keys(style) + let hasLineStyleProps = false + props.forEach((key) => { + if (lineStyleProps.includes(key)) { + hasLineStyleProps = true + } + }) + if (hasLineStyleProps) { + ;(node.parent || node).renderLine(true) + } + } + // 设置节点是否激活 setNodeActive(node, active) { this.setNodeData(node, { diff --git a/simple-mind-map/src/core/render/node/nodeCommandWraps.js b/simple-mind-map/src/core/render/node/nodeCommandWraps.js index 3ef043e9..8745fa7f 100644 --- a/simple-mind-map/src/core/render/node/nodeCommandWraps.js +++ b/simple-mind-map/src/core/render/node/nodeCommandWraps.js @@ -43,6 +43,11 @@ function setStyle(prop, value, isActive) { this.mindMap.execCommand('SET_NODE_STYLE', this, prop, value, isActive) } +// 修改多个样式 +function setStyles(style, isActive) { + this.mindMap.execCommand('SET_NODE_STYLES', this, style, isActive) +} + export default { setData, setText, @@ -52,5 +57,6 @@ export default { setNote, setTag, setShape, - setStyle + setStyle, + setStyles } diff --git a/simple-mind-map/src/plugins/Painter.js b/simple-mind-map/src/plugins/Painter.js new file mode 100644 index 00000000..50ee08e5 --- /dev/null +++ b/simple-mind-map/src/plugins/Painter.js @@ -0,0 +1,76 @@ +import { nodeDataNoStylePropList } from '../constants/constant' + +// 格式刷插件 +class Painter { + constructor({ mindMap }) { + this.mindMap = mindMap + this.isInPainter = false + this.painterNode = null + this.bindEvent() + } + + bindEvent() { + this.painterOneNode = this.painterOneNode.bind(this) + this.onEndPainter = this.onEndPainter.bind(this) + this.mindMap.on('node_click', this.painterOneNode) + this.mindMap.on('draw_click', this.onEndPainter) + } + + unBindEvent() { + this.mindMap.off('node_click', this.painterOneNode) + this.mindMap.off('draw_click', this.onEndPainter) + } + + // 开始格式刷 + startPainter() { + if (this.mindMap.opt.readonly) return + let activeNodeList = this.mindMap.renderer.activeNodeList + if (activeNodeList.length <= 0) return + this.painterNode = activeNodeList[0] + this.isInPainter = true + this.mindMap.emit('painter_start') + } + + // 结束格式刷 + endPainter() { + this.painterNode = null + this.isInPainter = false + } + + onEndPainter() { + this.endPainter() + this.mindMap.emit('painter_end') + } + + // 格式刷某个节点 + painterOneNode(node) { + if ( + !node || + !this.isInPainter || + !this.painterNode || + !node || + node === this.painterNode + ) + return + const style = {} + const painterNodeData = this.painterNode.nodeData.data + Object.keys(painterNodeData).forEach(key => { + if (!nodeDataNoStylePropList.includes(key)) { + style[key] = painterNodeData[key] + } + }) + node.setStyles(style) + if (painterNodeData.activeStyle) { + node.setStyles(painterNodeData.activeStyle, true) + } + } + + // 插件被移除前做的事情 + beforePluginRemove() { + this.unBindEvent() + } +} + +Painter.instanceName = 'painter' + +export default Painter diff --git a/web/src/lang/en_us.js b/web/src/lang/en_us.js index a89f26ae..17721249 100644 --- a/web/src/lang/en_us.js +++ b/web/src/lang/en_us.js @@ -202,6 +202,7 @@ export default { export: 'Export', shortcutKey: 'Shortcut key', associativeLine: 'Associative line', + painter: 'Painter' }, edit: { newFeatureNoticeTitle: 'New feature reminder', diff --git a/web/src/lang/zh_cn.js b/web/src/lang/zh_cn.js index 910dedfa..0b15f401 100644 --- a/web/src/lang/zh_cn.js +++ b/web/src/lang/zh_cn.js @@ -202,6 +202,7 @@ export default { export: '导出', shortcutKey: '快捷键', associativeLine: '关联线', + painter: '格式刷' }, edit: { newFeatureNoticeTitle: '新特性提醒', diff --git a/web/src/pages/Edit/components/Edit.vue b/web/src/pages/Edit/components/Edit.vue index 09be185c..2f4405b4 100644 --- a/web/src/pages/Edit/components/Edit.vue +++ b/web/src/pages/Edit/components/Edit.vue @@ -39,6 +39,7 @@ import AssociativeLine from 'simple-mind-map/src/plugins/AssociativeLine.js' import TouchEvent from 'simple-mind-map/src/plugins/TouchEvent.js' import NodeImgAdjust from 'simple-mind-map/src/plugins/NodeImgAdjust.js' import SearchPlugin from 'simple-mind-map/src/plugins/Search.js' +import Painter from 'simple-mind-map/src/plugins/Painter.js' import Outline from './Outline' import Style from './Style' import BaseStyle from './BaseStyle' @@ -81,6 +82,7 @@ MindMap .usePlugin(NodeImgAdjust) .usePlugin(TouchEvent) .usePlugin(SearchPlugin) + .usePlugin(Painter) // 注册自定义主题 customThemeList.forEach((item) => { @@ -153,6 +155,9 @@ export default { this.$bus.$on('createAssociativeLine', () => { this.mindMap.associativeLine.createLineFromActiveNode() }) + this.$bus.$on('startPainter', () => { + this.mindMap.painter.startPainter() + }) window.addEventListener('resize', () => { this.mindMap.resize() }) @@ -268,7 +273,9 @@ export default { 'node_tree_render_end', 'rich_text_selection_change', 'transforming-dom-to-images', - 'generalization_node_contextmenu' + 'generalization_node_contextmenu', + 'painter_start', + 'painter_end' ].forEach(event => { this.mindMap.on(event, (...args) => { this.$bus.$emit(event, ...args) diff --git a/web/src/pages/Edit/components/Toolbar.vue b/web/src/pages/Edit/components/Toolbar.vue index 9519002c..4f8b7d56 100644 --- a/web/src/pages/Edit/components/Toolbar.vue +++ b/web/src/pages/Edit/components/Toolbar.vue @@ -23,6 +23,17 @@ {{ $t('toolbar.redo') }} +
+ + {{ $t('toolbar.painter') }} +