Compare commits
12 Commits
0.6.10
...
0.6.11-fix
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d4f1b993e | ||
|
|
b814bd35ca | ||
|
|
c57361a360 | ||
|
|
f8c2a62bd6 | ||
|
|
59241717f5 | ||
|
|
e90509cac9 | ||
|
|
8a8cc26c1d | ||
|
|
1d443b9f94 | ||
|
|
60a4f443a7 | ||
|
|
72c2540dcc | ||
|
|
18cec3b75a | ||
|
|
d4aae5268e |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.6.10",
|
||||
"version": "0.6.11-fix.1",
|
||||
"description": "一个简单的web在线思维导图",
|
||||
"authors": [
|
||||
{
|
||||
|
||||
@@ -137,7 +137,7 @@ export const themeList = [
|
||||
{
|
||||
name: '简约黑',
|
||||
value: 'simpleBlack',
|
||||
dark: true
|
||||
dark: false
|
||||
},
|
||||
{
|
||||
name: '课程绿',
|
||||
|
||||
@@ -266,6 +266,7 @@ class Node {
|
||||
paddingY += this.shapePadding.paddingY
|
||||
// 节点形状
|
||||
this.shapeNode = this.shapeInstance.createShape()
|
||||
this.shapeNode.addClass('smm-node-shape')
|
||||
this.group.add(this.shapeNode)
|
||||
this.updateNodeShape()
|
||||
// 渲染一个隐藏的矩形区域,用来触发展开收起按钮的显示
|
||||
@@ -531,6 +532,7 @@ class Node {
|
||||
isLayout = true
|
||||
// 创建组
|
||||
this.group = new G()
|
||||
this.group.addClass('smm-node')
|
||||
this.group.css({
|
||||
cursor: 'default'
|
||||
})
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { isWhite, isTransparent, getVisibleColorFromTheme } from '../utils/index'
|
||||
|
||||
// 小地图插件
|
||||
class MiniMap {
|
||||
// 构造函数
|
||||
@@ -20,7 +22,7 @@ class MiniMap {
|
||||
* boxHeight:小地图容器的高度
|
||||
*/
|
||||
calculationMiniMap(boxWidth, boxHeight) {
|
||||
let { svgHTML, rect, origWidth, origHeight, scaleX, scaleY } =
|
||||
let { svg, rect, origWidth, origHeight, scaleX, scaleY } =
|
||||
this.mindMap.getSvgData()
|
||||
// 计算数据
|
||||
let boxRatio = boxWidth / boxHeight
|
||||
@@ -65,8 +67,10 @@ class MiniMap {
|
||||
Math.max(0, ((_rectY2 - origHeight) / _rectHeight) * actHeight) +
|
||||
miniMapBoxTop +
|
||||
'px'
|
||||
|
||||
this.removeNodeContent(svg)
|
||||
return {
|
||||
svgHTML, // 小地图html
|
||||
svgHTML: svg.svg(), // 小地图html
|
||||
viewBoxStyle, // 视图框的位置信息
|
||||
miniMapBoxScale, // 视图框的缩放值
|
||||
miniMapBoxLeft, // 视图框的left值
|
||||
@@ -74,6 +78,26 @@ class MiniMap {
|
||||
}
|
||||
}
|
||||
|
||||
// 移除节点的内容
|
||||
removeNodeContent(svg) {
|
||||
if (svg.hasClass('smm-node')) {
|
||||
let shape = svg.findOne('.smm-node-shape')
|
||||
let fill = shape.attr('fill')
|
||||
if (isWhite(fill) || isTransparent(fill)) {
|
||||
shape.attr('fill', getVisibleColorFromTheme(this.mindMap.themeConfig))
|
||||
}
|
||||
svg.clear()
|
||||
svg.add(shape)
|
||||
return
|
||||
}
|
||||
let children = svg.children()
|
||||
if (children && children.length > 0) {
|
||||
children.forEach((node) => {
|
||||
this.removeNodeContent(node)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 小地图鼠标按下事件
|
||||
onMousedown(e) {
|
||||
this.isMousedown = true
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Quill from 'quill'
|
||||
import 'quill/dist/quill.snow.css'
|
||||
import html2canvas from 'html2canvas'
|
||||
import { walk, getTextFromHtml } from '../utils'
|
||||
import { walk, getTextFromHtml, isWhite, getVisibleColorFromTheme } from '../utils'
|
||||
import { CONSTANTS } from '../constants/constant'
|
||||
|
||||
let extended = false
|
||||
@@ -176,11 +176,12 @@ class RichText {
|
||||
}
|
||||
// 使用节点的填充色,否则如果节点颜色是白色的话编辑时看不见
|
||||
let bgColor = node.style.merge('fillColor')
|
||||
let color = node.style.merge('color')
|
||||
this.textEditNode.style.marginLeft = `-${paddingX * scaleX}px`
|
||||
this.textEditNode.style.marginTop = `-${paddingY * scaleY}px`
|
||||
this.textEditNode.style.zIndex = this.mindMap.opt.nodeTextEditZIndex
|
||||
this.textEditNode.style.backgroundColor =
|
||||
bgColor === 'transparent' ? '#fff' : bgColor
|
||||
bgColor === 'transparent' ? isWhite(color) ? getVisibleColorFromTheme(this.mindMap.themeConfig) : '#fff' : bgColor
|
||||
this.textEditNode.style.minWidth = originWidth + paddingX * 2 + 'px'
|
||||
this.textEditNode.style.minHeight = originHeight + 'px'
|
||||
this.textEditNode.style.left = rect.left + 'px'
|
||||
|
||||
@@ -515,4 +515,28 @@ export const replaceHtmlText = (html, searchText, replaceText) => {
|
||||
}
|
||||
walk(replaceHtmlTextEl)
|
||||
return replaceHtmlTextEl.innerHTML
|
||||
}
|
||||
|
||||
// 判断一个颜色是否是白色
|
||||
export const isWhite = (color) => {
|
||||
color = String(color).replaceAll(/\s+/g, '')
|
||||
return ['#fff', '#ffffff', '#FFF', '#FFFFFF', 'rgb(255,255,255)'].includes(color) || /rgba\(255,255,255,[^)]+\)/.test(color)
|
||||
}
|
||||
|
||||
// 判断一个颜色是否是透明
|
||||
export const isTransparent = (color) => {
|
||||
color = String(color).replaceAll(/\s+/g, '')
|
||||
return ['', 'transparent'].includes(color) || /rgba\(\d+,\d+,\d+,0\)/.test(color)
|
||||
}
|
||||
|
||||
// 从当前主题里获取一个非透明非白色的颜色
|
||||
export const getVisibleColorFromTheme = (themeConfig) => {
|
||||
let { lineColor, root, second, node } = themeConfig
|
||||
let list = [lineColor, root.fillColor, root.color, second.fillColor, second.color, node.fillColor, node.color, root.borderColor, second.borderColor, node.borderColor]
|
||||
for(let i = 0; i < list.length; i++) {
|
||||
let color = list[i]
|
||||
if (!isTransparent(color) && !isWhite(color)) {
|
||||
return color
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
web/src/assets/img/darkNightLceBlade.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
web/src/assets/img/lemonBubbles.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
web/src/assets/img/morandi.jpg
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
web/src/assets/img/neonLamp.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
web/src/assets/img/oreo.jpg
Normal file
|
After Width: | Height: | Size: 9.2 KiB |
BIN
web/src/assets/img/rose.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
web/src/assets/img/seaBlueLine.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
web/src/assets/img/shallowSea.jpg
Normal file
|
After Width: | Height: | Size: 10 KiB |
@@ -44,5 +44,13 @@ export const themeMap = {
|
||||
autumn: require('../assets/img/autumn.jpg'),
|
||||
avocado: require('../assets/img/avocado.jpg'),
|
||||
orangeJuice: require('../assets/img/orangeJuice.jpg'),
|
||||
oreo: require('../assets/img/oreo.jpg'),
|
||||
shallowSea: require('../assets/img/shallowSea.jpg'),
|
||||
lemonBubbles: require('../assets/img/lemonBubbles.jpg'),
|
||||
rose: require('../assets/img/rose.jpg'),
|
||||
seaBlueLine: require('../assets/img/seaBlueLine.jpg'),
|
||||
neonLamp: require('../assets/img/neonLamp.jpg'),
|
||||
darkNightLceBlade: require('../assets/img/darkNightLceBlade.jpg'),
|
||||
morandi: require('../assets/img/morandi.jpg'),
|
||||
}
|
||||
|
||||
59
web/src/customThemes/darkNightLceBlade.js
Normal file
@@ -0,0 +1,59 @@
|
||||
// 暗夜冰刃
|
||||
export default {
|
||||
backgroundColor: 'rgb(0, 21, 21)',
|
||||
// 连线的颜色
|
||||
lineColor: 'rgb(0, 139, 146)',
|
||||
lineWidth: 3,
|
||||
// 概要连线的粗细
|
||||
generalizationLineWidth: 3,
|
||||
// 概要连线的颜色
|
||||
generalizationLineColor: 'rgba(2, 167, 240, 0.5)',
|
||||
// 关联线默认状态的颜色
|
||||
associativeLineColor: 'rgb(255, 255, 255)',
|
||||
// 关联线文字颜色
|
||||
associativeLineTextColor: 'rgb(255, 255, 255)',
|
||||
// 根节点样式
|
||||
root: {
|
||||
fillColor: 'rgb(0, 243, 255)',
|
||||
color: 'rgb(0, 21, 21)',
|
||||
borderColor: '#fff',
|
||||
borderWidth: 3,
|
||||
fontSize: 24,
|
||||
shape: 'parallelogram',
|
||||
active: {
|
||||
borderColor: 'rgba(2, 167, 240, 0.5)',
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
second: {
|
||||
fillColor: 'rgb(0, 21, 21)',
|
||||
color: '#fff',
|
||||
borderColor: '#fff',
|
||||
borderWidth: 3,
|
||||
fontSize: 18,
|
||||
shape: 'diamond',
|
||||
active: {
|
||||
borderColor: 'rgba(2, 167, 240, 0.5)',
|
||||
}
|
||||
},
|
||||
// 三级及以下节点样式
|
||||
node: {
|
||||
fontSize: 14,
|
||||
color: '#fff',
|
||||
active: {
|
||||
borderColor: 'rgba(2, 167, 240, 0.5)'
|
||||
}
|
||||
},
|
||||
// 概要节点样式
|
||||
generalization: {
|
||||
fontSize: 14,
|
||||
fillColor: '#fff',
|
||||
borderColor: 'rgb(0, 117, 255)',
|
||||
borderWidth: 2,
|
||||
color: 'rgb(0, 21, 21)',
|
||||
active: {
|
||||
borderColor: 'rgb(0, 243, 255)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,59 @@
|
||||
import simpleBlack from './simpleBlack'
|
||||
import oreo from './oreo'
|
||||
import shallowSea from './shallowSea'
|
||||
import lemonBubbles from './lemonBubbles'
|
||||
import rose from './rose'
|
||||
import seaBlueLine from './seaBlueLine'
|
||||
import neonLamp from './neonLamp'
|
||||
import darkNightLceBlade from './darkNightLceBlade'
|
||||
import morandi from './morandi'
|
||||
|
||||
export default [
|
||||
{
|
||||
name: '简约黑',
|
||||
value: 'simpleBlack',
|
||||
theme: simpleBlack
|
||||
name: '奥利奥',
|
||||
value: 'oreo',
|
||||
theme: oreo,
|
||||
dark: false
|
||||
},
|
||||
{
|
||||
name: '浅海',
|
||||
value: 'shallowSea',
|
||||
theme: shallowSea,
|
||||
dark: false
|
||||
},
|
||||
{
|
||||
name: '柠檬气泡',
|
||||
value: 'lemonBubbles',
|
||||
theme: lemonBubbles,
|
||||
dark: false
|
||||
},
|
||||
{
|
||||
name: '玫瑰',
|
||||
value: 'rose',
|
||||
theme: rose,
|
||||
dark: false
|
||||
},
|
||||
{
|
||||
name: '海蓝线',
|
||||
value: 'seaBlueLine',
|
||||
theme: seaBlueLine,
|
||||
dark: false
|
||||
},
|
||||
{
|
||||
name: '霓虹灯',
|
||||
value: 'neonLamp',
|
||||
theme: neonLamp,
|
||||
dark: true
|
||||
},
|
||||
{
|
||||
name: '暗夜冰刃',
|
||||
value: 'darkNightLceBlade',
|
||||
theme: darkNightLceBlade,
|
||||
dark: true
|
||||
},
|
||||
{
|
||||
name: '莫兰迪',
|
||||
value: 'morandi',
|
||||
theme: morandi,
|
||||
dark: false
|
||||
}
|
||||
]
|
||||
55
web/src/customThemes/lemonBubbles.js
Normal file
@@ -0,0 +1,55 @@
|
||||
// 柠檬气泡
|
||||
export default {
|
||||
backgroundColor: 'rgb(236, 254, 255)',
|
||||
// 连线的颜色
|
||||
lineColor: 'rgb(51, 51, 51)',
|
||||
lineWidth: 3,
|
||||
// 概要连线的粗细
|
||||
generalizationLineWidth: 3,
|
||||
// 概要连线的颜色
|
||||
generalizationLineColor: 'rgb(51, 51, 51)',
|
||||
// 根节点样式
|
||||
root: {
|
||||
fillColor: 'rgb(39, 222, 232)',
|
||||
color: 'rgb(26, 26, 26)',
|
||||
borderColor: 'rgb(26, 26, 26)',
|
||||
borderWidth: 3,
|
||||
fontSize: 24,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(235, 255, 187)',
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
second: {
|
||||
fillColor: 'rgb(235, 255, 187)',
|
||||
color: 'rgb(0, 0, 0)',
|
||||
borderColor: 'rgb(51, 51, 51)',
|
||||
borderWidth: 3,
|
||||
fontSize: 18,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(39, 222, 232)',
|
||||
}
|
||||
},
|
||||
// 三级及以下节点样式
|
||||
node: {
|
||||
fontSize: 14,
|
||||
color: 'rgb(0, 0, 0)',
|
||||
active: {
|
||||
borderColor: 'rgb(39, 222, 232)'
|
||||
}
|
||||
},
|
||||
// 概要节点样式
|
||||
generalization: {
|
||||
fontSize: 14,
|
||||
fillColor: '#fff',
|
||||
borderColor: 'rgb(26, 26, 26)',
|
||||
borderWidth: 2,
|
||||
color: 'rgb(26, 26, 26)',
|
||||
active: {
|
||||
borderColor: 'rgb(39, 222, 232)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
59
web/src/customThemes/morandi.js
Normal file
@@ -0,0 +1,59 @@
|
||||
// 莫兰迪
|
||||
export default {
|
||||
backgroundColor: 'rgb(252, 245, 241)',
|
||||
// 连线的颜色
|
||||
lineColor: 'rgb(144, 114, 110)',
|
||||
lineWidth: 3,
|
||||
// 概要连线的粗细
|
||||
generalizationLineWidth: 3,
|
||||
// 概要连线的颜色
|
||||
generalizationLineColor: 'rgb(128, 154, 151)',
|
||||
// 关联线默认状态的颜色
|
||||
associativeLineColor: 'rgb(166, 124, 106)',
|
||||
// 关联线文字颜色
|
||||
associativeLineTextColor: 'rgb(166, 124, 106)',
|
||||
// 根节点样式
|
||||
root: {
|
||||
fillColor: 'rgb(207, 121, 105)',
|
||||
color: '#fff',
|
||||
borderColor: 'rgb(207, 121, 105)',
|
||||
borderWidth: 3,
|
||||
fontSize: 24,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(172, 202, 199)',
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
second: {
|
||||
fillColor: 'rgb(239, 210, 207)',
|
||||
color: 'rgb(144, 79, 68)',
|
||||
borderColor: 'rgb(222, 186, 183)',
|
||||
borderWidth: 3,
|
||||
fontSize: 18,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(172, 202, 199)',
|
||||
}
|
||||
},
|
||||
// 三级及以下节点样式
|
||||
node: {
|
||||
fontSize: 14,
|
||||
color: 'rgb(131, 90, 64)',
|
||||
active: {
|
||||
borderColor: 'rgb(172, 202, 199)'
|
||||
}
|
||||
},
|
||||
// 概要节点样式
|
||||
generalization: {
|
||||
fontSize: 14,
|
||||
fillColor: 'rgb(172, 202, 199)',
|
||||
borderColor: 'rgb(172, 202, 199)',
|
||||
borderWidth: 2,
|
||||
color: 'rgb(91, 102, 97)',
|
||||
active: {
|
||||
borderColor: 'rgb(207, 121, 105)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
58
web/src/customThemes/neonLamp.js
Normal file
@@ -0,0 +1,58 @@
|
||||
// 霓虹灯
|
||||
export default {
|
||||
backgroundColor: 'rgb(17, 17, 84)',
|
||||
// 连线的颜色
|
||||
lineColor: 'rgb(255, 0, 214)',
|
||||
lineWidth: 3,
|
||||
// 概要连线的粗细
|
||||
generalizationLineWidth: 3,
|
||||
// 概要连线的颜色
|
||||
generalizationLineColor: 'rgb(255, 181, 0)',
|
||||
// 关联线默认状态的颜色
|
||||
associativeLineColor: 'rgb(255, 255, 255)',
|
||||
// 关联线文字颜色
|
||||
associativeLineTextColor: 'rgb(255, 255, 255)',
|
||||
// 根节点样式
|
||||
root: {
|
||||
fillColor: 'rgb(251, 233, 248)',
|
||||
color: 'rgb(208, 5, 176)',
|
||||
borderColor: 'rgb(255, 0, 214)',
|
||||
borderWidth: 3,
|
||||
fontSize: 24,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(255, 181, 0)',
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
second: {
|
||||
fillColor: 'transparent',
|
||||
color: 'rgb(248, 177, 237)',
|
||||
borderColor: '',
|
||||
borderWidth: 3,
|
||||
fontSize: 18,
|
||||
active: {
|
||||
borderColor: 'rgb(255, 181, 0)',
|
||||
}
|
||||
},
|
||||
// 三级及以下节点样式
|
||||
node: {
|
||||
fontSize: 14,
|
||||
color: '#fff',
|
||||
active: {
|
||||
borderColor: 'rgb(255, 181, 0)'
|
||||
}
|
||||
},
|
||||
// 概要节点样式
|
||||
generalization: {
|
||||
fontSize: 14,
|
||||
fillColor: '#fff',
|
||||
borderColor: 'rgb(255, 181, 0)',
|
||||
borderWidth: 2,
|
||||
color: 'rgb(17, 17, 84)',
|
||||
active: {
|
||||
borderColor: 'rgb(255, 0, 214)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
// 简约黑
|
||||
// 奥利奥
|
||||
export default {
|
||||
// 连线的颜色
|
||||
lineColor: 'rgb(34, 34, 34)',
|
||||
lineWidth: 4,
|
||||
lineColor: 'rgb(51, 51, 51)',
|
||||
lineWidth: 3,
|
||||
// 概要连线的粗细
|
||||
generalizationLineWidth: 4,
|
||||
generalizationLineWidth: 3,
|
||||
// 概要连线的颜色
|
||||
generalizationLineColor: 'rgb(34, 34, 34)',
|
||||
generalizationLineColor: 'rgb(51, 51, 51)',
|
||||
// 根节点样式
|
||||
root: {
|
||||
fillColor: '#fff',
|
||||
color: 'rgb(34, 34, 34)',
|
||||
borderColor: 'rgb(34, 34, 34)',
|
||||
fillColor: 'rgb(22, 22, 22)',
|
||||
color: '#fff',
|
||||
borderColor: 'rgb(22, 22, 22)',
|
||||
borderWidth: 3,
|
||||
fontSize: 24,
|
||||
active: {
|
||||
@@ -20,21 +20,22 @@ export default {
|
||||
},
|
||||
// 二级节点样式
|
||||
second: {
|
||||
fillColor: 'rgb(241, 246, 248)',
|
||||
color: 'rgb(34, 34, 34)',
|
||||
borderColor: 'rgb(34, 34, 34)',
|
||||
fillColor: 'rgb(244, 246, 253)',
|
||||
color: 'rgb(0, 0, 0)',
|
||||
borderColor: '',
|
||||
borderWidth: 3,
|
||||
fontSize: 18,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: '#a13600',
|
||||
borderColor: 'rgb(22, 22, 22)',
|
||||
}
|
||||
},
|
||||
// 三级及以下节点样式
|
||||
node: {
|
||||
fontSize: 14,
|
||||
color: 'rgb(34, 34, 34)',
|
||||
color: 'rgb(0, 0, 0)',
|
||||
active: {
|
||||
borderColor: '#a13600'
|
||||
borderColor: 'rgb(22, 22, 22)'
|
||||
}
|
||||
},
|
||||
// 概要节点样式
|
||||
55
web/src/customThemes/rose.js
Normal file
@@ -0,0 +1,55 @@
|
||||
// 玫瑰
|
||||
export default {
|
||||
backgroundColor: 'rgb(255, 251, 231)',
|
||||
// 连线的颜色
|
||||
lineColor: 'rgb(110, 165, 79)',
|
||||
lineWidth: 3,
|
||||
// 概要连线的粗细
|
||||
generalizationLineWidth: 3,
|
||||
// 概要连线的颜色
|
||||
generalizationLineColor: 'rgb(136, 100, 0)',
|
||||
// 根节点样式
|
||||
root: {
|
||||
fillColor: 'rgb(254, 92, 92)',
|
||||
color: '#fff',
|
||||
borderColor: 'rgb(18, 187, 55)',
|
||||
borderWidth: 3,
|
||||
fontSize: 24,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(136, 100, 0)',
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
second: {
|
||||
fillColor: 'rgb(209, 237, 176)',
|
||||
color: 'rgb(85, 136, 55)',
|
||||
borderColor: '',
|
||||
borderWidth: 3,
|
||||
fontSize: 18,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(254, 92, 92)',
|
||||
}
|
||||
},
|
||||
// 三级及以下节点样式
|
||||
node: {
|
||||
fontSize: 14,
|
||||
color: 'rgb(26, 26, 26)',
|
||||
active: {
|
||||
borderColor: 'rgb(209, 237, 176)'
|
||||
}
|
||||
},
|
||||
// 概要节点样式
|
||||
generalization: {
|
||||
fontSize: 14,
|
||||
fillColor: '#fff',
|
||||
borderColor: 'rgb(136, 100, 0)',
|
||||
borderWidth: 2,
|
||||
color: 'rgb(136, 100, 0)',
|
||||
active: {
|
||||
borderColor: 'rgb(254, 92, 92)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
55
web/src/customThemes/seaBlueLine.js
Normal file
@@ -0,0 +1,55 @@
|
||||
// 海蓝线
|
||||
export default {
|
||||
backgroundColor: 'rgb(231, 245, 255)',
|
||||
// 连线的颜色
|
||||
lineColor: 'rgb(96, 189, 255)',
|
||||
lineWidth: 3,
|
||||
// 概要连线的粗细
|
||||
generalizationLineWidth: 3,
|
||||
// 概要连线的颜色
|
||||
generalizationLineColor: 'rgb(0, 155, 255)',
|
||||
// 根节点样式
|
||||
root: {
|
||||
fillColor: 'rgb(96, 189, 255)',
|
||||
color: '#fff',
|
||||
borderColor: '#fff',
|
||||
borderWidth: 3,
|
||||
fontSize: 24,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(0, 155, 255)',
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
second: {
|
||||
fillColor: '#fff',
|
||||
color: 'rgb(0, 149, 255)',
|
||||
borderColor: '',
|
||||
borderWidth: 3,
|
||||
fontSize: 18,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(96, 189, 255)',
|
||||
}
|
||||
},
|
||||
// 三级及以下节点样式
|
||||
node: {
|
||||
fontSize: 14,
|
||||
color: 'rgb(0, 66, 157)',
|
||||
active: {
|
||||
borderColor: 'rgb(96, 189, 255)'
|
||||
}
|
||||
},
|
||||
// 概要节点样式
|
||||
generalization: {
|
||||
fontSize: 14,
|
||||
fillColor: '#fff',
|
||||
borderColor: 'rgb(0, 155, 255)',
|
||||
borderWidth: 2,
|
||||
color: 'rgb(0, 155, 255)',
|
||||
active: {
|
||||
borderColor: 'rgba(2, 167, 240, 0.5)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
54
web/src/customThemes/shallowSea.js
Normal file
@@ -0,0 +1,54 @@
|
||||
// 浅海
|
||||
export default {
|
||||
backgroundColor: 'rgb(187, 241, 250)',
|
||||
// 连线的颜色
|
||||
lineColor: 'rgb(74, 139, 170)',
|
||||
lineWidth: 3,
|
||||
// 概要连线的粗细
|
||||
generalizationLineWidth: 3,
|
||||
// 概要连线的颜色
|
||||
generalizationLineColor: 'rgb(255, 168, 101)',
|
||||
// 根节点样式
|
||||
root: {
|
||||
fillColor: 'rgb(51, 149, 255)',
|
||||
color: '#fff',
|
||||
borderColor: 'rgb(51, 149, 255)',
|
||||
borderWidth: 3,
|
||||
fontSize: 24,
|
||||
shape: 'roundedRectangle',
|
||||
active: {
|
||||
borderColor: 'rgb(255, 168, 101)',
|
||||
}
|
||||
},
|
||||
// 二级节点样式
|
||||
second: {
|
||||
fillColor: 'rgb(74, 139, 170)',
|
||||
color: '#fff',
|
||||
borderColor: '',
|
||||
borderWidth: 3,
|
||||
fontSize: 18,
|
||||
active: {
|
||||
borderColor: 'rgb(255, 168, 101)',
|
||||
}
|
||||
},
|
||||
// 三级及以下节点样式
|
||||
node: {
|
||||
fontSize: 14,
|
||||
color: 'rgb(0, 0, 0)',
|
||||
active: {
|
||||
borderColor: 'rgb(255, 168, 101)'
|
||||
}
|
||||
},
|
||||
// 概要节点样式
|
||||
generalization: {
|
||||
fontSize: 14,
|
||||
fillColor: '#fff',
|
||||
borderColor: 'rgb(255, 168, 101)',
|
||||
borderWidth: 2,
|
||||
color: '#000',
|
||||
active: {
|
||||
borderColor: 'rgb(51, 149, 255)'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
# Changelog
|
||||
|
||||
## 0.6.11-fix.1
|
||||
|
||||
Fix: 1.Fixed the issue of invisible editing when node text is white.
|
||||
|
||||
## 0.6.11
|
||||
|
||||
New: 1.Optimize the mini map, remove node content within the mini map, and optimize performance.
|
||||
|
||||
Demo: 1.Add a new topic and add tab differentiation to the topic list. 2.Node image upload supports inputting network image addresses. 3.Node image upload supports inputting network images.
|
||||
|
||||
## 0.6.10
|
||||
|
||||
Fix: 1.Fix the issue of deleting a node after searching for it and not updating the search results when searching again. 2.Fixed an issue where the button for adjusting image size did not update after node operation. 3.Fix the issue of incorrect internal data deep copy location. 4.Fix the issue of ineffective line wrapping in rich text nodes. 5. Fix the issue of node swapping and loss when switching themes and other scenarios.
|
||||
|
||||
New: 1.Search supports searching for white space characters and replacing them with white space characters.
|
||||
|
||||
Demo: 1.Support calling up search through icon buttons. 2.Support for switching to dark mode through icon buttons. 3.Optimize search: The mouse is not in the search area and not focused, solving the problem of not being able to delete input text when the mouse is not in the search area. 4.Adjust the interface UI for adding node icons and add a series of node icons. 5.Add a sticker list. 6.Fixed the issue of missing focus in the input box after entering the search box. 7.Support clicking on the icon within the node to display an icon for quick replacement and deletion of the floating panel.
|
||||
Demo: 1.Support calling up search through icon buttons. 2.Support for switching to dark mode through icon buttons. 3.Optimize search: The mouse is not in the search area and not focused, solving the problem of not being able to delete input text when the mouse is not in the search area. 4.Adjust the interface UI for adding node icons and add a series of node icons. 5.Add a sticker list. 6.Fixed the issue of missing focus in the input box after entering the search box. 7.Support clicking on the icon within the node to display an icon for quick replacement and deletion of the floating panel.
|
||||
|
||||
## 0.6.9-fix.1
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.6.11-fix.1</h2>
|
||||
<p>Fix: 1.Fixed the issue of invisible editing when node text is white.</p>
|
||||
<h2>0.6.11</h2>
|
||||
<p>New: 1.Optimize the mini map, remove node content within the mini map, and optimize performance.</p>
|
||||
<p>Demo: 1.Add a new topic and add tab differentiation to the topic list. 2.Node image upload supports inputting network image addresses. 3.Node image upload supports inputting network images.</p>
|
||||
<h2>0.6.10</h2>
|
||||
<p>Fix: 1.Fix the issue of deleting a node after searching for it and not updating the search results when searching again. 2.Fixed an issue where the button for adjusting image size did not update after node operation. 3.Fix the issue of incorrect internal data deep copy location. 4.Fix the issue of ineffective line wrapping in rich text nodes. 5. Fix the issue of node swapping and loss when switching themes and other scenarios.</p>
|
||||
<p>New: 1.Search supports searching for white space characters and replacing them with white space characters.</p>
|
||||
|
||||
@@ -220,6 +220,16 @@ Add inline styles to the specified tags in the HTML tag.
|
||||
|
||||
Check if a string is a rich text character.
|
||||
|
||||
#### isWhite(color)
|
||||
|
||||
> v0.6.11+
|
||||
|
||||
Determine whether a color is white.
|
||||
|
||||
#### isTransparent(color)
|
||||
|
||||
Determine whether a color is transparent.
|
||||
|
||||
## Simulate CSS background in Canvas
|
||||
|
||||
Import:
|
||||
|
||||
@@ -154,6 +154,13 @@ and copying the <code>data</code> of the data object, example:</p>
|
||||
<p>v0.6.10+</p>
|
||||
</blockquote>
|
||||
<p>Check if a string is a rich text character.</p>
|
||||
<h4>isWhite(color)</h4>
|
||||
<blockquote>
|
||||
<p>v0.6.11+</p>
|
||||
</blockquote>
|
||||
<p>Determine whether a color is white.</p>
|
||||
<h4>isTransparent(color)</h4>
|
||||
<p>Determine whether a color is transparent.</p>
|
||||
<h2>Simulate CSS background in Canvas</h2>
|
||||
<p>Import:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> drawBackgroundImageToCanvas <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/utils/simulateCSSBackgroundInCanvas'</span>
|
||||
|
||||
@@ -1,12 +1,22 @@
|
||||
# Changelog
|
||||
|
||||
## 0.6.11-fix.1
|
||||
|
||||
修复:1.修复节点文字为白色时编辑的时候看不见的问题。
|
||||
|
||||
## 0.6.11
|
||||
|
||||
新增:1.优化小地图,去除小地图内的节点内容,优化性能。
|
||||
|
||||
Demo:1.新增主题、主题列表新增tab区分。 2.节点图片上传支持输入网络图片地址。 3.节点图片上传支持输入网络图片。
|
||||
|
||||
## 0.6.10
|
||||
|
||||
修复:1.修复搜索定位到某个节点后删除该节点,再次搜索时搜索结果未更新的问题。 2.修复调整图片大小的按钮在节点操作后没有更新的问题。 3.修复内部数据深拷贝位置不正确的问题。 4.修复富文本节点换行不生效的问题。 5.修复切换主题等场景时节点换行会丢失的问题。
|
||||
|
||||
新增:1.搜索支持搜索空白字符和替换为空白字符。
|
||||
|
||||
Demo:1.支持通过图标按钮调出搜索。 2.支持通过图标按钮切换暗黑模式。 3.优化搜索:鼠标不在搜索区域内不聚焦,解决鼠标不在搜索区域内无法删除输入的文字的问题。 4.调整添加节点图标的界面UI,新增系列节点图标。 5.新增贴纸列表。 6.修复在搜索框回车后输入框焦点丢失的问题。 7.支持点击节点内的图标显示一个图标快捷替换和删除悬浮面板。
|
||||
Demo:1.支持通过图标按钮调出搜索。 2.支持通过图标按钮切换暗黑模式。 3.优化搜索:鼠标不在搜索区域内不聚焦,解决鼠标不在搜索区域内无法删除输入的文字的问题。 4.调整添加节点图标的界面UI,新增系列节点图标。 5.新增贴纸列表。 6.修复在搜索框回车后输入框焦点丢失的问题。 7.支持点击节点内的图标显示一个图标快捷替换和删除悬浮面板。
|
||||
|
||||
## 0.6.9-fix.1
|
||||
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.6.11-fix.1</h2>
|
||||
<p>修复:1.修复节点文字为白色时编辑的时候看不见的问题。</p>
|
||||
<h2>0.6.11</h2>
|
||||
<p>新增:1.优化小地图,去除小地图内的节点内容,优化性能。</p>
|
||||
<p>Demo:1.新增主题、主题列表新增tab区分。 2.节点图片上传支持输入网络图片地址。 3.节点图片上传支持输入网络图片。</p>
|
||||
<h2>0.6.10</h2>
|
||||
<p>修复:1.修复搜索定位到某个节点后删除该节点,再次搜索时搜索结果未更新的问题。 2.修复调整图片大小的按钮在节点操作后没有更新的问题。 3.修复内部数据深拷贝位置不正确的问题。 4.修复富文本节点换行不生效的问题。 5.修复切换主题等场景时节点换行会丢失的问题。</p>
|
||||
<p>新增:1.搜索支持搜索空白字符和替换为空白字符。</p>
|
||||
|
||||
@@ -215,6 +215,18 @@ copyNodeTree({}, node)
|
||||
|
||||
检查一个字符串是否是富文本字符。
|
||||
|
||||
#### isWhite(color)
|
||||
|
||||
> v0.6.11+
|
||||
|
||||
判断一个颜色是否是白色。
|
||||
|
||||
#### isTransparent(color)
|
||||
|
||||
判断一个颜色是否是透明。
|
||||
|
||||
> v0.6.11+
|
||||
|
||||
## 在canvas中模拟css的背景属性
|
||||
|
||||
引入:
|
||||
|
||||
@@ -149,6 +149,16 @@
|
||||
<p>v0.6.10+</p>
|
||||
</blockquote>
|
||||
<p>检查一个字符串是否是富文本字符。</p>
|
||||
<h4>isWhite(color)</h4>
|
||||
<blockquote>
|
||||
<p>v0.6.11+</p>
|
||||
</blockquote>
|
||||
<p>判断一个颜色是否是白色。</p>
|
||||
<h4>isTransparent(color)</h4>
|
||||
<p>判断一个颜色是否是透明。</p>
|
||||
<blockquote>
|
||||
<p>v0.6.11+</p>
|
||||
</blockquote>
|
||||
<h2>在canvas中模拟css的背景属性</h2>
|
||||
<p>引入:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> drawBackgroundImageToCanvas <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/utils/simulateCSSBackgroundInCanvas'</span>
|
||||
|
||||
@@ -83,9 +83,9 @@ MindMap
|
||||
.usePlugin(SearchPlugin)
|
||||
|
||||
// 注册自定义主题
|
||||
// customThemeList.forEach((item) => {
|
||||
// MindMap.defineTheme(item.value, item.theme)
|
||||
// })
|
||||
customThemeList.forEach((item) => {
|
||||
MindMap.defineTheme(item.value, item.theme)
|
||||
})
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
|
||||
@@ -5,9 +5,16 @@
|
||||
:visible.sync="dialogVisible"
|
||||
width="500"
|
||||
>
|
||||
<ImgUpload ref="ImgUpload" v-model="img"></ImgUpload>
|
||||
<div class="imgTitleBox">
|
||||
<span class="title">{{ $t('nodeImage.imgTitle') }}</span>
|
||||
<div class="title">方式一</div>
|
||||
<ImgUpload ref="ImgUpload" v-model="img" style="margin-bottom: 12px;"></ImgUpload>
|
||||
<div class="title">方式二</div>
|
||||
<div class="inputBox">
|
||||
<span class="label">请输入图片地址</span>
|
||||
<el-input v-model="imgUrl" size="mini" placeholder="http://xxx.com/xx.jpg"></el-input>
|
||||
</div>
|
||||
<div class="title">可选</div>
|
||||
<div class="inputBox">
|
||||
<span class="label">{{ $t('nodeImage.imgTitle') }}</span>
|
||||
<el-input v-model="imgTitle" size="mini"></el-input>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
@@ -21,6 +28,7 @@
|
||||
|
||||
<script>
|
||||
import ImgUpload from '@/components/ImgUpload'
|
||||
import { getImageSize } from 'simple-mind-map/src/utils/index'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -36,6 +44,7 @@ export default {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
img: '',
|
||||
imgUrl: '',
|
||||
imgTitle: '',
|
||||
activeNodes: null
|
||||
}
|
||||
@@ -43,43 +52,54 @@ export default {
|
||||
created() {
|
||||
this.$bus.$on('node_active', (...args) => {
|
||||
this.activeNodes = args[1]
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
this.img = firstNode.getData('image')
|
||||
this.imgTitle = firstNode.getData('imageTitle')
|
||||
} else {
|
||||
this.img = ''
|
||||
this.imgTitle = ''
|
||||
}
|
||||
})
|
||||
this.$bus.$on('showNodeImage', () => {
|
||||
this.reset()
|
||||
if (this.activeNodes.length > 0) {
|
||||
let firstNode = this.activeNodes[0]
|
||||
let img = firstNode.getData('image')
|
||||
if (img) {
|
||||
if (/^https?:\/\//.test(img)) {
|
||||
this.imgUrl = img
|
||||
} else {
|
||||
this.img = img
|
||||
}
|
||||
}
|
||||
this.imgTitle = firstNode.getData('imageTitle')
|
||||
}
|
||||
this.dialogVisible = true
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-22 22:08:11
|
||||
* @Desc: 取消
|
||||
*/
|
||||
cancel() {
|
||||
this.dialogVisible = false
|
||||
this.reset()
|
||||
},
|
||||
|
||||
reset() {
|
||||
this.img = ''
|
||||
this.imgTitle = ''
|
||||
this.imgUrl = ''
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-06 22:28:20
|
||||
* @Desc: 确定
|
||||
*/
|
||||
async confirm() {
|
||||
try {
|
||||
let { width, height } = await this.$refs.ImgUpload.getSize()
|
||||
if (!this.img && !this.imgUrl) return
|
||||
let res = null
|
||||
let img = ''
|
||||
if (this.img) {
|
||||
img = this.img
|
||||
res = await this.$refs.ImgUpload.getSize()
|
||||
} else if (this.imgUrl) {
|
||||
img = this.imgUrl
|
||||
res = await getImageSize(img)
|
||||
}
|
||||
this.activeNodes.forEach(node => {
|
||||
node.setImage({
|
||||
url: this.img || 'none',
|
||||
url: img || 'none',
|
||||
title: this.imgTitle,
|
||||
width,
|
||||
height
|
||||
width: res.width,
|
||||
height: res.height
|
||||
})
|
||||
})
|
||||
this.cancel()
|
||||
@@ -93,13 +113,18 @@ export default {
|
||||
|
||||
<style lang="less" scoped>
|
||||
.nodeDialog {
|
||||
.imgTitleBox {
|
||||
.title {
|
||||
font-size: 18px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.inputBox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.title {
|
||||
width: 100px;
|
||||
.label {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
<template>
|
||||
<Sidebar ref="sidebar" :title="$t('theme.title')">
|
||||
<div class="themeList" :class="{ isDark: isDark }">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane v-for="group in groupList" :key="group.name" :label="group.name" :name="group.name"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div
|
||||
class="themeItem"
|
||||
v-for="item in themeList"
|
||||
v-for="item in currentList"
|
||||
:key="item.value"
|
||||
@click="useTheme(item)"
|
||||
:class="{ active: item.value === theme }"
|
||||
@@ -42,13 +45,21 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
themeList: [...themeList].reverse(), // ...customThemeList
|
||||
themeList: [...themeList, ...customThemeList].reverse(),
|
||||
themeMap,
|
||||
theme: ''
|
||||
theme: '',
|
||||
activeName: '',
|
||||
groupList: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['activeSidebar', 'isDark'])
|
||||
...mapState(['activeSidebar', 'isDark']),
|
||||
|
||||
currentList() {
|
||||
return this.groupList.find((item) => {
|
||||
return item.name === this.activeName
|
||||
}).list
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
@@ -62,12 +73,43 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initGroup()
|
||||
this.theme = this.mindMap.getTheme()
|
||||
this.handleDark()
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setIsDark']),
|
||||
|
||||
initGroup() {
|
||||
let baiduThemes = ['default', 'skyGreen', 'classic2', 'classic3', 'classicGreen', 'classicBlue', 'blueSky', 'brainImpairedPink', 'earthYellow', 'freshGreen', 'freshRed', 'romanticPurple', 'pinkGrape', 'mint']
|
||||
let baiduList = []
|
||||
let classicsList = []
|
||||
this.themeList.forEach((item) => {
|
||||
if (baiduThemes.includes(item.value)) {
|
||||
baiduList.push(item)
|
||||
} else if (!item.dark) {
|
||||
classicsList.push(item)
|
||||
}
|
||||
})
|
||||
this.groupList = [
|
||||
{
|
||||
name: '经典',
|
||||
list: classicsList
|
||||
},
|
||||
{
|
||||
name: '深色',
|
||||
list: this.themeList.filter((item) => {
|
||||
return item.dark
|
||||
})
|
||||
},
|
||||
{
|
||||
name: '朴素',
|
||||
list: baiduList
|
||||
}
|
||||
]
|
||||
this.activeName = this.groupList[0].name
|
||||
},
|
||||
|
||||
useTheme(theme) {
|
||||
this.theme = theme.value
|
||||
this.handleDark()
|
||||
@@ -102,7 +144,7 @@ export default {
|
||||
},
|
||||
|
||||
handleDark() {
|
||||
let target = themeList.find(item => {
|
||||
let target = this.themeList.find(item => {
|
||||
return item.value === this.theme
|
||||
})
|
||||
this.setIsDark(target.dark)
|
||||
@@ -114,6 +156,7 @@ export default {
|
||||
<style lang="less" scoped>
|
||||
.themeList {
|
||||
padding: 20px;
|
||||
padding-top: 0;
|
||||
|
||||
&.isDark {
|
||||
.name {
|
||||
|
||||