优化和修复节点编辑的一些体验和问题
This commit is contained in:
parent
f8506cb75b
commit
8d9299aed7
@ -28,6 +28,7 @@ class Event extends EventEmitter {
|
|||||||
// 绑定函数上下文
|
// 绑定函数上下文
|
||||||
bindFn() {
|
bindFn() {
|
||||||
this.onDrawClick = this.onDrawClick.bind(this)
|
this.onDrawClick = this.onDrawClick.bind(this)
|
||||||
|
this.onDrawMousedown = this.onDrawMousedown.bind(this)
|
||||||
this.onMousedown = this.onMousedown.bind(this)
|
this.onMousedown = this.onMousedown.bind(this)
|
||||||
this.onMousemove = this.onMousemove.bind(this)
|
this.onMousemove = this.onMousemove.bind(this)
|
||||||
this.onMouseup = this.onMouseup.bind(this)
|
this.onMouseup = this.onMouseup.bind(this)
|
||||||
@ -40,6 +41,7 @@ class Event extends EventEmitter {
|
|||||||
// 绑定事件
|
// 绑定事件
|
||||||
bind() {
|
bind() {
|
||||||
this.mindMap.svg.on('click', this.onDrawClick)
|
this.mindMap.svg.on('click', this.onDrawClick)
|
||||||
|
this.mindMap.svg.on('mousedown', this.onDrawMousedown)
|
||||||
this.mindMap.el.addEventListener('mousedown', this.onMousedown)
|
this.mindMap.el.addEventListener('mousedown', this.onMousedown)
|
||||||
this.mindMap.svg.on('mousedown', this.onSvgMousedown)
|
this.mindMap.svg.on('mousedown', this.onSvgMousedown)
|
||||||
window.addEventListener('mousemove', this.onMousemove)
|
window.addEventListener('mousemove', this.onMousemove)
|
||||||
@ -52,6 +54,7 @@ class Event extends EventEmitter {
|
|||||||
// 解绑事件
|
// 解绑事件
|
||||||
unbind() {
|
unbind() {
|
||||||
this.mindMap.svg.off('click', this.onDrawClick)
|
this.mindMap.svg.off('click', this.onDrawClick)
|
||||||
|
this.mindMap.svg.off('mousedown', this.onDrawMousedown)
|
||||||
this.mindMap.el.removeEventListener('mousedown', this.onMousedown)
|
this.mindMap.el.removeEventListener('mousedown', this.onMousedown)
|
||||||
window.removeEventListener('mousemove', this.onMousemove)
|
window.removeEventListener('mousemove', this.onMousemove)
|
||||||
window.removeEventListener('mouseup', this.onMouseup)
|
window.removeEventListener('mouseup', this.onMouseup)
|
||||||
@ -65,6 +68,11 @@ class Event extends EventEmitter {
|
|||||||
this.emit('draw_click', e)
|
this.emit('draw_click', e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 画布的鼠标按下事件
|
||||||
|
onDrawMousedown(e) {
|
||||||
|
this.emit('draw_mousedown', e)
|
||||||
|
}
|
||||||
|
|
||||||
// svg画布的鼠标按下事件
|
// svg画布的鼠标按下事件
|
||||||
onSvgMousedown(e) {
|
onSvgMousedown(e) {
|
||||||
this.emit('svg_mousedown', e)
|
this.emit('svg_mousedown', e)
|
||||||
@ -72,7 +80,6 @@ class Event extends EventEmitter {
|
|||||||
|
|
||||||
// 鼠标按下事件
|
// 鼠标按下事件
|
||||||
onMousedown(e) {
|
onMousedown(e) {
|
||||||
// e.preventDefault()
|
|
||||||
// 鼠标左键
|
// 鼠标左键
|
||||||
if (e.which === 1) {
|
if (e.which === 1) {
|
||||||
this.isLeftMousedown = true
|
this.isLeftMousedown = true
|
||||||
@ -84,13 +91,13 @@ class Event extends EventEmitter {
|
|||||||
|
|
||||||
// 鼠标移动事件
|
// 鼠标移动事件
|
||||||
onMousemove(e) {
|
onMousemove(e) {
|
||||||
// e.preventDefault()
|
|
||||||
this.mousemovePos.x = e.clientX
|
this.mousemovePos.x = e.clientX
|
||||||
this.mousemovePos.y = e.clientY
|
this.mousemovePos.y = e.clientY
|
||||||
this.mousemoveOffset.x = e.clientX - this.mousedownPos.x
|
this.mousemoveOffset.x = e.clientX - this.mousedownPos.x
|
||||||
this.mousemoveOffset.y = e.clientY - this.mousedownPos.y
|
this.mousemoveOffset.y = e.clientY - this.mousedownPos.y
|
||||||
this.emit('mousemove', e, this)
|
this.emit('mousemove', e, this)
|
||||||
if (this.isLeftMousedown) {
|
if (this.isLeftMousedown) {
|
||||||
|
e.preventDefault()
|
||||||
this.emit('drag', e, this)
|
this.emit('drag', e, this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -450,6 +450,7 @@ class Node {
|
|||||||
|
|
||||||
// 更新节点形状样式
|
// 更新节点形状样式
|
||||||
updateNodeShape() {
|
updateNodeShape() {
|
||||||
|
if (!this.shapeNode) return
|
||||||
const shape = this.getShape()
|
const shape = this.getShape()
|
||||||
this.style[shape === CONSTANTS.SHAPE.RECTANGLE ? 'rect' : 'shape'](this.shapeNode)
|
this.style[shape === CONSTANTS.SHAPE.RECTANGLE ? 'rect' : 'shape'](this.shapeNode)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import './css/quill.css'
|
|||||||
import html2canvas from 'html2canvas'
|
import html2canvas from 'html2canvas'
|
||||||
import { Image as SvgImage } from '@svgdotjs/svg.js'
|
import { Image as SvgImage } from '@svgdotjs/svg.js'
|
||||||
import { walk } from './utils'
|
import { walk } from './utils'
|
||||||
|
import { CONSTANTS } from './utils/constant'
|
||||||
|
|
||||||
let extended = false
|
let extended = false
|
||||||
|
|
||||||
@ -97,7 +98,7 @@ class RichText {
|
|||||||
this.mindMap.renderer.textEdit.registerTmpShortcut()
|
this.mindMap.renderer.textEdit.registerTmpShortcut()
|
||||||
if (!this.textEditNode) {
|
if (!this.textEditNode) {
|
||||||
this.textEditNode = document.createElement('div')
|
this.textEditNode = document.createElement('div')
|
||||||
this.textEditNode.style.cssText = `position:fixed;box-sizing: border-box;box-shadow: 0 0 20px rgba(0,0,0,.5);outline: none; word-break: break-all;`
|
this.textEditNode.style.cssText = `position:fixed;box-sizing: border-box;box-shadow: 0 0 20px rgba(0,0,0,.5);outline: none; word-break: break-all;padding: 3px 5px;margin-left: -5px;margin-top: -3px;`
|
||||||
document.body.appendChild(this.textEditNode)
|
document.body.appendChild(this.textEditNode)
|
||||||
}
|
}
|
||||||
// 原始宽高
|
// 原始宽高
|
||||||
@ -147,7 +148,7 @@ class RichText {
|
|||||||
underline: node.style.merge('textDecoration') === 'underline',
|
underline: node.style.merge('textDecoration') === 'underline',
|
||||||
strike: node.style.merge('textDecoration') === 'line-through'
|
strike: node.style.merge('textDecoration') === 'line-through'
|
||||||
}
|
}
|
||||||
this.formatText(style)
|
this.formatAllText(style)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 隐藏文本编辑控件,即完成编辑
|
// 隐藏文本编辑控件,即完成编辑
|
||||||
@ -435,6 +436,7 @@ class RichText {
|
|||||||
node.data.richText = false
|
node.data.richText = false
|
||||||
div.innerHTML = node.data.text
|
div.innerHTML = node.data.text
|
||||||
node.data.text = div.textContent
|
node.data.text = div.textContent
|
||||||
|
// delete node.data.uid
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
@ -445,7 +447,7 @@ class RichText {
|
|||||||
// 清空历史数据,并且触发数据变化
|
// 清空历史数据,并且触发数据变化
|
||||||
this.mindMap.command.clearHistory()
|
this.mindMap.command.clearHistory()
|
||||||
this.mindMap.command.addHistory()
|
this.mindMap.command.addHistory()
|
||||||
this.mindMap.reRender()
|
this.mindMap.render(null, CONSTANTS.TRANSFORM_TO_NORMAL_NODE)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 插件被移除前做的事情
|
// 插件被移除前做的事情
|
||||||
|
|||||||
@ -79,14 +79,14 @@ class Style {
|
|||||||
color: this.merge('fillColor')
|
color: this.merge('fillColor')
|
||||||
})
|
})
|
||||||
// 节点使用横线样式,不需要渲染非激活状态的边框样式
|
// 节点使用横线样式,不需要渲染非激活状态的边框样式
|
||||||
if (
|
// if (
|
||||||
!this.ctx.isRoot &&
|
// !this.ctx.isRoot &&
|
||||||
!this.ctx.isGeneralization &&
|
// !this.ctx.isGeneralization &&
|
||||||
this.ctx.mindMap.themeConfig.nodeUseLineStyle &&
|
// this.ctx.mindMap.themeConfig.nodeUseLineStyle &&
|
||||||
!this.ctx.nodeData.data.isActive
|
// !this.ctx.nodeData.data.isActive
|
||||||
) {
|
// ) {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
node.stroke({
|
node.stroke({
|
||||||
color: this.merge('borderColor'),
|
color: this.merge('borderColor'),
|
||||||
width: this.merge('borderWidth'),
|
width: this.merge('borderWidth'),
|
||||||
@ -120,11 +120,11 @@ class Style {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// html文字节点
|
// html文字节点
|
||||||
domText(node, fontSizeScale = 1) {
|
domText(node, fontSizeScale = 1, textLines) {
|
||||||
node.style.fontFamily = this.merge('fontFamily')
|
node.style.fontFamily = this.merge('fontFamily')
|
||||||
node.style.fontSize = this.merge('fontSize') * fontSizeScale + 'px'
|
node.style.fontSize = this.merge('fontSize') * fontSizeScale + 'px'
|
||||||
node.style.fontWeight = this.merge('fontWeight') || 'normal'
|
node.style.fontWeight = this.merge('fontWeight') || 'normal'
|
||||||
node.style.lineHeight = this.merge('lineHeight')
|
node.style.lineHeight = textLines === 1 ? 'normal' : this.merge('lineHeight')
|
||||||
node.style.fontStyle = this.merge('fontStyle')
|
node.style.fontStyle = this.merge('fontStyle')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,10 @@ export default class TextEdit {
|
|||||||
// 隐藏文本编辑框
|
// 隐藏文本编辑框
|
||||||
this.hideEditTextBox()
|
this.hideEditTextBox()
|
||||||
})
|
})
|
||||||
|
this.mindMap.on('draw_mousedown', () => {
|
||||||
|
// 隐藏文本编辑框
|
||||||
|
this.hideEditTextBox()
|
||||||
|
})
|
||||||
// 展开收缩按钮点击事件
|
// 展开收缩按钮点击事件
|
||||||
this.mindMap.on('expand_btn_click', () => {
|
this.mindMap.on('expand_btn_click', () => {
|
||||||
this.hideEditTextBox()
|
this.hideEditTextBox()
|
||||||
@ -74,17 +78,18 @@ export default class TextEdit {
|
|||||||
let scale = this.mindMap.view.scale
|
let scale = this.mindMap.view.scale
|
||||||
let lineHeight = node.style.merge('lineHeight')
|
let lineHeight = node.style.merge('lineHeight')
|
||||||
let fontSize = node.style.merge('fontSize')
|
let fontSize = node.style.merge('fontSize')
|
||||||
node.style.domText(this.textEditNode, scale)
|
let textLines = node.nodeData.data.text.split(/\n/gim)
|
||||||
this.textEditNode.innerHTML = node.nodeData.data.text
|
node.style.domText(this.textEditNode, scale, textLines.length)
|
||||||
.split(/\n/gim)
|
this.textEditNode.innerHTML = textLines.join('<br>')
|
||||||
.join('<br>')
|
|
||||||
this.textEditNode.style.minWidth = rect.width + 10 + 'px'
|
this.textEditNode.style.minWidth = rect.width + 10 + 'px'
|
||||||
this.textEditNode.style.minHeight = rect.height + 6 + 'px'
|
this.textEditNode.style.minHeight = rect.height + 6 + '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 = this.mindMap.opt.textAutoWrapWidth * scale + 'px'
|
this.textEditNode.style.maxWidth = this.mindMap.opt.textAutoWrapWidth * scale + 'px'
|
||||||
this.textEditNode.style.transform = `translateY(${-(lineHeight * fontSize - fontSize) / 2 * scale}px)`
|
if (textLines.length > 1 && lineHeight !== 1) {
|
||||||
|
this.textEditNode.style.transform = `translateY(${-((lineHeight * fontSize - fontSize) / 2 - 2) * scale}px)`
|
||||||
|
}
|
||||||
this.showTextEdit = true
|
this.showTextEdit = true
|
||||||
// 选中文本
|
// 选中文本
|
||||||
this.selectNodeText()
|
this.selectNodeText()
|
||||||
@ -126,6 +131,7 @@ export default class TextEdit {
|
|||||||
this.textEditNode.style.fontFamily = 'inherit'
|
this.textEditNode.style.fontFamily = 'inherit'
|
||||||
this.textEditNode.style.fontSize = 'inherit'
|
this.textEditNode.style.fontSize = 'inherit'
|
||||||
this.textEditNode.style.fontWeight = 'normal'
|
this.textEditNode.style.fontWeight = 'normal'
|
||||||
|
this.textEditNode.style.transform = 'translateY(0)'
|
||||||
this.showTextEdit = false
|
this.showTextEdit = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
line-height: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ql-container {
|
.ql-container {
|
||||||
|
|||||||
@ -117,6 +117,7 @@ export const themeList = [
|
|||||||
// 常量
|
// 常量
|
||||||
export const CONSTANTS = {
|
export const CONSTANTS = {
|
||||||
CHANGE_THEME: 'changeTheme',
|
CHANGE_THEME: 'changeTheme',
|
||||||
|
TRANSFORM_TO_NORMAL_NODE: 'transformAllNodesToNormalNode',
|
||||||
MODE: {
|
MODE: {
|
||||||
READONLY: 'readonly',
|
READONLY: 'readonly',
|
||||||
EDIT: 'edit'
|
EDIT: 'edit'
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user