From 4e327c3a484375b3c16cb056ea510e30492faf0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com> Date: Thu, 29 Aug 2024 10:30:52 +0800 Subject: [PATCH] =?UTF-8?q?Feat=EF=BC=9A=E6=A0=BC=E5=BC=8F=E5=88=B7?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=88=B7=E8=8A=82=E7=82=B9=E6=89=80=E6=9C=89?= =?UTF-8?q?=E7=94=9F=E6=95=88=E7=9A=84=E6=A0=B7=E5=BC=8F=EF=BC=8C=E5=8C=85?= =?UTF-8?q?=E6=8B=AC=E6=9D=A5=E8=87=AA=E4=B8=BB=E9=A2=98=E7=9A=84=E5=92=8C?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/constants/defaultOptions.js | 6 +- .../src/core/render/node/MindMapNode.js | 2 + simple-mind-map/src/core/render/node/Style.js | 132 ++++++++++++++---- simple-mind-map/src/plugins/Painter.js | 13 +- 4 files changed, 117 insertions(+), 36 deletions(-) diff --git a/simple-mind-map/src/constants/defaultOptions.js b/simple-mind-map/src/constants/defaultOptions.js index 5da7c1c6..1e9ec431 100644 --- a/simple-mind-map/src/constants/defaultOptions.js +++ b/simple-mind-map/src/constants/defaultOptions.js @@ -409,5 +409,9 @@ export const defaultOpt = { // 【OuterFrame】插件 outerFramePaddingX: 10, - outerFramePaddingY: 10 + outerFramePaddingY: 10, + + // 【Painter】插件 + // 是否只格式刷节点手动设置的样式,不考虑节点通过主题的应用的样式 + onlyPainterNodeCustomStyles: false } diff --git a/simple-mind-map/src/core/render/node/MindMapNode.js b/simple-mind-map/src/core/render/node/MindMapNode.js index 5b3c7174..b1654cd3 100644 --- a/simple-mind-map/src/core/render/node/MindMapNode.js +++ b/simple-mind-map/src/core/render/node/MindMapNode.js @@ -34,6 +34,8 @@ class MindMapNode { this.lineDraw = this.mindMap.lineDraw // 样式实例 this.style = new Style(this) + // 节点当前生效的全部样式 + this.effectiveStyles = {} // 形状实例 this.shapeInstance = new Shape(this) this.shapePadding = { diff --git a/simple-mind-map/src/core/render/node/Style.js b/simple-mind-map/src/core/render/node/Style.js index 1248fbb7..f466a503 100644 --- a/simple-mind-map/src/core/render/node/Style.js +++ b/simple-mind-map/src/core/render/node/Style.js @@ -85,7 +85,14 @@ class Style { // 获取某个样式值 getStyle(prop, root) { - return this.merge(prop, root) + const value = this.merge(prop, root) + if (!root) { + const styles = { + [prop]: value + } + this.addToEffectiveStyles(styles) + } + return value } // 获取自身自定义样式 @@ -93,26 +100,47 @@ class Style { return this.ctx.getData(prop) } + // 更新当前节点生效的样式数据 + addToEffectiveStyles(styles) { + this.ctx.effectiveStyles = { + ...this.ctx.effectiveStyles, + ...styles + } + } + // 矩形 rect(node) { this.shape(node) - node.radius(this.merge('borderRadius')) + const styles = { + borderRadius: this.merge('borderRadius') + } + this.addToEffectiveStyles(styles) + node.radius(styles.borderRadius) } // 形状 shape(node) { - if (this.merge('gradientStyle')) { + const styles = { + gradientStyle: this.merge('gradientStyle'), + startColor: this.merge('startColor'), + endColor: this.merge('endColor'), + fillColor: this.merge('fillColor'), + borderColor: this.merge('borderColor'), + borderWidth: this.merge('borderWidth'), + borderDasharray: this.merge('borderDasharray') + } + if (styles.gradientStyle) { if (!this._gradient) { this._gradient = this.ctx.nodeDraw.gradient('linear') } this._gradient.update(add => { - add.stop(0, this.merge('startColor')) - add.stop(1, this.merge('endColor')) + add.stop(0, styles.startColor) + add.stop(1, styles.endColor) }) node.fill(this._gradient) } else { node.fill({ - color: this.merge('fillColor') + color: styles.fillColor }) } // 节点使用横线样式,不需要渲染非激活状态的边框样式 @@ -125,56 +153,94 @@ class Style { // return // } node.stroke({ - color: this.merge('borderColor'), - width: this.merge('borderWidth'), - dasharray: this.merge('borderDasharray') + color: styles.borderColor, + width: styles.borderWidth, + dasharray: styles.borderDasharray }) + this.addToEffectiveStyles(styles) } // 文字 text(node) { + const styles = { + color: this.merge('color'), + fontFamily: this.merge('fontFamily'), + fontSize: this.merge('fontSize'), + fontWeight: this.merge('fontWeight'), + fontStyle: this.merge('fontStyle'), + textDecoration: this.merge('textDecoration') + } node .fill({ - color: this.merge('color') + color: styles.color }) .css({ - 'font-family': this.merge('fontFamily'), - 'font-size': this.merge('fontSize'), - 'font-weight': this.merge('fontWeight'), - 'font-style': this.merge('fontStyle'), - 'text-decoration': this.merge('textDecoration') + 'font-family': styles.fontFamily, + 'font-size': styles.fontSize, + 'font-weight': styles.fontWeight, + 'font-style': styles.fontStyle, + 'text-decoration': styles.textDecoration }) + this.addToEffectiveStyles(styles) } // 生成内联样式 createStyleText() { + const styles = { + color: this.merge('color'), + fontFamily: this.merge('fontFamily'), + fontSize: this.merge('fontSize'), + fontWeight: this.merge('fontWeight'), + fontStyle: this.merge('fontStyle'), + textDecoration: this.merge('textDecoration') + } + this.addToEffectiveStyles(styles) return ` - color: ${this.merge('color')}; - font-family: ${this.merge('fontFamily')}; - font-size: ${this.merge('fontSize') + 'px'}; - font-weight: ${this.merge('fontWeight')}; - font-style: ${this.merge('fontStyle')}; - text-decoration: ${this.merge('textDecoration')} + color: ${styles.color}; + font-family: ${styles.fontFamily}; + font-size: ${styles.fontSize + 'px'}; + font-weight: ${styles.fontWeight}; + font-style: ${styles.fontStyle}; + text-decoration: ${styles.textDecoration} ` } // 获取文本样式 getTextFontStyle() { - return { - italic: this.merge('fontStyle') === 'italic', - bold: this.merge('fontWeight'), + const styles = { + color: this.merge('color'), + fontFamily: this.merge('fontFamily'), fontSize: this.merge('fontSize'), - fontFamily: this.merge('fontFamily') + fontWeight: this.merge('fontWeight'), + fontStyle: this.merge('fontStyle'), + textDecoration: this.merge('textDecoration') + } + this.addToEffectiveStyles(styles) + return { + italic: styles.fontStyle === 'italic', + bold: styles.fontWeight, + fontSize: styles.fontSize, + fontFamily: styles.fontFamily } } // html文字节点 domText(node, fontSizeScale = 1, isMultiLine) { - node.style.fontFamily = this.merge('fontFamily') - node.style.fontSize = this.merge('fontSize') * fontSizeScale + 'px' - node.style.fontWeight = this.merge('fontWeight') || 'normal' - node.style.lineHeight = !isMultiLine ? 'normal' : this.merge('lineHeight') - node.style.fontStyle = this.merge('fontStyle') + const styles = { + color: this.merge('color'), + fontFamily: this.merge('fontFamily'), + fontSize: this.merge('fontSize'), + fontWeight: this.merge('fontWeight'), + fontStyle: this.merge('fontStyle'), + textDecoration: this.merge('textDecoration'), + lineHeight: this.merge('lineHeight') + } + this.addToEffectiveStyles(styles) + node.style.fontFamily = styles.fontFamily + node.style.fontSize = styles.fontSize * fontSizeScale + 'px' + node.style.fontWeight = styles.fontWeight || 'normal' + node.style.lineHeight = !isMultiLine ? 'normal' : styles.lineHeight + node.style.fontStyle = styles.fontStyle } // 标签文字 @@ -200,8 +266,12 @@ class Style { // 内置图标 iconNode(node) { + const styles = { + color: this.merge('color') + } + this.addToEffectiveStyles(styles) node.attr({ - fill: this.merge('color') + fill: styles.color }) } diff --git a/simple-mind-map/src/plugins/Painter.js b/simple-mind-map/src/plugins/Painter.js index 8dcf90e8..3b7be755 100644 --- a/simple-mind-map/src/plugins/Painter.js +++ b/simple-mind-map/src/plugins/Painter.js @@ -53,17 +53,22 @@ class Painter { node.uid === this.painterNode.uid ) return - const style = {} + let style = {} + // 格式刷节点所有生效的样式 + if (!this.mindMap.opt.onlyPainterNodeCustomStyles) { + style = { + ...this.painterNode.effectiveStyles + } + } const painterNodeData = this.painterNode.getData() Object.keys(painterNodeData).forEach(key => { if (checkIsNodeStyleDataKey(key)) { style[key] = painterNodeData[key] } }) + // 先去除目标节点的样式 + this.mindMap.renderer._handleRemoveCustomStyles(node.getData()) node.setStyles(style) - if (painterNodeData.activeStyle) { - node.setStyles(painterNodeData.activeStyle, true) - } } // 插件被移除前做的事情