Feat:1.去除主题的行高配置;2.优化非富文本模式下的文本编辑效果
This commit is contained in:
parent
4aa5a8c48b
commit
889ec13dbf
@ -212,3 +212,6 @@ export const selfCloseTagList = [
|
|||||||
'meta',
|
'meta',
|
||||||
'area'
|
'area'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// 非富文本模式下的节点文本行高
|
||||||
|
export const noneRichTextNodeLineHeight = 1.2
|
||||||
@ -8,7 +8,11 @@ import {
|
|||||||
checkSmmFormatData,
|
checkSmmFormatData,
|
||||||
getTextFromHtml
|
getTextFromHtml
|
||||||
} from '../../utils'
|
} from '../../utils'
|
||||||
import { ERROR_TYPES, CONSTANTS } from '../../constants/constant'
|
import {
|
||||||
|
ERROR_TYPES,
|
||||||
|
CONSTANTS,
|
||||||
|
noneRichTextNodeLineHeight
|
||||||
|
} from '../../constants/constant'
|
||||||
|
|
||||||
// 节点文字编辑类
|
// 节点文字编辑类
|
||||||
export default class TextEdit {
|
export default class TextEdit {
|
||||||
@ -217,7 +221,17 @@ export default class TextEdit {
|
|||||||
if (!this.textEditNode) {
|
if (!this.textEditNode) {
|
||||||
this.textEditNode = document.createElement('div')
|
this.textEditNode = document.createElement('div')
|
||||||
this.textEditNode.classList.add('smm-node-edit-wrap')
|
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.setAttribute('contenteditable', true)
|
||||||
this.textEditNode.addEventListener('keyup', e => {
|
this.textEditNode.addEventListener('keyup', e => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
@ -254,30 +268,31 @@ export default class TextEdit {
|
|||||||
this.mindMap.opt.customInnerElsAppendTo || document.body
|
this.mindMap.opt.customInnerElsAppendTo || document.body
|
||||||
targetNode.appendChild(this.textEditNode)
|
targetNode.appendChild(this.textEditNode)
|
||||||
}
|
}
|
||||||
let scale = this.mindMap.view.scale
|
const scale = this.mindMap.view.scale
|
||||||
let lineHeight = node.style.merge('lineHeight')
|
const fontSize = node.style.merge('fontSize')
|
||||||
let fontSize = node.style.merge('fontSize')
|
const textLines = (this.cacheEditingText || node.getData('text'))
|
||||||
let textLines = (this.cacheEditingText || node.getData('text'))
|
|
||||||
.split(/\n/gim)
|
.split(/\n/gim)
|
||||||
.map(item => {
|
.map(item => {
|
||||||
return htmlEscape(item)
|
return htmlEscape(item)
|
||||||
})
|
})
|
||||||
let isMultiLine = node._textData.node.attr('data-ismultiLine') === 'true'
|
const isMultiLine = node._textData.node.attr('data-ismultiLine') === 'true'
|
||||||
node.style.domText(this.textEditNode, scale, isMultiLine)
|
node.style.domText(this.textEditNode, scale)
|
||||||
this.textEditNode.style.zIndex = nodeTextEditZIndex
|
this.textEditNode.style.zIndex = nodeTextEditZIndex
|
||||||
this.textEditNode.innerHTML = textLines.join('<br>')
|
this.textEditNode.innerHTML = textLines.join('<br>')
|
||||||
this.textEditNode.style.minWidth =
|
this.textEditNode.style.minWidth =
|
||||||
rect.width + this.textNodePaddingX * 2 + 'px'
|
rect.width + this.textNodePaddingX * 2 + 'px'
|
||||||
this.textEditNode.style.minHeight =
|
this.textEditNode.style.minHeight = rect.height + 'px'
|
||||||
rect.height + this.textNodePaddingY * 2 + 'px'
|
|
||||||
this.textEditNode.style.left = rect.left + 'px'
|
this.textEditNode.style.left = rect.left + 'px'
|
||||||
this.textEditNode.style.top = rect.top + 'px'
|
this.textEditNode.style.top = rect.top + 'px'
|
||||||
this.textEditNode.style.display = 'block'
|
this.textEditNode.style.display = 'block'
|
||||||
this.textEditNode.style.maxWidth = textAutoWrapWidth * scale + 'px'
|
this.textEditNode.style.maxWidth = textAutoWrapWidth * scale + 'px'
|
||||||
if (isMultiLine && lineHeight !== 1) {
|
if (isMultiLine) {
|
||||||
|
this.textEditNode.style.lineHeight = noneRichTextNodeLineHeight
|
||||||
this.textEditNode.style.transform = `translateY(${
|
this.textEditNode.style.transform = `translateY(${
|
||||||
-((lineHeight * fontSize - fontSize) / 2) * scale
|
(((noneRichTextNodeLineHeight - 1) * fontSize) / 2) * scale
|
||||||
}px)`
|
}px)`
|
||||||
|
} else {
|
||||||
|
this.textEditNode.style.lineHeight = 'normal'
|
||||||
}
|
}
|
||||||
this.showTextEdit = true
|
this.showTextEdit = true
|
||||||
// 选中文本
|
// 选中文本
|
||||||
|
|||||||
@ -229,20 +229,18 @@ class Style {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// html文字节点
|
// html文字节点
|
||||||
domText(node, fontSizeScale = 1, isMultiLine) {
|
domText(node, fontSizeScale = 1) {
|
||||||
const styles = {
|
const styles = {
|
||||||
color: this.merge('color'),
|
color: this.merge('color'),
|
||||||
fontFamily: this.merge('fontFamily'),
|
fontFamily: this.merge('fontFamily'),
|
||||||
fontSize: this.merge('fontSize'),
|
fontSize: this.merge('fontSize'),
|
||||||
fontWeight: this.merge('fontWeight'),
|
fontWeight: this.merge('fontWeight'),
|
||||||
fontStyle: this.merge('fontStyle'),
|
fontStyle: this.merge('fontStyle'),
|
||||||
textDecoration: this.merge('textDecoration'),
|
textDecoration: this.merge('textDecoration')
|
||||||
lineHeight: this.merge('lineHeight')
|
|
||||||
}
|
}
|
||||||
node.style.fontFamily = styles.fontFamily
|
node.style.fontFamily = styles.fontFamily
|
||||||
node.style.fontSize = styles.fontSize * fontSizeScale + 'px'
|
node.style.fontSize = styles.fontSize * fontSizeScale + 'px'
|
||||||
node.style.fontWeight = styles.fontWeight || 'normal'
|
node.style.fontWeight = styles.fontWeight || 'normal'
|
||||||
node.style.lineHeight = !isMultiLine ? 'normal' : styles.lineHeight
|
|
||||||
node.style.fontStyle = styles.fontStyle
|
node.style.fontStyle = styles.fontStyle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
import {
|
import {
|
||||||
measureText,
|
|
||||||
resizeImgSize,
|
resizeImgSize,
|
||||||
removeHtmlStyle,
|
removeHtmlStyle,
|
||||||
addHtmlStyle,
|
addHtmlStyle,
|
||||||
@ -11,7 +10,19 @@ import {
|
|||||||
} from '../../../utils'
|
} from '../../../utils'
|
||||||
import { Image as SVGImage, SVG, A, G, Rect, Text } from '@svgdotjs/svg.js'
|
import { Image as SVGImage, SVG, A, G, Rect, Text } from '@svgdotjs/svg.js'
|
||||||
import iconsSvg from '../../../svg/icons'
|
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 = {
|
const defaultTagStyle = {
|
||||||
@ -218,16 +229,14 @@ function createTextNode(specifyText) {
|
|||||||
}
|
}
|
||||||
let g = new G()
|
let g = new G()
|
||||||
let fontSize = this.getStyle('fontSize', false)
|
let fontSize = this.getStyle('fontSize', false)
|
||||||
let lineHeight = this.getStyle('lineHeight', false)
|
|
||||||
// 文本超长自动换行
|
// 文本超长自动换行
|
||||||
let textStyle = this.style.getTextFontStyle()
|
|
||||||
let textArr = []
|
let textArr = []
|
||||||
if (!isUndef(text)) {
|
if (!isUndef(text)) {
|
||||||
textArr = String(text).split(/\n/gim)
|
textArr = String(text).split(/\n/gim)
|
||||||
}
|
}
|
||||||
const { textAutoWrapWidth: maxWidth, emptyTextMeasureHeightText } =
|
const { textAutoWrapWidth: maxWidth, emptyTextMeasureHeightText } =
|
||||||
this.mindMap.opt
|
this.mindMap.opt
|
||||||
let isMultiLine = false
|
let isMultiLine = textArr.length > 1
|
||||||
textArr.forEach((item, index) => {
|
textArr.forEach((item, index) => {
|
||||||
let arr = item.split('')
|
let arr = item.split('')
|
||||||
let lines = []
|
let lines = []
|
||||||
@ -235,7 +244,7 @@ function createTextNode(specifyText) {
|
|||||||
while (arr.length) {
|
while (arr.length) {
|
||||||
let str = arr.shift()
|
let str = arr.shift()
|
||||||
let text = [...line, str].join('')
|
let text = [...line, str].join('')
|
||||||
if (measureText(text, textStyle).width <= maxWidth) {
|
if (measureText(text, this.style).width <= maxWidth) {
|
||||||
line.push(str)
|
line.push(str)
|
||||||
} else {
|
} else {
|
||||||
lines.push(line.join(''))
|
lines.push(line.join(''))
|
||||||
@ -254,7 +263,10 @@ function createTextNode(specifyText) {
|
|||||||
textArr.forEach((item, index) => {
|
textArr.forEach((item, index) => {
|
||||||
let node = new Text().text(item)
|
let node = new Text().text(item)
|
||||||
this.style.text(node)
|
this.style.text(node)
|
||||||
node.y(fontSize * lineHeight * index)
|
node.y(
|
||||||
|
fontSize * noneRichTextNodeLineHeight * index +
|
||||||
|
((noneRichTextNodeLineHeight - 1) * fontSize) / 2
|
||||||
|
)
|
||||||
g.add(node)
|
g.add(node)
|
||||||
})
|
})
|
||||||
let { width, height } = g.bbox()
|
let { width, height } = g.bbox()
|
||||||
|
|||||||
@ -72,7 +72,6 @@ export default {
|
|||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
lineHeight: 1.5,
|
|
||||||
borderColor: 'transparent',
|
borderColor: 'transparent',
|
||||||
borderWidth: 0,
|
borderWidth: 0,
|
||||||
borderDasharray: 'none',
|
borderDasharray: 'none',
|
||||||
@ -103,7 +102,6 @@ export default {
|
|||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: 'normal',
|
fontWeight: 'normal',
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
lineHeight: 1.5,
|
|
||||||
borderColor: '#549688',
|
borderColor: '#549688',
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderDasharray: 'none',
|
borderDasharray: 'none',
|
||||||
@ -131,7 +129,6 @@ export default {
|
|||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight: 'normal',
|
fontWeight: 'normal',
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
lineHeight: 1.5,
|
|
||||||
borderColor: 'transparent',
|
borderColor: 'transparent',
|
||||||
borderWidth: 0,
|
borderWidth: 0,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
@ -159,7 +156,6 @@ export default {
|
|||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: 'normal',
|
fontWeight: 'normal',
|
||||||
fontStyle: 'normal',
|
fontStyle: 'normal',
|
||||||
lineHeight: 1.5,
|
|
||||||
borderColor: '#549688',
|
borderColor: '#549688',
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderDasharray: 'none',
|
borderDasharray: 'none',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user