mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-17 22:08:25 +08:00
Feat:支持格式刷功能
This commit is contained in:
@@ -323,7 +323,9 @@ export const nodeDataNoStylePropList = [
|
||||
'richText',
|
||||
'resetRichText',
|
||||
'uid',
|
||||
'activeStyle'
|
||||
'activeStyle',
|
||||
'associativeLineTargets',
|
||||
'associativeLineTargetControlOffsets'
|
||||
]
|
||||
|
||||
// 数据缓存
|
||||
|
||||
@@ -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, {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
76
simple-mind-map/src/plugins/Painter.js
Normal file
76
simple-mind-map/src/plugins/Painter.js
Normal file
@@ -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
|
||||
@@ -202,6 +202,7 @@ export default {
|
||||
export: 'Export',
|
||||
shortcutKey: 'Shortcut key',
|
||||
associativeLine: 'Associative line',
|
||||
painter: 'Painter'
|
||||
},
|
||||
edit: {
|
||||
newFeatureNoticeTitle: 'New feature reminder',
|
||||
|
||||
@@ -202,6 +202,7 @@ export default {
|
||||
export: '导出',
|
||||
shortcutKey: '快捷键',
|
||||
associativeLine: '关联线',
|
||||
painter: '格式刷'
|
||||
},
|
||||
edit: {
|
||||
newFeatureNoticeTitle: '新特性提醒',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -23,6 +23,17 @@
|
||||
<span class="icon iconfont iconqianjin1"></span>
|
||||
<span class="text">{{ $t('toolbar.redo') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
:class="{
|
||||
disabled: activeNodes.length <= 0 || hasGeneralization,
|
||||
active: isInPainter
|
||||
}"
|
||||
@click="$bus.$emit('startPainter')"
|
||||
>
|
||||
<span class="icon iconfont iconjiedian"></span>
|
||||
<span class="text">{{ $t('toolbar.painter') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
:class="{
|
||||
@@ -195,7 +206,8 @@ export default {
|
||||
forwardEnd: true,
|
||||
readonly: false,
|
||||
isFullDataFile: false,
|
||||
timer: null
|
||||
timer: null,
|
||||
isInPainter: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -227,12 +239,16 @@ export default {
|
||||
this.$bus.$on('node_active', this.onNodeActive)
|
||||
this.$bus.$on('back_forward', this.onBackForward)
|
||||
this.$bus.$on('write_local_file', this.onWriteLocalFile)
|
||||
this.$bus.$on('painter_start', this.onPainterStart)
|
||||
this.$bus.$on('painter_end', this.onPainterEnd)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('mode_change', this.onModeChange)
|
||||
this.$bus.$off('node_active', this.onNodeActive)
|
||||
this.$bus.$off('back_forward', this.onBackForward)
|
||||
this.$bus.$off('write_local_file', this.onWriteLocalFile)
|
||||
this.$bus.$on('painter_start', this.onPainterStart)
|
||||
this.$bus.$off('painter_end', this.onPainterEnd)
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setActiveSidebar']),
|
||||
@@ -448,6 +464,14 @@ export default {
|
||||
'你的浏览器可能不支持,建议使用最新版本的Chrome浏览器'
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
onPainterStart() {
|
||||
this.isInPainter = true
|
||||
},
|
||||
|
||||
onPainterEnd() {
|
||||
this.isInPainter = false
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -531,6 +555,12 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
.icon {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
color: #bcbcbc;
|
||||
cursor: not-allowed;
|
||||
|
||||
Reference in New Issue
Block a user