Feat:1.演示模式中禁止画布的所有内容响应鼠标事件;2.节点的超链接和备注图标支持响应鼠标事件;3.支持填空模式
This commit is contained in:
parent
d60f30d97e
commit
bb2502501e
@ -128,13 +128,18 @@ class MindMap {
|
|||||||
// 创建容器元素
|
// 创建容器元素
|
||||||
initContainer() {
|
initContainer() {
|
||||||
const { associativeLineIsAlwaysAboveNode } = this.opt
|
const { associativeLineIsAlwaysAboveNode } = this.opt
|
||||||
|
// 给容器元素添加一个类名
|
||||||
|
this.el.classList.add('smm-mind-map-container')
|
||||||
// 节点关联线容器
|
// 节点关联线容器
|
||||||
const createAssociativeLineDraw = () => {
|
const createAssociativeLineDraw = () => {
|
||||||
this.associativeLineDraw = this.draw.group()
|
this.associativeLineDraw = this.draw.group()
|
||||||
this.associativeLineDraw.addClass('smm-associative-line-container')
|
this.associativeLineDraw.addClass('smm-associative-line-container')
|
||||||
}
|
}
|
||||||
// 画布
|
// 画布
|
||||||
this.svg = SVG().addTo(this.el).size(this.width, this.height)
|
this.svg = SVG()
|
||||||
|
.addTo(this.el)
|
||||||
|
.size(this.width, this.height)
|
||||||
|
|
||||||
// 容器
|
// 容器
|
||||||
this.draw = this.svg.group()
|
this.draw = this.svg.group()
|
||||||
this.draw.addClass('smm-container')
|
this.draw.addClass('smm-container')
|
||||||
@ -432,7 +437,13 @@ class MindMap {
|
|||||||
// 需要裁减的区域
|
// 需要裁减的区域
|
||||||
let clipData = null
|
let clipData = null
|
||||||
if (node) {
|
if (node) {
|
||||||
clipData = getNodeTreeBoundingRect(node, rect.x, rect.y, paddingX, paddingY)
|
clipData = getNodeTreeBoundingRect(
|
||||||
|
node,
|
||||||
|
rect.x,
|
||||||
|
rect.y,
|
||||||
|
paddingX,
|
||||||
|
paddingY
|
||||||
|
)
|
||||||
}
|
}
|
||||||
// 内边距
|
// 内边距
|
||||||
const fixHeight = 0
|
const fixHeight = 0
|
||||||
@ -581,6 +592,8 @@ class MindMap {
|
|||||||
this.svg.remove()
|
this.svg.remove()
|
||||||
// 去除给容器元素设置的背景样式
|
// 去除给容器元素设置的背景样式
|
||||||
Style.removeBackgroundStyle(this.el)
|
Style.removeBackgroundStyle(this.el)
|
||||||
|
// 移除给容器元素添加的类名
|
||||||
|
this.el.classList.remove('smm-mind-map-container')
|
||||||
this.el.innerHTML = ''
|
this.el.innerHTML = ''
|
||||||
this.el = null
|
this.el = null
|
||||||
this.removeCss()
|
this.removeCss()
|
||||||
|
|||||||
@ -316,7 +316,10 @@ function createNoteNode() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
let iconSize = this.mindMap.themeConfig.iconSize
|
let iconSize = this.mindMap.themeConfig.iconSize
|
||||||
let node = new SVG().attr('cursor', 'pointer').size(iconSize, iconSize)
|
let node = new SVG()
|
||||||
|
.attr('cursor', 'pointer')
|
||||||
|
.addClass('smm-node-note')
|
||||||
|
.size(iconSize, iconSize)
|
||||||
// 透明的层,用来作为鼠标区域
|
// 透明的层,用来作为鼠标区域
|
||||||
node.add(new Rect().size(iconSize, iconSize).fill({ color: 'transparent' }))
|
node.add(new Rect().size(iconSize, iconSize).fill({ color: 'transparent' }))
|
||||||
// 备注图标
|
// 备注图标
|
||||||
|
|||||||
@ -14,16 +14,25 @@ const defaultConfig = {
|
|||||||
transition: 'all 0.3s ease-out', // 高亮框动画的过渡
|
transition: 'all 0.3s ease-out', // 高亮框动画的过渡
|
||||||
zIndex: 9999, // 高亮框元素的层级
|
zIndex: 9999, // 高亮框元素的层级
|
||||||
padding: 20, // 高亮框的内边距
|
padding: 20, // 高亮框的内边距
|
||||||
margin: 50 // 高亮框的外边距
|
margin: 50, // 高亮框的外边距
|
||||||
|
openBlankMode: true // 是否开启填空模式,即带下划线的文本默认不显示,按回车键才依次显示
|
||||||
}
|
}
|
||||||
|
|
||||||
// 演示插件
|
// 演示插件
|
||||||
class Demonstrate {
|
class Demonstrate {
|
||||||
constructor(opt) {
|
constructor(opt) {
|
||||||
this.mindMap = opt.mindMap
|
this.mindMap = opt.mindMap
|
||||||
|
// 演示的步骤列表
|
||||||
this.stepList = []
|
this.stepList = []
|
||||||
|
// 当前所在步骤
|
||||||
this.currentStepIndex = 0
|
this.currentStepIndex = 0
|
||||||
this.maskEl = null
|
// 当前所在步骤对应的节点实例
|
||||||
|
this.currentStepNode = null
|
||||||
|
// 当前所在步骤节点的下划线文本数据
|
||||||
|
this.currentUnderlineTextData = null
|
||||||
|
// 临时的样式剩余
|
||||||
|
this.tmpStyleEl = null
|
||||||
|
// 高亮样式元素
|
||||||
this.highlightEl = null
|
this.highlightEl = null
|
||||||
this.transformState = null
|
this.transformState = null
|
||||||
this.renderTree = null
|
this.renderTree = null
|
||||||
@ -47,6 +56,8 @@ class Demonstrate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_enter() {
|
_enter() {
|
||||||
|
// 添加演示用的临时的样式
|
||||||
|
this.addTmpStyles()
|
||||||
// 记录演示前的画布状态
|
// 记录演示前的画布状态
|
||||||
this.transformState = this.mindMap.view.getTransformData()
|
this.transformState = this.mindMap.view.getTransformData()
|
||||||
// 记录演示前的画布数据
|
// 记录演示前的画布数据
|
||||||
@ -79,27 +90,53 @@ class Demonstrate {
|
|||||||
this.transformState = null
|
this.transformState = null
|
||||||
this.stepList = []
|
this.stepList = []
|
||||||
this.currentStepIndex = 0
|
this.currentStepIndex = 0
|
||||||
|
this.currentStepNode = null
|
||||||
|
this.currentUnderlineTextData = null
|
||||||
this.unBindEvent()
|
this.unBindEvent()
|
||||||
|
this.removeTmpStyles()
|
||||||
this.removeHighlightEl()
|
this.removeHighlightEl()
|
||||||
this.mindMap.command.recovery()
|
this.mindMap.command.recovery()
|
||||||
this.mindMap.keyCommand.recovery()
|
this.mindMap.keyCommand.recovery()
|
||||||
this.mindMap.emit('exit_demonstrate')
|
this.mindMap.emit('exit_demonstrate')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加临时的样式
|
||||||
|
addTmpStyles() {
|
||||||
|
this.tmpStyleEl = document.createElement('style')
|
||||||
|
let cssText = `
|
||||||
|
/* 画布所有元素禁止响应鼠标事件 */
|
||||||
|
.smm-mind-map-container {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
/* 超链接图标允许响应鼠标事件 */
|
||||||
|
.smm-node a {
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
/* 备注图标允许响应鼠标事件 */
|
||||||
|
.smm-node .smm-node-note {
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
if (this.config.openBlankMode) {
|
||||||
|
cssText += `
|
||||||
|
/* 带下划线的文本内容全部隐藏 */
|
||||||
|
.smm-richtext-node-wrap u {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
this.tmpStyleEl.innerText = cssText
|
||||||
|
document.head.appendChild(this.tmpStyleEl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移除临时的样式
|
||||||
|
removeTmpStyles() {
|
||||||
|
if (this.tmpStyleEl) document.head.removeChild(this.tmpStyleEl)
|
||||||
|
}
|
||||||
|
|
||||||
// 创建高亮元素
|
// 创建高亮元素
|
||||||
createHighlightEl() {
|
createHighlightEl() {
|
||||||
if (!this.highlightEl) {
|
if (!this.highlightEl) {
|
||||||
// 遮罩元素
|
|
||||||
this.maskEl = document.createElement('div')
|
|
||||||
this.maskEl.style.cssText = `
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
z-index: ${this.config.zIndex};
|
|
||||||
`
|
|
||||||
this.mindMap.el.appendChild(this.maskEl)
|
|
||||||
// 高亮元素
|
// 高亮元素
|
||||||
this.highlightEl = document.createElement('div')
|
this.highlightEl = document.createElement('div')
|
||||||
this.highlightEl.style.cssText = `
|
this.highlightEl.style.cssText = `
|
||||||
@ -108,6 +145,7 @@ class Demonstrate {
|
|||||||
border-radius: ${this.config.borderRadius};
|
border-radius: ${this.config.borderRadius};
|
||||||
transition: ${this.config.transition};
|
transition: ${this.config.transition};
|
||||||
z-index: ${this.config.zIndex + 1};
|
z-index: ${this.config.zIndex + 1};
|
||||||
|
pointer-events: none;
|
||||||
`
|
`
|
||||||
this.mindMap.el.appendChild(this.highlightEl)
|
this.mindMap.el.appendChild(this.highlightEl)
|
||||||
}
|
}
|
||||||
@ -119,10 +157,6 @@ class Demonstrate {
|
|||||||
this.mindMap.el.removeChild(this.highlightEl)
|
this.mindMap.el.removeChild(this.highlightEl)
|
||||||
this.highlightEl = null
|
this.highlightEl = null
|
||||||
}
|
}
|
||||||
if (this.maskEl) {
|
|
||||||
this.mindMap.el.removeChild(this.maskEl)
|
|
||||||
this.maskEl = null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新高亮元素的位置和大小
|
// 更新高亮元素的位置和大小
|
||||||
@ -180,6 +214,9 @@ class Demonstrate {
|
|||||||
} else if (e.keyCode === keyMap.Esc) {
|
} else if (e.keyCode === keyMap.Esc) {
|
||||||
// 退出演示
|
// 退出演示
|
||||||
this.exit()
|
this.exit()
|
||||||
|
} else if (e.keyCode === keyMap.Enter) {
|
||||||
|
// 回车键显示隐藏的下划线文本
|
||||||
|
this.showNextUnderlineText()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,8 +235,31 @@ class Demonstrate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 显示隐藏的下划线文本
|
||||||
|
showNextUnderlineText() {
|
||||||
|
if (
|
||||||
|
!this.config.openBlankMode ||
|
||||||
|
!this.currentStepNode ||
|
||||||
|
!this.currentUnderlineTextData
|
||||||
|
)
|
||||||
|
return
|
||||||
|
const { index, list, length } = this.currentUnderlineTextData
|
||||||
|
if (index >= length) return
|
||||||
|
const node = list[index]
|
||||||
|
this.currentUnderlineTextData.index++
|
||||||
|
node.node.style.opacity = 1
|
||||||
|
}
|
||||||
|
|
||||||
// 跳转到某一张
|
// 跳转到某一张
|
||||||
jump(index) {
|
jump(index) {
|
||||||
|
// 移除该当前下划线元素设置的样式
|
||||||
|
if (this.currentUnderlineTextData) {
|
||||||
|
this.currentUnderlineTextData.list.forEach(item => {
|
||||||
|
item.node.style.opacity = ''
|
||||||
|
})
|
||||||
|
this.currentUnderlineTextData = null
|
||||||
|
}
|
||||||
|
this.currentStepNode = null
|
||||||
this.currentStepIndex = index
|
this.currentStepIndex = index
|
||||||
this.mindMap.emit(
|
this.mindMap.emit(
|
||||||
'demonstrate_jump',
|
'demonstrate_jump',
|
||||||
@ -226,6 +286,16 @@ class Demonstrate {
|
|||||||
}
|
}
|
||||||
// 1.聚焦到某个节点
|
// 1.聚焦到某个节点
|
||||||
if (step.type === 'node') {
|
if (step.type === 'node') {
|
||||||
|
this.currentStepNode = node
|
||||||
|
// 当前节点存在带下划线的文本内容
|
||||||
|
const uNodeList = this.config.openBlankMode ? node.group.find('u') : null
|
||||||
|
if (uNodeList && uNodeList.length > 0) {
|
||||||
|
this.currentUnderlineTextData = {
|
||||||
|
index: 0,
|
||||||
|
list: uNodeList,
|
||||||
|
length: uNodeList.length
|
||||||
|
}
|
||||||
|
}
|
||||||
// 适应画布大小
|
// 适应画布大小
|
||||||
this.mindMap.view.fit(
|
this.mindMap.view.fit(
|
||||||
() => {
|
() => {
|
||||||
|
|||||||
@ -139,6 +139,7 @@ export default {
|
|||||||
top: 20px;
|
top: 20px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
z-index: 10001;
|
z-index: 10001;
|
||||||
|
pointer-events: all;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
font-size: 28px;
|
font-size: 28px;
|
||||||
@ -150,6 +151,7 @@ export default {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
right: 40px;
|
right: 40px;
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
|
pointer-events: all;
|
||||||
|
|
||||||
z-index: 10001;
|
z-index: 10001;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user