From 889ec13dbfde4954c641ffb7d4678215c1d14a34 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: Wed, 16 Oct 2024 18:40:47 +0800 Subject: [PATCH] =?UTF-8?q?Feat=EF=BC=9A1.=E5=8E=BB=E9=99=A4=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E7=9A=84=E8=A1=8C=E9=AB=98=E9=85=8D=E7=BD=AE=EF=BC=9B?= =?UTF-8?q?2.=E4=BC=98=E5=8C=96=E9=9D=9E=E5=AF=8C=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E4=B8=8B=E7=9A=84=E6=96=87=E6=9C=AC=E7=BC=96?= =?UTF-8?q?=E8=BE=91=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- simple-mind-map/src/constants/constant.js | 3 ++ simple-mind-map/src/core/render/TextEdit.js | 39 +++++++++++++------ simple-mind-map/src/core/render/node/Style.js | 6 +-- .../core/render/node/nodeCreateContents.js | 26 +++++++++---- simple-mind-map/src/theme/default.js | 4 -- 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/simple-mind-map/src/constants/constant.js b/simple-mind-map/src/constants/constant.js index 3a346fc8..20cee026 100644 --- a/simple-mind-map/src/constants/constant.js +++ b/simple-mind-map/src/constants/constant.js @@ -212,3 +212,6 @@ export const selfCloseTagList = [ 'meta', 'area' ] + +// 非富文本模式下的节点文本行高 +export const noneRichTextNodeLineHeight = 1.2 \ No newline at end of file diff --git a/simple-mind-map/src/core/render/TextEdit.js b/simple-mind-map/src/core/render/TextEdit.js index ad6cc6e6..24d4c161 100644 --- a/simple-mind-map/src/core/render/TextEdit.js +++ b/simple-mind-map/src/core/render/TextEdit.js @@ -8,7 +8,11 @@ import { checkSmmFormatData, getTextFromHtml } from '../../utils' -import { ERROR_TYPES, CONSTANTS } from '../../constants/constant' +import { + ERROR_TYPES, + CONSTANTS, + noneRichTextNodeLineHeight +} from '../../constants/constant' // 节点文字编辑类 export default class TextEdit { @@ -217,7 +221,17 @@ export default class TextEdit { 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.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: -${this.textNodePaddingX}px; + margin-top: -${this.textNodePaddingY}px; + outline: none; + word-break: break-all; + ` this.textEditNode.setAttribute('contenteditable', true) this.textEditNode.addEventListener('keyup', e => { e.stopPropagation() @@ -254,30 +268,31 @@ export default class TextEdit { this.mindMap.opt.customInnerElsAppendTo || document.body targetNode.appendChild(this.textEditNode) } - let scale = this.mindMap.view.scale - let lineHeight = node.style.merge('lineHeight') - let fontSize = node.style.merge('fontSize') - let textLines = (this.cacheEditingText || node.getData('text')) + const scale = this.mindMap.view.scale + const fontSize = node.style.merge('fontSize') + const textLines = (this.cacheEditingText || node.getData('text')) .split(/\n/gim) .map(item => { return htmlEscape(item) }) - let isMultiLine = node._textData.node.attr('data-ismultiLine') === 'true' - node.style.domText(this.textEditNode, scale, isMultiLine) + const isMultiLine = node._textData.node.attr('data-ismultiLine') === 'true' + node.style.domText(this.textEditNode, scale) this.textEditNode.style.zIndex = nodeTextEditZIndex this.textEditNode.innerHTML = textLines.join('
') this.textEditNode.style.minWidth = rect.width + this.textNodePaddingX * 2 + 'px' - this.textEditNode.style.minHeight = - rect.height + this.textNodePaddingY * 2 + 'px' + this.textEditNode.style.minHeight = rect.height + 'px' this.textEditNode.style.left = rect.left + 'px' this.textEditNode.style.top = rect.top + 'px' this.textEditNode.style.display = 'block' this.textEditNode.style.maxWidth = textAutoWrapWidth * scale + 'px' - if (isMultiLine && lineHeight !== 1) { + if (isMultiLine) { + this.textEditNode.style.lineHeight = noneRichTextNodeLineHeight this.textEditNode.style.transform = `translateY(${ - -((lineHeight * fontSize - fontSize) / 2) * scale + (((noneRichTextNodeLineHeight - 1) * fontSize) / 2) * scale }px)` + } else { + this.textEditNode.style.lineHeight = 'normal' } this.showTextEdit = true // 选中文本 diff --git a/simple-mind-map/src/core/render/node/Style.js b/simple-mind-map/src/core/render/node/Style.js index 98359644..bed7797d 100644 --- a/simple-mind-map/src/core/render/node/Style.js +++ b/simple-mind-map/src/core/render/node/Style.js @@ -229,20 +229,18 @@ class Style { } // html文字节点 - domText(node, fontSizeScale = 1, isMultiLine) { + domText(node, fontSizeScale = 1) { 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') + textDecoration: this.merge('textDecoration') } 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 } diff --git a/simple-mind-map/src/core/render/node/nodeCreateContents.js b/simple-mind-map/src/core/render/node/nodeCreateContents.js index bd6aa408..7a76cf41 100644 --- a/simple-mind-map/src/core/render/node/nodeCreateContents.js +++ b/simple-mind-map/src/core/render/node/nodeCreateContents.js @@ -1,5 +1,4 @@ import { - measureText, resizeImgSize, removeHtmlStyle, addHtmlStyle, @@ -11,7 +10,19 @@ import { } from '../../../utils' import { Image as SVGImage, SVG, A, G, Rect, Text } from '@svgdotjs/svg.js' import iconsSvg from '../../../svg/icons' -import { CONSTANTS } from '../../../constants/constant' +import { + CONSTANTS, + noneRichTextNodeLineHeight +} from '../../../constants/constant' + +// 测量svg文本宽高 +const measureText = (text, style) => { + const g = new G() + const node = new Text().text(text) + style.text(node) + g.add(node) + return g.bbox() +} // 标签默认的样式 const defaultTagStyle = { @@ -218,16 +229,14 @@ function createTextNode(specifyText) { } let g = new G() let fontSize = this.getStyle('fontSize', false) - let lineHeight = this.getStyle('lineHeight', false) // 文本超长自动换行 - let textStyle = this.style.getTextFontStyle() let textArr = [] if (!isUndef(text)) { textArr = String(text).split(/\n/gim) } const { textAutoWrapWidth: maxWidth, emptyTextMeasureHeightText } = this.mindMap.opt - let isMultiLine = false + let isMultiLine = textArr.length > 1 textArr.forEach((item, index) => { let arr = item.split('') let lines = [] @@ -235,7 +244,7 @@ function createTextNode(specifyText) { while (arr.length) { let str = arr.shift() let text = [...line, str].join('') - if (measureText(text, textStyle).width <= maxWidth) { + if (measureText(text, this.style).width <= maxWidth) { line.push(str) } else { lines.push(line.join('')) @@ -254,7 +263,10 @@ function createTextNode(specifyText) { textArr.forEach((item, index) => { let node = new Text().text(item) this.style.text(node) - node.y(fontSize * lineHeight * index) + node.y( + fontSize * noneRichTextNodeLineHeight * index + + ((noneRichTextNodeLineHeight - 1) * fontSize) / 2 + ) g.add(node) }) let { width, height } = g.bbox() diff --git a/simple-mind-map/src/theme/default.js b/simple-mind-map/src/theme/default.js index 1cf3f7bd..94ddb12d 100644 --- a/simple-mind-map/src/theme/default.js +++ b/simple-mind-map/src/theme/default.js @@ -72,7 +72,6 @@ export default { fontSize: 16, fontWeight: 'bold', fontStyle: 'normal', - lineHeight: 1.5, borderColor: 'transparent', borderWidth: 0, borderDasharray: 'none', @@ -103,7 +102,6 @@ export default { fontSize: 16, fontWeight: 'normal', fontStyle: 'normal', - lineHeight: 1.5, borderColor: '#549688', borderWidth: 1, borderDasharray: 'none', @@ -131,7 +129,6 @@ export default { fontSize: 14, fontWeight: 'normal', fontStyle: 'normal', - lineHeight: 1.5, borderColor: 'transparent', borderWidth: 0, borderRadius: 5, @@ -159,7 +156,6 @@ export default { fontSize: 16, fontWeight: 'normal', fontStyle: 'normal', - lineHeight: 1.5, borderColor: '#549688', borderWidth: 1, borderDasharray: 'none',