mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-25 04:12:42 +08:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04001fd181 | ||
|
|
7fc42879c7 | ||
|
|
c4c9f9421c | ||
|
|
4b246f7106 | ||
|
|
621e62af4c | ||
|
|
3df6538c86 | ||
|
|
fea7d32c97 | ||
|
|
c31a67e7bd | ||
|
|
f451d37254 | ||
|
|
377e507fd9 |
14
README.md
14
README.md
@@ -423,6 +423,14 @@ v0.1.5+
|
||||
|
||||
将节点移动到另一个节点的后面
|
||||
|
||||
#### moveNodeToCenter(node)
|
||||
|
||||
v0.2.17+
|
||||
|
||||
移动节点到画布中心。
|
||||
|
||||
目前如果是存在缩放的情况下回到中心会重置缩放。
|
||||
|
||||
## keyCommand实例
|
||||
|
||||
`keyCommand`实例负责快捷键的添加及触发,内置了一些快捷键,也可以自行添加。可通过`mindMap.keyCommand`获取到该实例。
|
||||
@@ -550,6 +558,12 @@ v0.1.1+
|
||||
|
||||
动态设置变换数据,可以通过getTransformData方法获取变换数据
|
||||
|
||||
#### setScale(scale)
|
||||
|
||||
v0.2.17+
|
||||
|
||||
设置缩放
|
||||
|
||||
## MiniMap实例
|
||||
|
||||
v0.2.11+
|
||||
|
||||
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>一个简单的web思维导图实现</title><link href="dist/js/chunk-2d20ec02.81d632f4.js" rel="prefetch"><link href="dist/js/chunk-2d216b67.228f2009.js" rel="prefetch"><link href="dist/js/chunk-35b0a040.cb76da7d.js" rel="prefetch"><link href="dist/css/app.80644c67.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.faba1249.css" rel="preload" as="style"><link href="dist/js/app.e664c97c.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.0c7365d5.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.faba1249.css" rel="stylesheet"><link href="dist/css/app.80644c67.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="dist/js/chunk-vendors.0c7365d5.js"></script><script src="dist/js/app.e664c97c.js"></script></body></html>
|
||||
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><title>一个简单的web思维导图实现</title><link href="dist/js/chunk-2d20ec02.81d632f4.js" rel="prefetch"><link href="dist/js/chunk-2d216b67.228f2009.js" rel="prefetch"><link href="dist/js/chunk-35b0a040.cb76da7d.js" rel="prefetch"><link href="dist/css/app.2784db23.css" rel="preload" as="style"><link href="dist/css/chunk-vendors.faba1249.css" rel="preload" as="style"><link href="dist/js/app.77dbe506.js" rel="preload" as="script"><link href="dist/js/chunk-vendors.013a6cea.js" rel="preload" as="script"><link href="dist/css/chunk-vendors.faba1249.css" rel="stylesheet"><link href="dist/css/app.2784db23.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but thoughts doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="dist/js/chunk-vendors.013a6cea.js"></script><script src="dist/js/app.77dbe506.js"></script></body></html>
|
||||
@@ -15,6 +15,7 @@ import { layoutValueList } from './src/utils/constant'
|
||||
import { SVG } from '@svgdotjs/svg.js'
|
||||
import xmind from './src/parse/xmind'
|
||||
import { simpleDeepClone } from './src/utils'
|
||||
import KeyboardNavigation from './src/KeyboardNavigation'
|
||||
|
||||
// 默认选项配置
|
||||
const defaultOpt = {
|
||||
@@ -133,6 +134,11 @@ class MindMap {
|
||||
mindMap: this
|
||||
})
|
||||
|
||||
// 键盘导航类
|
||||
this.keyboardNavigation = new KeyboardNavigation({
|
||||
mindMap: this
|
||||
})
|
||||
|
||||
// 批量执行类
|
||||
this.batchExecution = new BatchExecution()
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.2.16",
|
||||
"version": "0.2.17",
|
||||
"description": "一个简单的web在线思维导图",
|
||||
"authors": [
|
||||
{
|
||||
|
||||
@@ -48,6 +48,7 @@ class Event extends EventEmitter {
|
||||
this.onMousewheel = this.onMousewheel.bind(this)
|
||||
this.onContextmenu = this.onContextmenu.bind(this)
|
||||
this.onSvgMousedown = this.onSvgMousedown.bind(this)
|
||||
this.onKeyup = this.onKeyup.bind(this)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -69,6 +70,7 @@ class Event extends EventEmitter {
|
||||
this.mindMap.el.addEventListener('mousewheel', this.onMousewheel)
|
||||
}
|
||||
this.mindMap.svg.on('contextmenu', this.onContextmenu)
|
||||
window.addEventListener('keyup', this.onKeyup)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,6 +86,7 @@ class Event extends EventEmitter {
|
||||
window.removeEventListener('mouseup', this.onMouseup)
|
||||
this.mindMap.el.removeEventListener('mousewheel', this.onMousewheel)
|
||||
this.mindMap.svg.off('contextmenu', this.onContextmenu)
|
||||
window.removeEventListener('keyup', this.onKeyup)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -177,6 +180,16 @@ class Event extends EventEmitter {
|
||||
e.preventDefault()
|
||||
this.emit('contextmenu', e)
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 11:12:11
|
||||
* @Desc: 按键松开事件
|
||||
*/
|
||||
onKeyup(e) {
|
||||
this.emit('keyup', e)
|
||||
}
|
||||
}
|
||||
|
||||
export default Event
|
||||
|
||||
133
simple-mind-map/src/KeyboardNavigation.js
Normal file
133
simple-mind-map/src/KeyboardNavigation.js
Normal file
@@ -0,0 +1,133 @@
|
||||
import { isKey } from './utils/keyMap'
|
||||
import { bfsWalk } from './utils'
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 11:06:50
|
||||
* @Desc: 键盘导航类
|
||||
*/
|
||||
export default class KeyboardNavigation {
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 11:07:24
|
||||
* @Desc: 构造函数
|
||||
*/
|
||||
constructor(opt) {
|
||||
this.opt = opt
|
||||
this.mindMap = opt.mindMap
|
||||
this.onKeyup = this.onKeyup.bind(this)
|
||||
this.mindMap.on('keyup', this.onKeyup)
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 14:12:27
|
||||
* @Desc: 处理按键事件
|
||||
*/
|
||||
onKeyup(e) {
|
||||
if (this.mindMap.renderer.activeNodeList.length > 0) {
|
||||
;['Left', 'Up', 'Right', 'Down'].forEach(dir => {
|
||||
if (isKey(e, dir)) {
|
||||
this.focus(dir)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
let root = this.mindMap.renderer.root
|
||||
this.mindMap.renderer.moveNodeToCenter(root)
|
||||
root.active()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 14:12:39
|
||||
* @Desc: 聚焦到下一个节点
|
||||
*/
|
||||
focus(dir) {
|
||||
let currentActiveNode = this.mindMap.renderer.activeNodeList[0]
|
||||
let currentActiveNodeRect = this.getNodeRect(currentActiveNode)
|
||||
let targetNode = null
|
||||
let targetDis = Infinity
|
||||
let checkNodeDis = (rect, node) => {
|
||||
let dis = this.getDistance(currentActiveNodeRect, rect)
|
||||
if (dis < targetDis) {
|
||||
targetNode = node
|
||||
targetDis = dis
|
||||
}
|
||||
}
|
||||
bfsWalk(this.mindMap.renderer.root, node => {
|
||||
let rect = this.getNodeRect(node)
|
||||
let { left, top, right, bottom } = rect
|
||||
if (dir === 'Right') {
|
||||
if (left >= currentActiveNodeRect.right) {
|
||||
checkNodeDis(rect, node)
|
||||
}
|
||||
} else if (dir === 'Left') {
|
||||
if (right <= currentActiveNodeRect.left) {
|
||||
checkNodeDis(rect, node)
|
||||
}
|
||||
} else if (dir === 'Up') {
|
||||
if (bottom <= currentActiveNodeRect.top) {
|
||||
checkNodeDis(rect, node)
|
||||
}
|
||||
} else if (dir === 'Down') {
|
||||
if (top >= currentActiveNodeRect.bottom) {
|
||||
checkNodeDis(rect, node)
|
||||
}
|
||||
}
|
||||
})
|
||||
if (targetNode) {
|
||||
this.mindMap.renderer.moveNodeToCenter(targetNode)
|
||||
targetNode.active()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 14:12:50
|
||||
* @Desc: 获取节点的位置信息
|
||||
*/
|
||||
getNodeRect(node) {
|
||||
let { scaleX, scaleY, translateX, translateY } =
|
||||
this.mindMap.draw.transform()
|
||||
let { left, top, width, height } = node
|
||||
return {
|
||||
right: (left + width) * scaleX + translateX,
|
||||
bottom: (top + height) * scaleY + translateY,
|
||||
left: left * scaleX + translateX,
|
||||
top: top * scaleY + translateY
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 14:13:04
|
||||
* @Desc: 获取两个节点的距离
|
||||
*/
|
||||
getDistance(node1Rect, node2Rect) {
|
||||
let center1 = this.getCenter(node1Rect)
|
||||
let center2 = this.getCenter(node2Rect)
|
||||
return Math.sqrt(
|
||||
Math.pow(center1.x - center2.x, 2) + Math.pow(center1.y - center2.y, 2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 14:13:11
|
||||
* @Desc: 获取节点的中心点
|
||||
*/
|
||||
getCenter({ left, right, top, bottom }) {
|
||||
return {
|
||||
x: (left + right) / 2,
|
||||
y: (top + bottom) / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1097,6 +1097,28 @@ class Render {
|
||||
this.mindMap.render()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 11:46:57
|
||||
* @Desc: 移动节点到画布中心
|
||||
*/
|
||||
moveNodeToCenter(node) {
|
||||
let halfWidth = this.mindMap.width / 2
|
||||
let halfHeight = this.mindMap.height / 2
|
||||
let { left, top, width, height } = node
|
||||
let nodeCenterX = left + width / 2
|
||||
let nodeCenterY = top + height / 2
|
||||
let { state } = this.mindMap.view.getTransformData()
|
||||
let targetX = halfWidth - state.x
|
||||
let targetY = halfHeight - state.y
|
||||
let offsetX = targetX - nodeCenterX
|
||||
let offsetY = targetY - nodeCenterY
|
||||
this.mindMap.view.translateX(offsetX)
|
||||
this.mindMap.view.translateY(offsetY)
|
||||
this.mindMap.view.setScale(1)
|
||||
}
|
||||
}
|
||||
|
||||
export default Render
|
||||
|
||||
@@ -88,6 +88,9 @@ export default class TextEdit {
|
||||
this.textEditNode = document.createElement('div')
|
||||
this.textEditNode.style.cssText = `position:fixed;box-sizing: border-box;background-color:#fff;box-shadow: 0 0 20px rgba(0,0,0,.5);padding: 3px 5px;margin-left: -5px;margin-top: -3px;outline: none;`
|
||||
this.textEditNode.setAttribute('contenteditable', true)
|
||||
this.textEditNode.addEventListener('keyup', e => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
document.body.appendChild(this.textEditNode)
|
||||
}
|
||||
node.style.domText(this.textEditNode, this.mindMap.view.scale)
|
||||
|
||||
@@ -213,6 +213,18 @@ class View {
|
||||
this.transform()
|
||||
this.mindMap.emit('scale', this.scale)
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-12-09 16:31:59
|
||||
* @Desc: 设置缩放
|
||||
*/
|
||||
setScale(scale) {
|
||||
this.scale = scale
|
||||
this.transform()
|
||||
this.mindMap.emit('scale', this.scale)
|
||||
}
|
||||
}
|
||||
|
||||
export default View
|
||||
|
||||
@@ -6,4 +6,6 @@ public
|
||||
*.md
|
||||
.eslintrc.js
|
||||
.prettierignore
|
||||
.prettierrc
|
||||
.prettierrc
|
||||
package-lock.json
|
||||
package.json
|
||||
@@ -7,7 +7,7 @@
|
||||
"build": "vue-cli-service build && node ../copy.js",
|
||||
"lint": "vue-cli-service lint",
|
||||
"buildLibrary": "vue-cli-service build --target lib --name simpleMindMap ../simple-mind-map/index.js --dest ../simple-mind-map/dist",
|
||||
"format": "prettier --write src/**"
|
||||
"format": "prettier --write src/* src/*/* src/*/*/* src/*/*/*/*"
|
||||
},
|
||||
"dependencies": {
|
||||
"@toast-ui/editor": "^3.1.5",
|
||||
@@ -15,6 +15,7 @@
|
||||
"element-ui": "^2.15.1",
|
||||
"v-viewer": "^1.6.4",
|
||||
"vue": "^2.6.11",
|
||||
"vue-i18n": "^8.27.2",
|
||||
"vue-router": "^3.5.1",
|
||||
"vuex": "^3.6.2",
|
||||
"xlsx": "^0.18.5"
|
||||
|
||||
@@ -3,6 +3,8 @@ import { simpleDeepClone } from 'simple-mind-map/src/utils/index'
|
||||
import Vue from 'vue'
|
||||
|
||||
const SIMPLE_MIND_MAP_DATA = 'SIMPLE_MIND_MAP_DATA'
|
||||
const SIMPLE_MIND_MAP_LANG = 'SIMPLE_MIND_MAP_LANG'
|
||||
const SIMPLE_MIND_MAP_LOCAL_CONFIG = 'SIMPLE_MIND_MAP_LOCAL_CONFIG'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -75,3 +77,52 @@ export const storeConfig = config => {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林
|
||||
* @Date: 2022-11-05 14:36:50
|
||||
* @Desc: 存储语言
|
||||
*/
|
||||
export const storeLang = lang => {
|
||||
localStorage.setItem(SIMPLE_MIND_MAP_LANG, lang)
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林
|
||||
* @Date: 2022-11-05 14:37:36
|
||||
* @Desc: 获取存储的语言
|
||||
*/
|
||||
export const getLang = () => {
|
||||
let lang = localStorage.getItem(SIMPLE_MIND_MAP_LANG)
|
||||
if (lang) {
|
||||
return lang
|
||||
}
|
||||
storeLang('zh')
|
||||
return 'zh'
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 18:57:31
|
||||
* @Desc: 存储本地配置
|
||||
*/
|
||||
export const storeLocalConfig = config => {
|
||||
localStorage.setItem(SIMPLE_MIND_MAP_LOCAL_CONFIG, JSON.stringify(config))
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 18:57:37
|
||||
* @Desc: 获取本地配置
|
||||
*/
|
||||
export const getLocalConfig = () => {
|
||||
let config = localStorage.getItem(SIMPLE_MIND_MAP_LOCAL_CONFIG)
|
||||
if (config) {
|
||||
return JSON.parse(config)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
@@ -1,19 +1,15 @@
|
||||
/* Logo 字体 */
|
||||
@font-face {
|
||||
font-family: 'iconfont logo';
|
||||
font-family: "iconfont logo";
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix')
|
||||
format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834')
|
||||
format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834')
|
||||
format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont')
|
||||
format('svg');
|
||||
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
|
||||
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.logo {
|
||||
font-family: 'iconfont logo';
|
||||
font-family: "iconfont logo";
|
||||
font-size: 160px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
@@ -52,6 +48,7 @@
|
||||
color: #666;
|
||||
}
|
||||
|
||||
|
||||
#tabs .active {
|
||||
border-bottom-color: #f00;
|
||||
color: #222;
|
||||
@@ -218,35 +215,35 @@
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.markdown > p,
|
||||
.markdown > blockquote,
|
||||
.markdown > .highlight,
|
||||
.markdown > ol,
|
||||
.markdown > ul {
|
||||
.markdown>p,
|
||||
.markdown>blockquote,
|
||||
.markdown>.highlight,
|
||||
.markdown>ol,
|
||||
.markdown>ul {
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.markdown ul > li {
|
||||
.markdown ul>li {
|
||||
list-style: circle;
|
||||
}
|
||||
|
||||
.markdown > ul li,
|
||||
.markdown blockquote ul > li {
|
||||
.markdown>ul li,
|
||||
.markdown blockquote ul>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
|
||||
.markdown > ul li p,
|
||||
.markdown > ol li p {
|
||||
.markdown>ul li p,
|
||||
.markdown>ol li p {
|
||||
margin: 0.6em 0;
|
||||
}
|
||||
|
||||
.markdown ol > li {
|
||||
.markdown ol>li {
|
||||
list-style: decimal;
|
||||
}
|
||||
|
||||
.markdown > ol li,
|
||||
.markdown blockquote ol > li {
|
||||
.markdown>ol li,
|
||||
.markdown blockquote ol>li {
|
||||
margin-left: 20px;
|
||||
padding-left: 4px;
|
||||
}
|
||||
@@ -263,7 +260,7 @@
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown > table {
|
||||
.markdown>table {
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0px;
|
||||
empty-cells: show;
|
||||
@@ -272,21 +269,21 @@
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.markdown > table th {
|
||||
.markdown>table th {
|
||||
white-space: nowrap;
|
||||
color: #333;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown > table th,
|
||||
.markdown > table td {
|
||||
.markdown>table th,
|
||||
.markdown>table td {
|
||||
border: 1px solid #e9e9e9;
|
||||
padding: 8px 16px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown > table th {
|
||||
background: #f7f7f7;
|
||||
.markdown>table th {
|
||||
background: #F7F7F7;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
@@ -321,11 +318,12 @@
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.markdown > br,
|
||||
.markdown > p > br {
|
||||
.markdown>br,
|
||||
.markdown>p>br {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
background: white;
|
||||
@@ -401,8 +399,8 @@ https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javasc
|
||||
* Based on dabblet (http://dabblet.com)
|
||||
* @author Lea Verou
|
||||
*/
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
color: black;
|
||||
background: none;
|
||||
text-shadow: 0 1px white;
|
||||
@@ -424,45 +422,46 @@ pre[class*='language-'] {
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre[class*='language-']::-moz-selection,
|
||||
pre[class*='language-'] ::-moz-selection,
|
||||
code[class*='language-']::-moz-selection,
|
||||
code[class*='language-'] ::-moz-selection {
|
||||
pre[class*="language-"]::-moz-selection,
|
||||
pre[class*="language-"] ::-moz-selection,
|
||||
code[class*="language-"]::-moz-selection,
|
||||
code[class*="language-"] ::-moz-selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
pre[class*='language-']::selection,
|
||||
pre[class*='language-'] ::selection,
|
||||
code[class*='language-']::selection,
|
||||
code[class*='language-'] ::selection {
|
||||
pre[class*="language-"]::selection,
|
||||
pre[class*="language-"] ::selection,
|
||||
code[class*="language-"]::selection,
|
||||
code[class*="language-"] ::selection {
|
||||
text-shadow: none;
|
||||
background: #b3d4fc;
|
||||
}
|
||||
|
||||
@media print {
|
||||
code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
|
||||
code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
text-shadow: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Code blocks */
|
||||
pre[class*='language-'] {
|
||||
pre[class*="language-"] {
|
||||
padding: 1em;
|
||||
margin: 0.5em 0;
|
||||
margin: .5em 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre) > code[class*='language-'],
|
||||
pre[class*='language-'] {
|
||||
:not(pre)>code[class*="language-"],
|
||||
pre[class*="language-"] {
|
||||
background: #f5f2f0;
|
||||
}
|
||||
|
||||
/* Inline code */
|
||||
:not(pre) > code[class*='language-'] {
|
||||
padding: 0.1em;
|
||||
border-radius: 0.3em;
|
||||
:not(pre)>code[class*="language-"] {
|
||||
padding: .1em;
|
||||
border-radius: .3em;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
@@ -478,7 +477,7 @@ pre[class*='language-'] {
|
||||
}
|
||||
|
||||
.namespace {
|
||||
opacity: 0.7;
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.property,
|
||||
@@ -506,7 +505,7 @@ pre[class*='language-'] {
|
||||
.language-css .token.string,
|
||||
.style .token.string {
|
||||
color: #9a6e3a;
|
||||
background: hsla(0, 0%, 100%, 0.5);
|
||||
background: hsla(0, 0%, 100%, .5);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
@@ -517,7 +516,7 @@ pre[class*='language-'] {
|
||||
|
||||
.token.function,
|
||||
.token.class-name {
|
||||
color: #dd4a68;
|
||||
color: #DD4A68;
|
||||
}
|
||||
|
||||
.token.regex,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,186 +1,195 @@
|
||||
@font-face {
|
||||
font-family: 'iconfont'; /* Project id 2479351 */
|
||||
src: url('iconfont.woff2?t=1664005697217') format('woff2'),
|
||||
url('iconfont.woff?t=1664005697217') format('woff'),
|
||||
url('iconfont.ttf?t=1664005697217') format('truetype');
|
||||
font-family: "iconfont"; /* Project id 2479351 */
|
||||
src: url('iconfont.woff2?t=1668512547595') format('woff2'),
|
||||
url('iconfont.woff?t=1668512547595') format('woff'),
|
||||
url('iconfont.ttf?t=1668512547595') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: 'iconfont' !important;
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.iconchoose1:before {
|
||||
content: "\e6c5";
|
||||
}
|
||||
|
||||
.iconzhuti:before {
|
||||
content: "\e7aa";
|
||||
}
|
||||
|
||||
.icondaochu1:before {
|
||||
content: '\e63e';
|
||||
content: "\e63e";
|
||||
}
|
||||
|
||||
.iconlingcunwei:before {
|
||||
content: '\e657';
|
||||
content: "\e657";
|
||||
}
|
||||
|
||||
.iconexport:before {
|
||||
content: '\e642';
|
||||
content: "\e642";
|
||||
}
|
||||
|
||||
.icondakai:before {
|
||||
content: '\ebdf';
|
||||
content: "\ebdf";
|
||||
}
|
||||
|
||||
.iconxinjian:before {
|
||||
content: '\e64e';
|
||||
content: "\e64e";
|
||||
}
|
||||
|
||||
.iconjianqie:before {
|
||||
content: '\e601';
|
||||
content: "\e601";
|
||||
}
|
||||
|
||||
.iconzhengli:before {
|
||||
content: '\e83b';
|
||||
content: "\e83b";
|
||||
}
|
||||
|
||||
.iconfuzhi:before {
|
||||
content: '\e604';
|
||||
content: "\e604";
|
||||
}
|
||||
|
||||
.iconniantie:before {
|
||||
content: '\e63f';
|
||||
content: "\e63f";
|
||||
}
|
||||
|
||||
.iconshangyi:before {
|
||||
content: '\e6be';
|
||||
content: "\e6be";
|
||||
}
|
||||
|
||||
.iconxiayi:before {
|
||||
content: '\e6bf';
|
||||
content: "\e6bf";
|
||||
}
|
||||
|
||||
.icongaikuozonglan:before {
|
||||
content: '\e609';
|
||||
content: "\e609";
|
||||
}
|
||||
|
||||
.iconquanxuan:before {
|
||||
content: '\f199';
|
||||
content: "\f199";
|
||||
}
|
||||
|
||||
.icondaoru:before {
|
||||
content: '\e6a3';
|
||||
content: "\e6a3";
|
||||
}
|
||||
|
||||
.iconhoutui-shi:before {
|
||||
content: '\e656';
|
||||
content: "\e656";
|
||||
}
|
||||
|
||||
.iconqianjin1:before {
|
||||
content: '\e654';
|
||||
content: "\e654";
|
||||
}
|
||||
|
||||
.iconwithdraw:before {
|
||||
content: '\e603';
|
||||
content: "\e603";
|
||||
}
|
||||
|
||||
.iconqianjin:before {
|
||||
content: '\e600';
|
||||
content: "\e600";
|
||||
}
|
||||
|
||||
.iconhuifumoren:before {
|
||||
content: '\e60e';
|
||||
content: "\e60e";
|
||||
}
|
||||
|
||||
.iconhuanhang:before {
|
||||
content: '\e61e';
|
||||
content: "\e61e";
|
||||
}
|
||||
|
||||
.iconsuoxiao:before {
|
||||
content: '\ec13';
|
||||
content: "\ec13";
|
||||
}
|
||||
|
||||
.iconbianji:before {
|
||||
content: '\e626';
|
||||
content: "\e626";
|
||||
}
|
||||
|
||||
.iconfangda:before {
|
||||
content: '\e663';
|
||||
content: "\e663";
|
||||
}
|
||||
|
||||
.iconquanping1:before {
|
||||
content: '\e664';
|
||||
content: "\e664";
|
||||
}
|
||||
|
||||
.icondingwei:before {
|
||||
content: '\e616';
|
||||
content: "\e616";
|
||||
}
|
||||
|
||||
.icondaohang:before {
|
||||
content: '\e611';
|
||||
content: "\e611";
|
||||
}
|
||||
|
||||
.iconjianpan:before {
|
||||
content: '\e64d';
|
||||
content: "\e64d";
|
||||
}
|
||||
|
||||
.iconquanping:before {
|
||||
content: '\e602';
|
||||
content: "\e602";
|
||||
}
|
||||
|
||||
.icondaochu:before {
|
||||
content: '\e63d';
|
||||
content: "\e63d";
|
||||
}
|
||||
|
||||
.iconbiaoqian:before {
|
||||
content: '\e63c';
|
||||
content: "\e63c";
|
||||
}
|
||||
|
||||
.iconflow-Mark:before {
|
||||
content: '\e65b';
|
||||
content: "\e65b";
|
||||
}
|
||||
|
||||
.iconchaolianjie:before {
|
||||
content: '\e6f4';
|
||||
content: "\e6f4";
|
||||
}
|
||||
|
||||
.iconjingzi:before {
|
||||
content: '\e610';
|
||||
content: "\e610";
|
||||
}
|
||||
|
||||
.iconxiaolian:before {
|
||||
content: '\e60f';
|
||||
content: "\e60f";
|
||||
}
|
||||
|
||||
.iconimage:before {
|
||||
content: '\e629';
|
||||
content: "\e629";
|
||||
}
|
||||
|
||||
.iconjiegou:before {
|
||||
content: '\e61d';
|
||||
content: "\e61d";
|
||||
}
|
||||
|
||||
.iconyangshi:before {
|
||||
content: '\e631';
|
||||
content: "\e631";
|
||||
}
|
||||
|
||||
.iconfuhao-dagangshu:before {
|
||||
content: '\e71f';
|
||||
content: "\e71f";
|
||||
}
|
||||
|
||||
.icontianjiazijiedian:before {
|
||||
content: '\e622';
|
||||
content: "\e622";
|
||||
}
|
||||
|
||||
.iconjiedian:before {
|
||||
content: '\e655';
|
||||
content: "\e655";
|
||||
}
|
||||
|
||||
.iconshanchu:before {
|
||||
content: '\e696';
|
||||
content: "\e696";
|
||||
}
|
||||
|
||||
.iconzhankai:before {
|
||||
content: '\e64c';
|
||||
content: "\e64c";
|
||||
}
|
||||
|
||||
.iconzhankai1:before {
|
||||
content: '\e673';
|
||||
content: "\e673";
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -5,6 +5,20 @@
|
||||
"css_prefix_text": "icon",
|
||||
"description": "思维导图",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "1009019",
|
||||
"name": "选择",
|
||||
"font_class": "choose1",
|
||||
"unicode": "e6c5",
|
||||
"unicode_decimal": 59077
|
||||
},
|
||||
{
|
||||
"icon_id": "493507",
|
||||
"name": "主题",
|
||||
"font_class": "zhuti",
|
||||
"unicode": "e7aa",
|
||||
"unicode_decimal": 59306
|
||||
},
|
||||
{
|
||||
"icon_id": "1305460",
|
||||
"name": "导出",
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
355
web/src/config/en.js
Normal file
355
web/src/config/en.js
Normal file
@@ -0,0 +1,355 @@
|
||||
// 字体列表
|
||||
export const fontFamilyList = [
|
||||
{
|
||||
name: 'Song Ti',
|
||||
value: '宋体, SimSun, Songti SC'
|
||||
},
|
||||
{
|
||||
name: 'Microsoft Yahei',
|
||||
value: '微软雅黑, Microsoft YaHei'
|
||||
},
|
||||
{
|
||||
name: 'Italics',
|
||||
value: '楷体, 楷体_GB2312, SimKai, STKaiti'
|
||||
},
|
||||
{
|
||||
name: 'Boldface',
|
||||
value: '黑体, SimHei, Heiti SC'
|
||||
},
|
||||
{
|
||||
name: 'Official script',
|
||||
value: '隶书, SimLi'
|
||||
},
|
||||
{
|
||||
name: 'Andale Mono',
|
||||
value: 'andale mono'
|
||||
},
|
||||
{
|
||||
name: 'Arial',
|
||||
value: 'arial, helvetica, sans-serif'
|
||||
},
|
||||
{
|
||||
name: 'arialBlack',
|
||||
value: 'arial black, avant garde'
|
||||
},
|
||||
{
|
||||
name: 'Comic Sans Ms',
|
||||
value: 'comic sans ms'
|
||||
},
|
||||
{
|
||||
name: 'Impact',
|
||||
value: 'impact, chicago'
|
||||
},
|
||||
{
|
||||
name: 'Times New Roman',
|
||||
value: 'times new roman'
|
||||
},
|
||||
{
|
||||
name: 'Sans-Serif',
|
||||
value: 'sans-serif'
|
||||
},
|
||||
{
|
||||
name: 'serif',
|
||||
value: 'serif'
|
||||
}
|
||||
]
|
||||
|
||||
// 边框样式
|
||||
export const borderDasharrayList = [
|
||||
{
|
||||
name: 'Solid',
|
||||
value: 'none'
|
||||
},
|
||||
{
|
||||
name: 'Dotted1',
|
||||
value: '5,5'
|
||||
},
|
||||
{
|
||||
name: 'Dotted2',
|
||||
value: '10,10'
|
||||
},
|
||||
{
|
||||
name: 'Dotted3',
|
||||
value: '20,10,5,5,5,10'
|
||||
},
|
||||
{
|
||||
name: 'Dotted4',
|
||||
value: '5, 5, 1, 5'
|
||||
},
|
||||
{
|
||||
name: 'Dotted5',
|
||||
value: '15, 10, 5, 10, 15'
|
||||
},
|
||||
{
|
||||
name: 'Dotted6',
|
||||
value: '1, 5'
|
||||
}
|
||||
]
|
||||
|
||||
// 连线风格
|
||||
export const lineStyleList = [
|
||||
{
|
||||
name: 'Straight',
|
||||
value: 'straight'
|
||||
},
|
||||
{
|
||||
name: 'Curve',
|
||||
value: 'curve'
|
||||
},
|
||||
{
|
||||
name: 'Direct',
|
||||
value: 'direct'
|
||||
}
|
||||
]
|
||||
|
||||
// 图片重复方式
|
||||
export const backgroundRepeatList = [
|
||||
{
|
||||
name: 'No repeat',
|
||||
value: 'no-repeat'
|
||||
},
|
||||
{
|
||||
name: 'Repeat',
|
||||
value: 'repeat'
|
||||
},
|
||||
{
|
||||
name: 'Repeat-x',
|
||||
value: 'repeat-x'
|
||||
},
|
||||
{
|
||||
name: 'Repeat-y',
|
||||
value: 'repeat-y'
|
||||
}
|
||||
]
|
||||
|
||||
// 背景图片定位
|
||||
export const backgroundPositionList = [
|
||||
{
|
||||
name: 'Default',
|
||||
value: '0% 0%'
|
||||
},
|
||||
{
|
||||
name: 'Left top',
|
||||
value: 'left top'
|
||||
},
|
||||
{
|
||||
name: 'Left center',
|
||||
value: 'left center'
|
||||
},
|
||||
{
|
||||
name: 'Left bottom',
|
||||
value: 'left bottom'
|
||||
},
|
||||
{
|
||||
name: 'Right top',
|
||||
value: 'right top'
|
||||
},
|
||||
{
|
||||
name: 'Right center',
|
||||
value: 'right center'
|
||||
},
|
||||
{
|
||||
name: 'Right bottom',
|
||||
value: 'right bottom'
|
||||
},
|
||||
{
|
||||
name: 'Center top',
|
||||
value: 'center top'
|
||||
},
|
||||
{
|
||||
name: 'Center center',
|
||||
value: 'center center'
|
||||
},
|
||||
{
|
||||
name: 'Center bottom',
|
||||
value: 'center bottom'
|
||||
}
|
||||
]
|
||||
|
||||
// 快捷键列表
|
||||
export const shortcutKeyList = [
|
||||
{
|
||||
type: 'Node operation',
|
||||
list: [
|
||||
{
|
||||
icon: 'icontianjiazijiedian',
|
||||
name: 'Inert child node',
|
||||
value: 'Tab'
|
||||
},
|
||||
{
|
||||
icon: 'iconjiedian',
|
||||
name: 'Insert sibling node',
|
||||
value: 'Enter'
|
||||
},
|
||||
{
|
||||
icon: 'iconshangyi',
|
||||
name: 'Move up node',
|
||||
value: 'Ctrl + ↑'
|
||||
},
|
||||
{
|
||||
icon: 'iconxiayi',
|
||||
name: 'Move down node',
|
||||
value: 'Ctrl + ↓'
|
||||
},
|
||||
{
|
||||
icon: 'icongaikuozonglan',
|
||||
name: 'Insert summary',
|
||||
value: 'Ctrl + S'
|
||||
},
|
||||
{
|
||||
icon: 'iconzhankai',
|
||||
name: 'Expand/UnExpand node',
|
||||
value: '/'
|
||||
},
|
||||
{
|
||||
icon: 'iconshanchu',
|
||||
name: 'Delete node',
|
||||
value: 'Delete | Backspace'
|
||||
},
|
||||
{
|
||||
icon: 'iconfuzhi',
|
||||
name: 'Copy node',
|
||||
value: 'Ctrl + C'
|
||||
},
|
||||
{
|
||||
icon: 'iconjianqie',
|
||||
name: 'Cut node',
|
||||
value: 'Ctrl + X'
|
||||
},
|
||||
{
|
||||
icon: 'iconniantie',
|
||||
name: 'Paste node',
|
||||
value: 'Ctrl + V'
|
||||
},
|
||||
{
|
||||
icon: 'iconbianji',
|
||||
name: 'Edit node',
|
||||
value: 'F2'
|
||||
},
|
||||
{
|
||||
icon: 'iconhuanhang',
|
||||
name: 'Text Wrap',
|
||||
value: 'Shift + Enter'
|
||||
},
|
||||
{
|
||||
icon: 'iconhoutui-shi',
|
||||
name: 'Undo',
|
||||
value: 'Ctrl + Z'
|
||||
},
|
||||
{
|
||||
icon: 'iconqianjin1',
|
||||
name: 'Redo',
|
||||
value: 'Ctrl + Y'
|
||||
},
|
||||
{
|
||||
icon: 'iconquanxuan',
|
||||
name: 'Select All',
|
||||
value: 'Ctrl + A'
|
||||
},
|
||||
{
|
||||
icon: 'iconquanxuan',
|
||||
name: 'Multiple choice',
|
||||
value: 'Right click / Ctrl + Left click'
|
||||
},
|
||||
{
|
||||
icon: 'iconzhengli',
|
||||
name: 'Arrange layout',
|
||||
value: 'Ctrl + L'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: 'Canvas operation',
|
||||
list: [
|
||||
{
|
||||
icon: 'iconfangda',
|
||||
name: 'Zoom in',
|
||||
value: 'Ctrl + +'
|
||||
},
|
||||
{
|
||||
icon: 'iconsuoxiao',
|
||||
name: 'Zoom out',
|
||||
value: 'Ctrl + -'
|
||||
},
|
||||
{
|
||||
icon: 'icondingwei',
|
||||
name: 'Reset',
|
||||
value: 'Ctrl + Enter'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// 形状列表
|
||||
export const shapeList = [
|
||||
{
|
||||
name: 'Rectangle',
|
||||
value: 'rectangle'
|
||||
},
|
||||
{
|
||||
name: 'Diamond',
|
||||
value: 'diamond'
|
||||
},
|
||||
{
|
||||
name: 'Parallelogram',
|
||||
value: 'parallelogram'
|
||||
},
|
||||
{
|
||||
name: 'Rounded rectangle',
|
||||
value: 'roundedRectangle'
|
||||
},
|
||||
{
|
||||
name: 'Octagonal rectangle',
|
||||
value: 'octagonalRectangle'
|
||||
},
|
||||
{
|
||||
name: 'Outer triangular rectangle',
|
||||
value: 'outerTriangularRectangle'
|
||||
},
|
||||
{
|
||||
name: 'Inner triangular rectangle',
|
||||
value: 'innerTriangularRectangle'
|
||||
},
|
||||
{
|
||||
name: 'Ellipse',
|
||||
value: 'ellipse'
|
||||
},
|
||||
{
|
||||
name: 'Circle',
|
||||
value: 'circle'
|
||||
}
|
||||
]
|
||||
|
||||
// 侧边栏列表
|
||||
export const sidebarTriggerList = [
|
||||
{
|
||||
name: 'Node style',
|
||||
value: 'nodeStyle',
|
||||
icon: 'iconzhuti'
|
||||
},
|
||||
{
|
||||
name: 'Base style',
|
||||
value: 'baseStyle',
|
||||
icon: 'iconyangshi'
|
||||
},
|
||||
{
|
||||
name: 'Theme',
|
||||
value: 'theme',
|
||||
icon: 'iconjingzi'
|
||||
},
|
||||
{
|
||||
name: 'Structure',
|
||||
value: 'structure',
|
||||
icon: 'iconjiegou'
|
||||
},
|
||||
{
|
||||
name: 'Outline',
|
||||
value: 'outline',
|
||||
icon: 'iconfuhao-dagangshu'
|
||||
},
|
||||
{
|
||||
name: 'ShortcutKey',
|
||||
value: 'shortcutKey',
|
||||
icon: 'iconjianpan'
|
||||
}
|
||||
]
|
||||
@@ -1,381 +1,87 @@
|
||||
// 字体列表
|
||||
export const fontFamilyList = [
|
||||
{
|
||||
name: '宋体',
|
||||
value: '宋体, SimSun, Songti SC'
|
||||
},
|
||||
{
|
||||
name: '微软雅黑',
|
||||
value: '微软雅黑, Microsoft YaHei'
|
||||
},
|
||||
{
|
||||
name: '楷体',
|
||||
value: '楷体, 楷体_GB2312, SimKai, STKaiti'
|
||||
},
|
||||
{
|
||||
name: '黑体',
|
||||
value: '黑体, SimHei, Heiti SC'
|
||||
},
|
||||
{
|
||||
name: '隶书',
|
||||
value: '隶书, SimLi'
|
||||
},
|
||||
{
|
||||
name: 'Andale Mono',
|
||||
value: 'andale mono'
|
||||
},
|
||||
{
|
||||
name: 'Arial',
|
||||
value: 'arial, helvetica, sans-serif'
|
||||
},
|
||||
{
|
||||
name: 'arialBlack',
|
||||
value: 'arial black, avant garde'
|
||||
},
|
||||
{
|
||||
name: 'Comic Sans Ms',
|
||||
value: 'comic sans ms'
|
||||
},
|
||||
{
|
||||
name: 'Impact',
|
||||
value: 'impact, chicago'
|
||||
},
|
||||
{
|
||||
name: 'Times New Roman',
|
||||
value: 'times new roman'
|
||||
},
|
||||
{
|
||||
name: 'Sans-Serif',
|
||||
value: 'sans-serif'
|
||||
},
|
||||
{
|
||||
name: 'serif',
|
||||
value: 'serif'
|
||||
}
|
||||
]
|
||||
import {
|
||||
fontSizeList,
|
||||
lineHeightList,
|
||||
colorList,
|
||||
borderWidthList,
|
||||
borderRadiusList,
|
||||
lineWidthList,
|
||||
store,
|
||||
langList,
|
||||
fontFamilyList as fontFamilyListZh,
|
||||
borderDasharrayList as borderDasharrayListZh,
|
||||
lineStyleList as lineStyleListZh,
|
||||
backgroundRepeatList as backgroundRepeatListZh,
|
||||
backgroundPositionList as backgroundPositionListZh,
|
||||
shortcutKeyList as shortcutKeyListZh,
|
||||
shapeList as shapeListZh,
|
||||
sidebarTriggerList as sidebarTriggerListZh
|
||||
} from './zh'
|
||||
import {
|
||||
fontFamilyList as fontFamilyListEn,
|
||||
borderDasharrayList as borderDasharrayListEn,
|
||||
lineStyleList as lineStyleListEn,
|
||||
backgroundRepeatList as backgroundRepeatListEn,
|
||||
backgroundPositionList as backgroundPositionListEn,
|
||||
shortcutKeyList as shortcutKeyListEn,
|
||||
shapeList as shapeListEn,
|
||||
sidebarTriggerList as sidebarTriggerListEn
|
||||
} from './en'
|
||||
|
||||
// 字号
|
||||
export const fontSizeList = [10, 12, 16, 18, 24, 32, 48]
|
||||
|
||||
// 行高
|
||||
export const lineHeightList = [1, 1.5, 2, 2.5, 3]
|
||||
|
||||
// 颜色
|
||||
export const colorList = [
|
||||
'#4D4D4D',
|
||||
'#999999',
|
||||
'#FFFFFF',
|
||||
'#F44E3B',
|
||||
'#FE9200',
|
||||
'#FCDC00',
|
||||
'#DBDF00',
|
||||
'#A4DD00',
|
||||
'#68CCCA',
|
||||
'#73D8FF',
|
||||
'#AEA1FF',
|
||||
'#FDA1FF',
|
||||
'#333333',
|
||||
'#808080',
|
||||
'#cccccc',
|
||||
'#D33115',
|
||||
'#E27300',
|
||||
'#FCC400',
|
||||
'#B0BC00',
|
||||
'#68BC00',
|
||||
'#16A5A5',
|
||||
'#009CE0',
|
||||
'#7B64FF',
|
||||
'#FA28FF',
|
||||
'#000000',
|
||||
'#666666',
|
||||
'#B3B3B3',
|
||||
'#9F0500',
|
||||
'#C45100',
|
||||
'#FB9E00',
|
||||
'#808900',
|
||||
'#194D33',
|
||||
'#0C797D',
|
||||
'#0062B1',
|
||||
'#653294',
|
||||
'#AB149E'
|
||||
]
|
||||
|
||||
// 边框宽度
|
||||
export const borderWidthList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
|
||||
// 边框样式
|
||||
export const borderDasharrayList = [
|
||||
{
|
||||
name: '实线',
|
||||
value: 'none'
|
||||
},
|
||||
{
|
||||
name: '虚线1',
|
||||
value: '5,5'
|
||||
},
|
||||
{
|
||||
name: '虚线2',
|
||||
value: '10,10'
|
||||
},
|
||||
{
|
||||
name: '虚线3',
|
||||
value: '20,10,5,5,5,10'
|
||||
},
|
||||
{
|
||||
name: '虚线4',
|
||||
value: '5, 5, 1, 5'
|
||||
},
|
||||
{
|
||||
name: '虚线5',
|
||||
value: '15, 10, 5, 10, 15'
|
||||
},
|
||||
{
|
||||
name: '虚线6',
|
||||
value: '1, 5'
|
||||
}
|
||||
]
|
||||
|
||||
// 圆角
|
||||
export const borderRadiusList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
|
||||
// 线宽
|
||||
export const lineWidthList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
|
||||
// 连线风格
|
||||
export const lineStyleList = [
|
||||
{
|
||||
name: '直线',
|
||||
value: 'straight'
|
||||
},
|
||||
{
|
||||
name: '曲线',
|
||||
value: 'curve'
|
||||
},
|
||||
{
|
||||
name: '直连',
|
||||
value: 'direct'
|
||||
}
|
||||
]
|
||||
|
||||
// 图片重复方式
|
||||
export const backgroundRepeatList = [
|
||||
{
|
||||
name: '不重复',
|
||||
value: 'no-repeat'
|
||||
},
|
||||
{
|
||||
name: '重复',
|
||||
value: 'repeat'
|
||||
},
|
||||
{
|
||||
name: '水平方向重复',
|
||||
value: 'repeat-x'
|
||||
},
|
||||
{
|
||||
name: '垂直方向重复',
|
||||
value: 'repeat-y'
|
||||
}
|
||||
]
|
||||
|
||||
// 背景图片定位
|
||||
export const backgroundPositionList = [
|
||||
{
|
||||
name: '默认',
|
||||
value: '0% 0%'
|
||||
},
|
||||
{
|
||||
name: '左上',
|
||||
value: 'left top'
|
||||
},
|
||||
{
|
||||
name: '左中',
|
||||
value: 'left center'
|
||||
},
|
||||
{
|
||||
name: '左下',
|
||||
value: 'left bottom'
|
||||
},
|
||||
{
|
||||
name: '右上',
|
||||
value: 'right top'
|
||||
},
|
||||
{
|
||||
name: '右中',
|
||||
value: 'right center'
|
||||
},
|
||||
{
|
||||
name: '右下',
|
||||
value: 'right bottom'
|
||||
},
|
||||
{
|
||||
name: '中上',
|
||||
value: 'center top'
|
||||
},
|
||||
{
|
||||
name: '居中',
|
||||
value: 'center center'
|
||||
},
|
||||
{
|
||||
name: '中下',
|
||||
value: 'center bottom'
|
||||
}
|
||||
]
|
||||
|
||||
// 数据存储
|
||||
export const store = {
|
||||
sidebarZIndex: 1 //侧边栏zIndex
|
||||
const fontFamilyList = {
|
||||
zh: fontFamilyListZh,
|
||||
en: fontFamilyListEn
|
||||
}
|
||||
|
||||
// 快捷键列表
|
||||
export const shortcutKeyList = [
|
||||
{
|
||||
type: '节点操作',
|
||||
list: [
|
||||
{
|
||||
icon: 'icontianjiazijiedian',
|
||||
name: '插入下级节点',
|
||||
value: 'Tab'
|
||||
},
|
||||
{
|
||||
icon: 'iconjiedian',
|
||||
name: '插入同级节点',
|
||||
value: 'Enter'
|
||||
},
|
||||
{
|
||||
icon: 'iconshangyi',
|
||||
name: '上移节点',
|
||||
value: 'Ctrl + ↑'
|
||||
},
|
||||
{
|
||||
icon: 'iconxiayi',
|
||||
name: '下移节点',
|
||||
value: 'Ctrl + ↓'
|
||||
},
|
||||
{
|
||||
icon: 'icongaikuozonglan',
|
||||
name: '插入概要',
|
||||
value: 'Ctrl + S'
|
||||
},
|
||||
{
|
||||
icon: 'iconzhankai',
|
||||
name: '展开/收起节点',
|
||||
value: '/'
|
||||
},
|
||||
{
|
||||
icon: 'iconshanchu',
|
||||
name: '删除节点',
|
||||
value: 'Delete | Backspace'
|
||||
},
|
||||
{
|
||||
icon: 'iconfuzhi',
|
||||
name: '复制节点',
|
||||
value: 'Ctrl + C'
|
||||
},
|
||||
{
|
||||
icon: 'iconjianqie',
|
||||
name: '剪切节点',
|
||||
value: 'Ctrl + X'
|
||||
},
|
||||
{
|
||||
icon: 'iconniantie',
|
||||
name: '粘贴节点',
|
||||
value: 'Ctrl + V'
|
||||
},
|
||||
{
|
||||
icon: 'iconbianji',
|
||||
name: '编辑节点',
|
||||
value: 'F2'
|
||||
},
|
||||
{
|
||||
icon: 'iconhuanhang',
|
||||
name: '文本换行',
|
||||
value: 'Shift + Enter'
|
||||
},
|
||||
{
|
||||
icon: 'iconhoutui-shi',
|
||||
name: '回退',
|
||||
value: 'Ctrl + Z'
|
||||
},
|
||||
{
|
||||
icon: 'iconqianjin1',
|
||||
name: '前进',
|
||||
value: 'Ctrl + Y'
|
||||
},
|
||||
{
|
||||
icon: 'iconquanxuan',
|
||||
name: '全选',
|
||||
value: 'Ctrl + A'
|
||||
},
|
||||
{
|
||||
icon: 'iconquanxuan',
|
||||
name: '多选',
|
||||
value: '右键 / Ctrl + 左键'
|
||||
},
|
||||
{
|
||||
icon: 'iconzhengli',
|
||||
name: '一键整理布局',
|
||||
value: 'Ctrl + L'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: '画布操作',
|
||||
list: [
|
||||
{
|
||||
icon: 'iconfangda',
|
||||
name: '放大',
|
||||
value: 'Ctrl + +'
|
||||
},
|
||||
{
|
||||
icon: 'iconsuoxiao',
|
||||
name: '缩小',
|
||||
value: 'Ctrl + -'
|
||||
},
|
||||
{
|
||||
icon: 'icondingwei',
|
||||
name: '恢复默认',
|
||||
value: 'Ctrl + Enter'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
const borderDasharrayList = {
|
||||
zh: borderDasharrayListZh,
|
||||
en: borderDasharrayListEn
|
||||
}
|
||||
|
||||
// 形状列表
|
||||
export const shapeList = [
|
||||
{
|
||||
name: '矩形',
|
||||
value: 'rectangle'
|
||||
},
|
||||
{
|
||||
name: '菱形',
|
||||
value: 'diamond'
|
||||
},
|
||||
{
|
||||
name: '平行四边形',
|
||||
value: 'parallelogram'
|
||||
},
|
||||
{
|
||||
name: '圆角矩形',
|
||||
value: 'roundedRectangle'
|
||||
},
|
||||
{
|
||||
name: '八角矩形',
|
||||
value: 'octagonalRectangle'
|
||||
},
|
||||
{
|
||||
name: '外三角矩形',
|
||||
value: 'outerTriangularRectangle'
|
||||
},
|
||||
{
|
||||
name: '内三角矩形',
|
||||
value: 'innerTriangularRectangle'
|
||||
},
|
||||
{
|
||||
name: '椭圆',
|
||||
value: 'ellipse'
|
||||
},
|
||||
{
|
||||
name: '圆',
|
||||
value: 'circle'
|
||||
}
|
||||
]
|
||||
const lineStyleList = {
|
||||
zh: lineStyleListZh,
|
||||
en: lineStyleListEn
|
||||
}
|
||||
|
||||
const backgroundRepeatList = {
|
||||
zh: backgroundRepeatListZh,
|
||||
en: backgroundRepeatListEn
|
||||
}
|
||||
|
||||
const backgroundPositionList = {
|
||||
zh: backgroundPositionListZh,
|
||||
en: backgroundPositionListEn
|
||||
}
|
||||
|
||||
const shortcutKeyList = {
|
||||
zh: shortcutKeyListZh,
|
||||
en: shortcutKeyListEn
|
||||
}
|
||||
|
||||
const shapeList = {
|
||||
zh: shapeListZh,
|
||||
en: shapeListEn
|
||||
}
|
||||
|
||||
const sidebarTriggerList = {
|
||||
zh: sidebarTriggerListZh,
|
||||
en: sidebarTriggerListEn
|
||||
}
|
||||
|
||||
export {
|
||||
fontSizeList,
|
||||
lineHeightList,
|
||||
borderWidthList,
|
||||
borderRadiusList,
|
||||
lineWidthList,
|
||||
store,
|
||||
colorList,
|
||||
langList,
|
||||
fontFamilyList,
|
||||
borderDasharrayList,
|
||||
lineStyleList,
|
||||
backgroundRepeatList,
|
||||
backgroundPositionList,
|
||||
shortcutKeyList,
|
||||
shapeList,
|
||||
sidebarTriggerList
|
||||
}
|
||||
|
||||
427
web/src/config/zh.js
Normal file
427
web/src/config/zh.js
Normal file
@@ -0,0 +1,427 @@
|
||||
// 字体列表
|
||||
export const fontFamilyList = [
|
||||
{
|
||||
name: '宋体',
|
||||
value: '宋体, SimSun, Songti SC'
|
||||
},
|
||||
{
|
||||
name: '微软雅黑',
|
||||
value: '微软雅黑, Microsoft YaHei'
|
||||
},
|
||||
{
|
||||
name: '楷体',
|
||||
value: '楷体, 楷体_GB2312, SimKai, STKaiti'
|
||||
},
|
||||
{
|
||||
name: '黑体',
|
||||
value: '黑体, SimHei, Heiti SC'
|
||||
},
|
||||
{
|
||||
name: '隶书',
|
||||
value: '隶书, SimLi'
|
||||
},
|
||||
{
|
||||
name: 'Andale Mono',
|
||||
value: 'andale mono'
|
||||
},
|
||||
{
|
||||
name: 'Arial',
|
||||
value: 'arial, helvetica, sans-serif'
|
||||
},
|
||||
{
|
||||
name: 'arialBlack',
|
||||
value: 'arial black, avant garde'
|
||||
},
|
||||
{
|
||||
name: 'Comic Sans Ms',
|
||||
value: 'comic sans ms'
|
||||
},
|
||||
{
|
||||
name: 'Impact',
|
||||
value: 'impact, chicago'
|
||||
},
|
||||
{
|
||||
name: 'Times New Roman',
|
||||
value: 'times new roman'
|
||||
},
|
||||
{
|
||||
name: 'Sans-Serif',
|
||||
value: 'sans-serif'
|
||||
},
|
||||
{
|
||||
name: 'serif',
|
||||
value: 'serif'
|
||||
}
|
||||
]
|
||||
|
||||
// 字号
|
||||
export const fontSizeList = [10, 12, 16, 18, 24, 32, 48]
|
||||
|
||||
// 行高
|
||||
export const lineHeightList = [1, 1.5, 2, 2.5, 3]
|
||||
|
||||
// 颜色
|
||||
export const colorList = [
|
||||
'#4D4D4D',
|
||||
'#999999',
|
||||
'#FFFFFF',
|
||||
'#F44E3B',
|
||||
'#FE9200',
|
||||
'#FCDC00',
|
||||
'#DBDF00',
|
||||
'#A4DD00',
|
||||
'#68CCCA',
|
||||
'#73D8FF',
|
||||
'#AEA1FF',
|
||||
'#FDA1FF',
|
||||
'#333333',
|
||||
'#808080',
|
||||
'#cccccc',
|
||||
'#D33115',
|
||||
'#E27300',
|
||||
'#FCC400',
|
||||
'#B0BC00',
|
||||
'#68BC00',
|
||||
'#16A5A5',
|
||||
'#009CE0',
|
||||
'#7B64FF',
|
||||
'#FA28FF',
|
||||
'#000000',
|
||||
'#666666',
|
||||
'#B3B3B3',
|
||||
'#9F0500',
|
||||
'#C45100',
|
||||
'#FB9E00',
|
||||
'#808900',
|
||||
'#194D33',
|
||||
'#0C797D',
|
||||
'#0062B1',
|
||||
'#653294',
|
||||
'#AB149E'
|
||||
]
|
||||
|
||||
// 边框宽度
|
||||
export const borderWidthList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
|
||||
// 边框样式
|
||||
export const borderDasharrayList = [
|
||||
{
|
||||
name: '实线',
|
||||
value: 'none'
|
||||
},
|
||||
{
|
||||
name: '虚线1',
|
||||
value: '5,5'
|
||||
},
|
||||
{
|
||||
name: '虚线2',
|
||||
value: '10,10'
|
||||
},
|
||||
{
|
||||
name: '虚线3',
|
||||
value: '20,10,5,5,5,10'
|
||||
},
|
||||
{
|
||||
name: '虚线4',
|
||||
value: '5, 5, 1, 5'
|
||||
},
|
||||
{
|
||||
name: '虚线5',
|
||||
value: '15, 10, 5, 10, 15'
|
||||
},
|
||||
{
|
||||
name: '虚线6',
|
||||
value: '1, 5'
|
||||
}
|
||||
]
|
||||
|
||||
// 圆角
|
||||
export const borderRadiusList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
|
||||
// 线宽
|
||||
export const lineWidthList = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
|
||||
|
||||
// 连线风格
|
||||
export const lineStyleList = [
|
||||
{
|
||||
name: '直线',
|
||||
value: 'straight'
|
||||
},
|
||||
{
|
||||
name: '曲线',
|
||||
value: 'curve'
|
||||
},
|
||||
{
|
||||
name: '直连',
|
||||
value: 'direct'
|
||||
}
|
||||
]
|
||||
|
||||
// 图片重复方式
|
||||
export const backgroundRepeatList = [
|
||||
{
|
||||
name: '不重复',
|
||||
value: 'no-repeat'
|
||||
},
|
||||
{
|
||||
name: '重复',
|
||||
value: 'repeat'
|
||||
},
|
||||
{
|
||||
name: '水平方向重复',
|
||||
value: 'repeat-x'
|
||||
},
|
||||
{
|
||||
name: '垂直方向重复',
|
||||
value: 'repeat-y'
|
||||
}
|
||||
]
|
||||
|
||||
// 背景图片定位
|
||||
export const backgroundPositionList = [
|
||||
{
|
||||
name: '默认',
|
||||
value: '0% 0%'
|
||||
},
|
||||
{
|
||||
name: '左上',
|
||||
value: 'left top'
|
||||
},
|
||||
{
|
||||
name: '左中',
|
||||
value: 'left center'
|
||||
},
|
||||
{
|
||||
name: '左下',
|
||||
value: 'left bottom'
|
||||
},
|
||||
{
|
||||
name: '右上',
|
||||
value: 'right top'
|
||||
},
|
||||
{
|
||||
name: '右中',
|
||||
value: 'right center'
|
||||
},
|
||||
{
|
||||
name: '右下',
|
||||
value: 'right bottom'
|
||||
},
|
||||
{
|
||||
name: '中上',
|
||||
value: 'center top'
|
||||
},
|
||||
{
|
||||
name: '居中',
|
||||
value: 'center center'
|
||||
},
|
||||
{
|
||||
name: '中下',
|
||||
value: 'center bottom'
|
||||
}
|
||||
]
|
||||
|
||||
// 数据存储
|
||||
export const store = {
|
||||
sidebarZIndex: 1 //侧边栏zIndex
|
||||
}
|
||||
|
||||
// 快捷键列表
|
||||
export const shortcutKeyList = [
|
||||
{
|
||||
type: '节点操作',
|
||||
list: [
|
||||
{
|
||||
icon: 'icontianjiazijiedian',
|
||||
name: '插入下级节点',
|
||||
value: 'Tab'
|
||||
},
|
||||
{
|
||||
icon: 'iconjiedian',
|
||||
name: '插入同级节点',
|
||||
value: 'Enter'
|
||||
},
|
||||
{
|
||||
icon: 'iconshangyi',
|
||||
name: '上移节点',
|
||||
value: 'Ctrl + ↑'
|
||||
},
|
||||
{
|
||||
icon: 'iconxiayi',
|
||||
name: '下移节点',
|
||||
value: 'Ctrl + ↓'
|
||||
},
|
||||
{
|
||||
icon: 'icongaikuozonglan',
|
||||
name: '插入概要',
|
||||
value: 'Ctrl + S'
|
||||
},
|
||||
{
|
||||
icon: 'iconzhankai',
|
||||
name: '展开/收起节点',
|
||||
value: '/'
|
||||
},
|
||||
{
|
||||
icon: 'iconshanchu',
|
||||
name: '删除节点',
|
||||
value: 'Delete | Backspace'
|
||||
},
|
||||
{
|
||||
icon: 'iconfuzhi',
|
||||
name: '复制节点',
|
||||
value: 'Ctrl + C'
|
||||
},
|
||||
{
|
||||
icon: 'iconjianqie',
|
||||
name: '剪切节点',
|
||||
value: 'Ctrl + X'
|
||||
},
|
||||
{
|
||||
icon: 'iconniantie',
|
||||
name: '粘贴节点',
|
||||
value: 'Ctrl + V'
|
||||
},
|
||||
{
|
||||
icon: 'iconbianji',
|
||||
name: '编辑节点',
|
||||
value: 'F2'
|
||||
},
|
||||
{
|
||||
icon: 'iconhuanhang',
|
||||
name: '文本换行',
|
||||
value: 'Shift + Enter'
|
||||
},
|
||||
{
|
||||
icon: 'iconhoutui-shi',
|
||||
name: '回退',
|
||||
value: 'Ctrl + Z'
|
||||
},
|
||||
{
|
||||
icon: 'iconqianjin1',
|
||||
name: '前进',
|
||||
value: 'Ctrl + Y'
|
||||
},
|
||||
{
|
||||
icon: 'iconquanxuan',
|
||||
name: '全选',
|
||||
value: 'Ctrl + A'
|
||||
},
|
||||
{
|
||||
icon: 'iconquanxuan',
|
||||
name: '多选',
|
||||
value: '右键 / Ctrl + 左键'
|
||||
},
|
||||
{
|
||||
icon: 'iconzhengli',
|
||||
name: '一键整理布局',
|
||||
value: 'Ctrl + L'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
type: '画布操作',
|
||||
list: [
|
||||
{
|
||||
icon: 'iconfangda',
|
||||
name: '放大',
|
||||
value: 'Ctrl + +'
|
||||
},
|
||||
{
|
||||
icon: 'iconsuoxiao',
|
||||
name: '缩小',
|
||||
value: 'Ctrl + -'
|
||||
},
|
||||
{
|
||||
icon: 'icondingwei',
|
||||
name: '恢复默认',
|
||||
value: 'Ctrl + Enter'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// 形状列表
|
||||
export const shapeList = [
|
||||
{
|
||||
name: '矩形',
|
||||
value: 'rectangle'
|
||||
},
|
||||
{
|
||||
name: '菱形',
|
||||
value: 'diamond'
|
||||
},
|
||||
{
|
||||
name: '平行四边形',
|
||||
value: 'parallelogram'
|
||||
},
|
||||
{
|
||||
name: '圆角矩形',
|
||||
value: 'roundedRectangle'
|
||||
},
|
||||
{
|
||||
name: '八角矩形',
|
||||
value: 'octagonalRectangle'
|
||||
},
|
||||
{
|
||||
name: '外三角矩形',
|
||||
value: 'outerTriangularRectangle'
|
||||
},
|
||||
{
|
||||
name: '内三角矩形',
|
||||
value: 'innerTriangularRectangle'
|
||||
},
|
||||
{
|
||||
name: '椭圆',
|
||||
value: 'ellipse'
|
||||
},
|
||||
{
|
||||
name: '圆',
|
||||
value: 'circle'
|
||||
}
|
||||
]
|
||||
|
||||
// 多语言列表
|
||||
export const langList = [
|
||||
{
|
||||
value: 'zh',
|
||||
name: '简体中文'
|
||||
},
|
||||
{
|
||||
value: 'en',
|
||||
name: 'English'
|
||||
}
|
||||
]
|
||||
|
||||
// 侧边栏列表
|
||||
export const sidebarTriggerList = [
|
||||
{
|
||||
name: '节点样式',
|
||||
value: 'nodeStyle',
|
||||
icon: 'iconzhuti'
|
||||
},
|
||||
{
|
||||
name: '基础样式',
|
||||
value: 'baseStyle',
|
||||
icon: 'iconyangshi'
|
||||
},
|
||||
{
|
||||
name: '主题',
|
||||
value: 'theme',
|
||||
icon: 'iconjingzi'
|
||||
},
|
||||
{
|
||||
name: '结构',
|
||||
value: 'structure',
|
||||
icon: 'iconjiegou'
|
||||
},
|
||||
{
|
||||
name: '大纲',
|
||||
value: 'outline',
|
||||
icon: 'iconfuhao-dagangshu'
|
||||
},
|
||||
{
|
||||
name: '快捷键',
|
||||
value: 'shortcutKey',
|
||||
icon: 'iconjianpan'
|
||||
}
|
||||
]
|
||||
13
web/src/i18n.js
Normal file
13
web/src/i18n.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import messages from './lang'
|
||||
import { getLang } from '@/api'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: getLang(),
|
||||
messages
|
||||
})
|
||||
|
||||
export default i18n
|
||||
165
web/src/lang/en_us.js
Normal file
165
web/src/lang/en_us.js
Normal file
@@ -0,0 +1,165 @@
|
||||
export default {
|
||||
baseStyle: {
|
||||
title: 'BaseStyle',
|
||||
background: 'Background',
|
||||
color: 'Color',
|
||||
image: 'Image',
|
||||
imageRepeat: 'Image repeat',
|
||||
line: 'Line',
|
||||
width: 'Width',
|
||||
style: 'Style',
|
||||
lineOfOutline: 'Line of outline',
|
||||
nodePadding: 'Node padding',
|
||||
nodeMargin: 'Node margin',
|
||||
horizontal: 'Horizontal',
|
||||
vertical: 'Vertical',
|
||||
maximumWidth: 'Max width',
|
||||
maximumHeight: 'Max height',
|
||||
icon: 'Icon',
|
||||
size: 'Size',
|
||||
level2Node: 'Level2 node',
|
||||
belowLevel2Node: 'Below level2 node'
|
||||
},
|
||||
color: {
|
||||
moreColor: 'More color'
|
||||
},
|
||||
contextmenu: {
|
||||
insertSiblingNode: 'Insert sibling node',
|
||||
insertChildNode: 'Insert child node',
|
||||
insertSummary: 'Insert summary',
|
||||
moveUpNode: 'Move up node',
|
||||
moveDownNode: 'Move down node',
|
||||
deleteNode: 'Delete node',
|
||||
copyNode: 'Copy node',
|
||||
cutNode: 'Cut node',
|
||||
pasteNode: 'Paste node',
|
||||
backCenter: 'Back center',
|
||||
expandAll: 'Expand all',
|
||||
unExpandAll: 'Un expand all',
|
||||
expandTo: 'Expand to',
|
||||
arrangeLayout: 'Arrange layout',
|
||||
level1: 'Level1',
|
||||
level2: 'Level2',
|
||||
level3: 'Level3',
|
||||
level4: 'Level4',
|
||||
level5: 'Level5',
|
||||
level6: 'Level6',
|
||||
zenMode: 'Zen mode'
|
||||
},
|
||||
count: {
|
||||
words: 'Words',
|
||||
nodes: 'Nodes'
|
||||
},
|
||||
dialog: {
|
||||
cancel: 'Cancel',
|
||||
confirm: 'Confirm'
|
||||
},
|
||||
export: {
|
||||
title: 'Export',
|
||||
filename: 'Filename',
|
||||
include: 'Is include config like theme and structure',
|
||||
dedicatedFile: 'Dedicated file',
|
||||
jsonFile: 'json file',
|
||||
imageFile: 'Image file',
|
||||
svgFile: 'svg file',
|
||||
pdfFile: 'pdf file',
|
||||
tips: 'tips:.smm and .json file can be import'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreen: 'Fullscreen'
|
||||
},
|
||||
import: {
|
||||
title: 'Import',
|
||||
selectFile: 'Select file',
|
||||
supportFile: 'Support .smm、.json、.xmind、.xlsx file'
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: 'Open mini map',
|
||||
readonly: 'Readonly',
|
||||
edit: 'Edit'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: 'Link',
|
||||
link: 'Href',
|
||||
name: 'Name'
|
||||
},
|
||||
nodeIcon: {
|
||||
title: 'Icon'
|
||||
},
|
||||
nodeImage: {
|
||||
title: 'Image',
|
||||
imgTitle: 'Title'
|
||||
},
|
||||
nodeNote: {
|
||||
title: 'Note'
|
||||
},
|
||||
nodeTag: {
|
||||
title: 'Tag',
|
||||
addTip: 'Press Enter to add'
|
||||
},
|
||||
outline: {
|
||||
title: 'Outline'
|
||||
},
|
||||
scale: {
|
||||
zoomIn: 'Zoom in',
|
||||
zoomOut: 'Zoom out'
|
||||
},
|
||||
shortcutKey: {
|
||||
title: 'Shortcut key'
|
||||
},
|
||||
strusture: {
|
||||
title: 'Strusture'
|
||||
},
|
||||
style: {
|
||||
title: 'Node style',
|
||||
normal: 'Normal',
|
||||
active: 'Active',
|
||||
text: 'Text',
|
||||
fontFamily: 'Font family',
|
||||
fontSize: 'Font size',
|
||||
lineHeight: 'Line height',
|
||||
color: 'color',
|
||||
addFontWeight: 'add font weight',
|
||||
italic: 'Italic',
|
||||
textDecoration: 'Text decoration',
|
||||
underline: 'Underline',
|
||||
lineThrough: 'Line through',
|
||||
overline: 'Overline',
|
||||
border: 'Border',
|
||||
style: 'Style',
|
||||
width: 'Width',
|
||||
borderRadius: 'Border radius',
|
||||
background: 'Background',
|
||||
shape: 'Shape',
|
||||
line: 'Line',
|
||||
nodePadding: 'Node padding',
|
||||
horizontal: 'Horizontal',
|
||||
vertical: 'Vertical'
|
||||
},
|
||||
theme: {
|
||||
title: 'Theme'
|
||||
},
|
||||
toolbar: {
|
||||
undo: 'Undo',
|
||||
redo: 'Redo',
|
||||
insertSiblingNode: 'Insert sibling node',
|
||||
insertChildNode: 'Insert child node',
|
||||
deleteNode: 'Delete node',
|
||||
image: 'Image',
|
||||
icon: 'Icon',
|
||||
link: 'Link',
|
||||
note: 'Note',
|
||||
tag: 'Tag',
|
||||
summary: 'Summary',
|
||||
displayOutline: 'Display outline',
|
||||
baseStyle: 'Base style',
|
||||
theme: 'Theme',
|
||||
strusture: 'Strusture',
|
||||
newFile: 'New file',
|
||||
openFile: 'Open file',
|
||||
saveAs: 'Save as',
|
||||
import: 'Import',
|
||||
export: 'Export',
|
||||
shortcutKey: 'Shortcut key'
|
||||
}
|
||||
}
|
||||
7
web/src/lang/index.js
Normal file
7
web/src/lang/index.js
Normal file
@@ -0,0 +1,7 @@
|
||||
import en from './en_us'
|
||||
import zh from './zh_cn'
|
||||
|
||||
export default {
|
||||
zh,
|
||||
en
|
||||
}
|
||||
165
web/src/lang/zh_cn.js
Normal file
165
web/src/lang/zh_cn.js
Normal file
@@ -0,0 +1,165 @@
|
||||
export default {
|
||||
baseStyle: {
|
||||
title: '基础样式',
|
||||
background: '背景',
|
||||
color: '颜色',
|
||||
image: '图片',
|
||||
imageRepeat: '图片重复',
|
||||
line: '连线',
|
||||
width: '粗细',
|
||||
style: '风格',
|
||||
lineOfOutline: '概要的连线',
|
||||
nodePadding: '节点内边距',
|
||||
nodeMargin: '节点外边距',
|
||||
horizontal: '水平',
|
||||
vertical: '垂直',
|
||||
maximumWidth: '显示的最大宽度',
|
||||
maximumHeight: '显示的最大高度',
|
||||
icon: '图标',
|
||||
size: '大小',
|
||||
level2Node: '二级节点',
|
||||
belowLevel2Node: '三级及以下节点'
|
||||
},
|
||||
color: {
|
||||
moreColor: '更多颜色'
|
||||
},
|
||||
contextmenu: {
|
||||
insertSiblingNode: '插入同级节点',
|
||||
insertChildNode: '插入子级节点',
|
||||
insertSummary: '插入概要',
|
||||
moveUpNode: '上移节点',
|
||||
moveDownNode: '下移节点',
|
||||
deleteNode: '删除节点',
|
||||
copyNode: '复制节点',
|
||||
cutNode: '剪切节点',
|
||||
pasteNode: '粘贴节点',
|
||||
backCenter: '回到中心',
|
||||
expandAll: '展开所有',
|
||||
unExpandAll: '收起所有',
|
||||
expandTo: '展开到',
|
||||
arrangeLayout: '一键整理布局',
|
||||
level1: '一级主题',
|
||||
level2: '二级主题',
|
||||
level3: '三级主题',
|
||||
level4: '四级主题',
|
||||
level5: '五级主题',
|
||||
level6: '六级主题',
|
||||
zenMode: '禅模式'
|
||||
},
|
||||
count: {
|
||||
words: '字数',
|
||||
nodes: '节点'
|
||||
},
|
||||
dialog: {
|
||||
cancel: '取 消',
|
||||
confirm: '确 定'
|
||||
},
|
||||
export: {
|
||||
title: '导出',
|
||||
filename: '导出文件名称',
|
||||
include: '是否包含主题、结构等配置数据',
|
||||
dedicatedFile: '专有文件',
|
||||
jsonFile: 'json文件',
|
||||
imageFile: '图片文件',
|
||||
svgFile: 'svg文件',
|
||||
pdfFile: 'pdf文件',
|
||||
tips: 'tips:.smm和.json文件可用于导入'
|
||||
},
|
||||
fullscreen: {
|
||||
fullscreen: '全屏'
|
||||
},
|
||||
import: {
|
||||
title: '导入',
|
||||
selectFile: '选取文件',
|
||||
supportFile: '支持.smm、.json、.xmind、.xlsx文件'
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: '开启小地图',
|
||||
readonly: '只读模式',
|
||||
edit: '编辑模式'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: '超链接',
|
||||
link: '链接',
|
||||
name: '名称'
|
||||
},
|
||||
nodeIcon: {
|
||||
title: '图标'
|
||||
},
|
||||
nodeImage: {
|
||||
title: '图片',
|
||||
imgTitle: '图片标题'
|
||||
},
|
||||
nodeNote: {
|
||||
title: '备注'
|
||||
},
|
||||
nodeTag: {
|
||||
title: '标签',
|
||||
addTip: '请按回车键添加'
|
||||
},
|
||||
outline: {
|
||||
title: '大纲'
|
||||
},
|
||||
scale: {
|
||||
zoomIn: '放大',
|
||||
zoomOut: '缩小'
|
||||
},
|
||||
shortcutKey: {
|
||||
title: '快捷键'
|
||||
},
|
||||
strusture: {
|
||||
title: '结构'
|
||||
},
|
||||
style: {
|
||||
title: '节点样式',
|
||||
normal: '常态',
|
||||
active: '选中状态',
|
||||
text: '文字',
|
||||
fontFamily: '字体',
|
||||
fontSize: '字号',
|
||||
lineHeight: '行高',
|
||||
color: '颜色',
|
||||
addFontWeight: '加粗',
|
||||
italic: '斜体',
|
||||
textDecoration: '划线',
|
||||
underline: '下划线',
|
||||
lineThrough: '中划线',
|
||||
overline: '上划线',
|
||||
border: '边框',
|
||||
style: '样式',
|
||||
width: '宽度',
|
||||
borderRadius: '圆角',
|
||||
background: '背景',
|
||||
shape: '形状',
|
||||
line: '线条',
|
||||
nodePadding: '节点内边距',
|
||||
horizontal: '水平',
|
||||
vertical: '垂直'
|
||||
},
|
||||
theme: {
|
||||
title: '主题'
|
||||
},
|
||||
toolbar: {
|
||||
undo: '回退',
|
||||
redo: '前进',
|
||||
insertSiblingNode: '插入同级节点',
|
||||
insertChildNode: '插入子节点',
|
||||
deleteNode: '删除节点',
|
||||
image: '图片',
|
||||
icon: '图标',
|
||||
link: '超链接',
|
||||
note: '备注',
|
||||
tag: '标签',
|
||||
summary: '概要',
|
||||
displayOutline: '显示大纲',
|
||||
baseStyle: '基础样式',
|
||||
theme: '主题',
|
||||
strusture: '结构',
|
||||
newFile: '新建',
|
||||
openFile: '打开',
|
||||
saveAs: '另存为',
|
||||
import: '导入',
|
||||
export: '导出',
|
||||
shortcutKey: '快捷键'
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import 'element-ui/lib/theme-chalk/index.css'
|
||||
import '@/assets/icon-font/iconfont.css'
|
||||
import 'viewerjs/dist/viewer.css'
|
||||
import VueViewer from 'v-viewer'
|
||||
import i18n from './i18n'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
Vue.prototype.$bus = new Vue()
|
||||
@@ -16,5 +17,6 @@ Vue.use(VueViewer)
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
router,
|
||||
store
|
||||
store,
|
||||
i18n
|
||||
}).$mount('#app')
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="container">
|
||||
<template v-if="show">
|
||||
<Toolbar></Toolbar>
|
||||
<Toolbar v-if="!isZenMode"></Toolbar>
|
||||
<Edit></Edit>
|
||||
</template>
|
||||
</div>
|
||||
@@ -10,7 +10,8 @@
|
||||
<script>
|
||||
import Toolbar from './components/Toolbar'
|
||||
import Edit from './components/Edit'
|
||||
import { mapActions } from 'vuex'
|
||||
import { mapState, mapActions, mapMutations } from 'vuex'
|
||||
import { getLocalConfig } from '@/api'
|
||||
|
||||
export default {
|
||||
name: 'Index',
|
||||
@@ -23,7 +24,13 @@ export default {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
isZenMode: state => state.localConfig.isZenMode
|
||||
})
|
||||
},
|
||||
async created() {
|
||||
this.initLocalConfig()
|
||||
const loading = this.$loading({
|
||||
lock: true,
|
||||
text: '正在加载,请稍后...'
|
||||
@@ -33,7 +40,23 @@ export default {
|
||||
loading.close()
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['getUserMindMapData'])
|
||||
...mapActions(['getUserMindMapData']),
|
||||
...mapMutations(['setLocalConfig']),
|
||||
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 19:07:03
|
||||
* @Desc: 初始化本地配置
|
||||
*/
|
||||
initLocalConfig() {
|
||||
let config = getLocalConfig()
|
||||
if (config) {
|
||||
this.setLocalConfig({
|
||||
...this.$store.state.localConfig,
|
||||
...config
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<Sidebar ref="sidebar" title="基础样式">
|
||||
<Sidebar ref="sidebar" :title="$t('baseStyle.title')">
|
||||
<div class="sidebarContent" v-if="data">
|
||||
<!-- 背景 -->
|
||||
<div class="title noTop">背景</div>
|
||||
<div class="title noTop">{{ $t('baseStyle.background') }}</div>
|
||||
<div class="row">
|
||||
<el-tabs class="tab" v-model="activeTab">
|
||||
<el-tab-pane label="颜色" name="color">
|
||||
<el-tab-pane :label="$t('baseStyle.color')" name="color">
|
||||
<Color
|
||||
:color="style.backgroundColor"
|
||||
@change="
|
||||
@@ -15,7 +15,7 @@
|
||||
"
|
||||
></Color>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="图片" name="image">
|
||||
<el-tab-pane :label="$t('baseStyle.image')" name="image">
|
||||
<ImgUpload
|
||||
class="imgUpload"
|
||||
v-model="style.backgroundImage"
|
||||
@@ -26,7 +26,7 @@
|
||||
"
|
||||
></ImgUpload>
|
||||
<div class="rowItem">
|
||||
<span class="name">图片重复</span>
|
||||
<span class="name">{{ $t('baseStyle.imageRepeat') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 120px"
|
||||
@@ -51,10 +51,10 @@
|
||||
</el-tabs>
|
||||
</div>
|
||||
<!-- 连线 -->
|
||||
<div class="title noTop">连线</div>
|
||||
<div class="title noTop">{{ $t('baseStyle.line') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">颜色</span>
|
||||
<span class="name">{{ $t('baseStyle.color') }}</span>
|
||||
<span
|
||||
class="block"
|
||||
v-popover:popover
|
||||
@@ -72,7 +72,7 @@
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">粗细</span>
|
||||
<span class="name">{{ $t('baseStyle.width') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -96,7 +96,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">风格</span>
|
||||
<span class="name">{{ $t('baseStyle.style') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -119,10 +119,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 概要连线 -->
|
||||
<div class="title noTop">概要的连线</div>
|
||||
<div class="title noTop">{{ $t('baseStyle.lineOfOutline') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">颜色</span>
|
||||
<span class="name">{{ $t('baseStyle.color') }}</span>
|
||||
<span
|
||||
class="block"
|
||||
v-popover:popover2
|
||||
@@ -140,7 +140,7 @@
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">粗细</span>
|
||||
<span class="name">{{ $t('baseStyle.width') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -163,10 +163,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 内边距 -->
|
||||
<div class="title noTop">节点内边距</div>
|
||||
<div class="title noTop">{{ $t('baseStyle.nodePadding') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">水平</span>
|
||||
<span class="name">{{ $t('baseStyle.horizontal') }}</span>
|
||||
<el-slider
|
||||
style="width: 200px"
|
||||
v-model="style.paddingX"
|
||||
@@ -180,7 +180,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">垂直</span>
|
||||
<span class="name">{{ $t('baseStyle.vertical') }}</span>
|
||||
<el-slider
|
||||
style="width: 200px"
|
||||
v-model="style.paddingY"
|
||||
@@ -193,10 +193,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图片 -->
|
||||
<div class="title noTop">图片</div>
|
||||
<div class="title noTop">{{ $t('baseStyle.image') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">显示的最大宽度</span>
|
||||
<span class="name">{{ $t('baseStyle.maximumWidth') }}</span>
|
||||
<el-slider
|
||||
style="width: 140px"
|
||||
v-model="style.imgMaxWidth"
|
||||
@@ -212,7 +212,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">显示的最大高度</span>
|
||||
<span class="name">{{ $t('baseStyle.maximumHeight') }}</span>
|
||||
<el-slider
|
||||
style="width: 140px"
|
||||
v-model="style.imgMaxHeight"
|
||||
@@ -227,10 +227,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 图标 -->
|
||||
<div class="title noTop">图标</div>
|
||||
<div class="title noTop">{{ $t('baseStyle.icon') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">大小</span>
|
||||
<span class="name">{{ $t('baseStyle.size') }}</span>
|
||||
<el-slider
|
||||
style="width: 200px"
|
||||
v-model="style.iconSize"
|
||||
@@ -245,18 +245,24 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 二级节点外边距 -->
|
||||
<div class="title noTop">节点外边距</div>
|
||||
<div class="title noTop">{{ $t('baseStyle.nodeMargin') }}</div>
|
||||
<div class="row column">
|
||||
<el-tabs
|
||||
class="tab"
|
||||
v-model="marginActiveTab"
|
||||
@tab-click="initMarginStyle"
|
||||
>
|
||||
<el-tab-pane label="二级节点" name="second"></el-tab-pane>
|
||||
<el-tab-pane label="三级及以下节点" name="node"></el-tab-pane>
|
||||
<el-tab-pane
|
||||
:label="$t('baseStyle.level2Node')"
|
||||
name="second"
|
||||
></el-tab-pane>
|
||||
<el-tab-pane
|
||||
:label="$t('baseStyle.belowLevel2Node')"
|
||||
name="node"
|
||||
></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="rowItem">
|
||||
<span class="name">水平</span>
|
||||
<span class="name">{{ $t('baseStyle.horizontal') }}</span>
|
||||
<el-slider
|
||||
:max="200"
|
||||
style="width: 200px"
|
||||
@@ -269,7 +275,7 @@
|
||||
></el-slider>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">垂直</span>
|
||||
<span class="name">{{ $t('baseStyle.vertical') }}</span>
|
||||
<el-slider
|
||||
:max="200"
|
||||
style="width: 200px"
|
||||
@@ -292,6 +298,7 @@ import Color from './Color'
|
||||
import { lineWidthList, lineStyleList, backgroundRepeatList } from '@/config'
|
||||
import ImgUpload from '@/components/ImgUpload'
|
||||
import { storeConfig } from '@/api'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -317,8 +324,6 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
lineWidthList,
|
||||
lineStyleList,
|
||||
backgroundRepeatList,
|
||||
activeTab: 'color',
|
||||
marginActiveTab: 'second',
|
||||
style: {
|
||||
@@ -340,14 +345,25 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('showBaseStyle', () => {
|
||||
this.$refs.sidebar.show = false
|
||||
this.$nextTick(() => {
|
||||
computed: {
|
||||
...mapState(['activeSidebar']),
|
||||
|
||||
lineStyleList() {
|
||||
return lineStyleList[this.$i18n.locale] || lineStyleList.zh
|
||||
},
|
||||
backgroundRepeatList() {
|
||||
return backgroundRepeatList[this.$i18n.locale] || backgroundRepeatList.zh
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
if (val === 'baseStyle') {
|
||||
this.$refs.sidebar.show = true
|
||||
this.initStyle()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.$refs.sidebar.show = false
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
></span>
|
||||
</div>
|
||||
<div class="moreColor">
|
||||
<span>更多颜色</span>
|
||||
<span>{{ $t('color.moreColor') }}</span>
|
||||
<el-color-picker
|
||||
size="mini"
|
||||
v-model="selectColor"
|
||||
|
||||
@@ -10,11 +10,11 @@
|
||||
@click="exec('INSERT_NODE', insertNodeBtnDisabled)"
|
||||
:class="{ disabled: insertNodeBtnDisabled }"
|
||||
>
|
||||
插入同级节点
|
||||
{{ $t('contextmenu.insertSiblingNode') }}
|
||||
<span class="desc">Enter</span>
|
||||
</div>
|
||||
<div class="item" @click="exec('INSERT_CHILD_NODE')">
|
||||
插入子级节点
|
||||
{{ $t('contextmenu.insertChildNode') }}
|
||||
<span class="desc">Tab</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -22,7 +22,7 @@
|
||||
@click="exec('ADD_GENERALIZATION')"
|
||||
:class="{ disabled: insertNodeBtnDisabled }"
|
||||
>
|
||||
插入概要
|
||||
{{ $t('contextmenu.insertSummary') }}
|
||||
<span class="desc">Ctrl + S</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -30,7 +30,7 @@
|
||||
@click="exec('UP_NODE')"
|
||||
:class="{ disabled: upNodeBtnDisabled }"
|
||||
>
|
||||
上移节点
|
||||
{{ $t('contextmenu.moveUpNode') }}
|
||||
<span class="desc">Ctrl + ↑</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -38,19 +38,19 @@
|
||||
@click="exec('DOWN_NODE')"
|
||||
:class="{ disabled: downNodeBtnDisabled }"
|
||||
>
|
||||
下移节点
|
||||
{{ $t('contextmenu.moveDownNode') }}
|
||||
<span class="desc">Ctrl + ↓</span>
|
||||
</div>
|
||||
<div class="item danger" @click="exec('REMOVE_NODE')">
|
||||
删除节点
|
||||
{{ $t('contextmenu.deleteNode') }}
|
||||
<span class="desc">Delete</span>
|
||||
</div>
|
||||
<div class="item" @click="exec('COPY_NODE')">
|
||||
复制节点
|
||||
{{ $t('contextmenu.copyNode') }}
|
||||
<span class="desc">Ctrl + C</span>
|
||||
</div>
|
||||
<div class="item" @click="exec('CUT_NODE')">
|
||||
剪切节点
|
||||
{{ $t('contextmenu.cutNode') }}
|
||||
<span class="desc">Ctrl + X</span>
|
||||
</div>
|
||||
<div
|
||||
@@ -58,16 +58,22 @@
|
||||
:class="{ disabled: copyData === null }"
|
||||
@click="exec('PASTE_NODE')"
|
||||
>
|
||||
粘贴节点
|
||||
{{ $t('contextmenu.pasteNode') }}
|
||||
<span class="desc">Ctrl + V</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-if="type === 'svg'">
|
||||
<div class="item" @click="exec('RETURN_CENTER')">回到中心</div>
|
||||
<div class="item" @click="exec('EXPAND_ALL')">展开所有</div>
|
||||
<div class="item" @click="exec('UNEXPAND_ALL')">收起所有</div>
|
||||
<div class="item" @click="exec('RETURN_CENTER')">
|
||||
{{ $t('contextmenu.backCenter') }}
|
||||
</div>
|
||||
<div class="item" @click="exec('EXPAND_ALL')">
|
||||
{{ $t('contextmenu.expandAll') }}
|
||||
</div>
|
||||
<div class="item" @click="exec('UNEXPAND_ALL')">
|
||||
{{ $t('contextmenu.unExpandAll') }}
|
||||
</div>
|
||||
<div class="item">
|
||||
展开到
|
||||
{{ $t('contextmenu.expandTo') }}
|
||||
<div class="subItems listBox">
|
||||
<div
|
||||
class="item"
|
||||
@@ -80,14 +86,20 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="item" @click="exec('RESET_LAYOUT')">
|
||||
一键整理布局
|
||||
{{ $t('contextmenu.arrangeLayout') }}
|
||||
<span class="desc">Ctrl + L</span>
|
||||
</div>
|
||||
<div class="item" @click="exec('TOGGLE_ZEN_MODE')">
|
||||
{{ $t('contextmenu.zenMode') }}
|
||||
{{ isZenMode ? '√' : '' }}
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-24 22:53:10
|
||||
@@ -110,18 +122,23 @@ export default {
|
||||
type: '',
|
||||
isMousedown: false,
|
||||
mosuedownX: 0,
|
||||
mosuedownY: 0,
|
||||
expandList: [
|
||||
'一级主题',
|
||||
'二级主题',
|
||||
'三级主题',
|
||||
'四级主题',
|
||||
'五级主题',
|
||||
'六级主题'
|
||||
]
|
||||
mosuedownY: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
isZenMode: state => state.localConfig.isZenMode
|
||||
}),
|
||||
expandList() {
|
||||
return [
|
||||
this.$t('contextmenu.level1'),
|
||||
this.$t('contextmenu.level2'),
|
||||
this.$t('contextmenu.level3'),
|
||||
this.$t('contextmenu.level4'),
|
||||
this.$t('contextmenu.level5'),
|
||||
this.$t('contextmenu.level6')
|
||||
]
|
||||
},
|
||||
insertNodeBtnDisabled() {
|
||||
return !this.node || this.node.isRoot
|
||||
},
|
||||
@@ -173,6 +190,8 @@ export default {
|
||||
this.mindMap.keyCommand.removeShortcut('Control+x', this.cut)
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setLocalConfig']),
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-07-14 21:38:50
|
||||
@@ -268,6 +287,11 @@ export default {
|
||||
case 'RETURN_CENTER':
|
||||
this.mindMap.view.reset()
|
||||
break
|
||||
case 'TOGGLE_ZEN_MODE':
|
||||
this.setLocalConfig({
|
||||
isZenMode: !this.isZenMode
|
||||
})
|
||||
break
|
||||
default:
|
||||
this.$bus.$emit('execCommand', key, ...args)
|
||||
break
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="countContainer">
|
||||
<div class="item">
|
||||
<span class="name">字数</span>
|
||||
<span class="name">{{ $t('count.words') }}</span>
|
||||
<span class="value">{{ words }}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="name">节点</span>
|
||||
<span class="name">{{ $t('count.nodes') }}</span>
|
||||
<span class="value">{{ num }}</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,13 +27,23 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('data_change', data => {
|
||||
this.$bus.$on('data_change', this.onDataChange)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('data_change', this.onDataChange)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 19:20:20
|
||||
* @Desc: 监听数据变化
|
||||
*/
|
||||
onDataChange(data) {
|
||||
this.words = 0
|
||||
this.num = 0
|
||||
this.walk(data)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-30 22:13:07
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
<template>
|
||||
<div class="editContainer">
|
||||
<div class="mindMapContainer" ref="mindMapContainer"></div>
|
||||
<Count></Count>
|
||||
<Count v-if="!isZenMode"></Count>
|
||||
<Navigator :mindMap="mindMap"></Navigator>
|
||||
<NavigatorToolbar :mindMap="mindMap"></NavigatorToolbar>
|
||||
<Outline></Outline>
|
||||
<Style></Style>
|
||||
<NavigatorToolbar :mindMap="mindMap" v-if="!isZenMode"></NavigatorToolbar>
|
||||
<Outline :mindMap="mindMap"></Outline>
|
||||
<Style v-if="!isZenMode"></Style>
|
||||
<BaseStyle :data="mindMapData" :mindMap="mindMap"></BaseStyle>
|
||||
<Theme :mindMap="mindMap"></Theme>
|
||||
<Structure :mindMap="mindMap"></Structure>
|
||||
<ShortcutKey></ShortcutKey>
|
||||
<Contextmenu v-if="mindMap" :mindMap="mindMap"></Contextmenu>
|
||||
<NodeNoteContentShow></NodeNoteContentShow>
|
||||
<NodeNoteContentShow
|
||||
v-if="mindMap"
|
||||
:mindMap="mindMap"
|
||||
></NodeNoteContentShow>
|
||||
<NodeImgPreview v-if="mindMap" :mindMap="mindMap"></NodeImgPreview>
|
||||
<SidebarTrigger v-if="!isZenMode"></SidebarTrigger>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -31,6 +35,8 @@ import NodeNoteContentShow from './NodeNoteContentShow.vue'
|
||||
import { getData, storeData, storeConfig } from '@/api'
|
||||
import Navigator from './Navigator.vue'
|
||||
import NodeImgPreview from './NodeImgPreview.vue'
|
||||
import SidebarTrigger from './SidebarTrigger.vue'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -51,7 +57,8 @@ export default {
|
||||
Contextmenu,
|
||||
NodeNoteContentShow,
|
||||
Navigator,
|
||||
NodeImgPreview
|
||||
NodeImgPreview,
|
||||
SidebarTrigger
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -61,6 +68,11 @@ export default {
|
||||
openTest: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
isZenMode: state => state.localConfig.isZenMode
|
||||
})
|
||||
},
|
||||
mounted() {
|
||||
this.getData()
|
||||
this.init()
|
||||
@@ -225,7 +237,7 @@ export default {
|
||||
this.$bus.$emit('showNoteContent', content, left, top)
|
||||
},
|
||||
hide: () => {
|
||||
this.$bus.$emit('hideNoteContent')
|
||||
// this.$bus.$emit('hideNoteContent')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="nodeDialog"
|
||||
title="导出"
|
||||
:title="$t('export.title')"
|
||||
:visible.sync="dialogVisible"
|
||||
width="700px"
|
||||
>
|
||||
<div>
|
||||
<div class="nameInputBox">
|
||||
<span class="name">导出文件名称</span>
|
||||
<span class="name">{{ $t('export.filename') }}</span>
|
||||
<el-input
|
||||
style="width: 300px"
|
||||
v-model="fileName"
|
||||
@@ -17,21 +17,33 @@
|
||||
v-show="['smm', 'json'].includes(exportType)"
|
||||
v-model="widthConfig"
|
||||
style="margin-left: 12px"
|
||||
>是否包含主题、结构等配置数据</el-checkbox
|
||||
>{{ $t('export.include') }}</el-checkbox
|
||||
>
|
||||
</div>
|
||||
<el-radio-group v-model="exportType" size="mini">
|
||||
<el-radio-button label="smm">专有文件(.smm)</el-radio-button>
|
||||
<el-radio-button label="json">json文件(.json)</el-radio-button>
|
||||
<el-radio-button label="png">图片文件(.png)</el-radio-button>
|
||||
<el-radio-button label="svg">svg文件(.svg)</el-radio-button>
|
||||
<el-radio-button label="pdf">pdf文件(.pdf)</el-radio-button>
|
||||
<el-radio-button label="smm"
|
||||
>{{ $t('export.dedicatedFile') }}(.smm)</el-radio-button
|
||||
>
|
||||
<el-radio-button label="json"
|
||||
>{{ $t('export.jsonFile') }}(.json)</el-radio-button
|
||||
>
|
||||
<el-radio-button label="png"
|
||||
>{{ $t('export.imageFile') }}(.png)</el-radio-button
|
||||
>
|
||||
<el-radio-button label="svg"
|
||||
>{{ $t('export.svgFile') }}(.svg)</el-radio-button
|
||||
>
|
||||
<el-radio-button label="pdf"
|
||||
>{{ $t('export.pdfFile') }}(.pdf)</el-radio-button
|
||||
>
|
||||
</el-radio-group>
|
||||
<div class="tip">tips:.smm和.json文件可用于导入</div>
|
||||
<div class="tip">{{ $t('export.tips') }}</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" @click="confirm">确 定</el-button>
|
||||
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('dialog.confirm')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div class="fullscreenContainer">
|
||||
<el-tooltip class="item" effect="dark" content="全屏" placement="top">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="$t('fullscreen.fullscreen')"
|
||||
placement="top"
|
||||
>
|
||||
<div class="btn iconfont iconquanping" @click="toFullscreen"></div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="nodeDialog"
|
||||
title="导入"
|
||||
:title="$t('import.title')"
|
||||
:visible.sync="dialogVisible"
|
||||
width="300px"
|
||||
>
|
||||
@@ -15,14 +15,18 @@
|
||||
:limit="1"
|
||||
:on-exceed="onExceed"
|
||||
>
|
||||
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
|
||||
<el-button slot="trigger" size="small" type="primary">{{
|
||||
$t('import.selectFile')
|
||||
}}</el-button>
|
||||
<div slot="tip" class="el-upload__tip">
|
||||
支持.smm、.json、.xmind、.xlsx文件
|
||||
{{ $t('import.supportFile') }}
|
||||
</div>
|
||||
</el-upload>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" @click="confirm">确 定</el-button>
|
||||
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('dialog.confirm')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@@ -1,15 +1,30 @@
|
||||
<template>
|
||||
<div class="navigatorContainer">
|
||||
<div class="item">
|
||||
<el-checkbox v-model="openMiniMap" @change="toggleMiniMap"
|
||||
>开启小地图</el-checkbox
|
||||
<el-select
|
||||
v-model="lang"
|
||||
size="small"
|
||||
style="width: 100px"
|
||||
@change="onLangChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in langList"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-checkbox v-model="openMiniMap" @change="toggleMiniMap">{{
|
||||
$t('navigatorToolbar.openMiniMap')
|
||||
}}</el-checkbox>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-switch
|
||||
v-model="isReadonly"
|
||||
active-text="只读模式"
|
||||
inactive-text="编辑模式"
|
||||
:active-text="$t('navigatorToolbar.readonly')"
|
||||
:inactive-text="$t('navigatorToolbar.edit')"
|
||||
@change="readonlyChange"
|
||||
>
|
||||
</el-switch>
|
||||
@@ -26,6 +41,9 @@
|
||||
<script>
|
||||
import Scale from './Scale'
|
||||
import Fullscreen from './Fullscreen'
|
||||
import { langList } from '@/config'
|
||||
import i18n from '@/i18n'
|
||||
import { storeLang, getLang } from '@/api'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -45,6 +63,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
langList,
|
||||
lang: getLang(),
|
||||
isReadonly: false,
|
||||
openMiniMap: false
|
||||
}
|
||||
@@ -59,6 +79,11 @@ export default {
|
||||
|
||||
toggleMiniMap(show) {
|
||||
this.$bus.$emit('toggle_mini_map', show)
|
||||
},
|
||||
|
||||
onLangChange(lang) {
|
||||
i18n.locale = lang
|
||||
storeLang(lang)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="nodeDialog"
|
||||
title="超链接"
|
||||
:title="$t('nodeHyperlink.title')"
|
||||
:visible.sync="dialogVisible"
|
||||
width="500"
|
||||
>
|
||||
<div class="item">
|
||||
<span class="name">链接</span>
|
||||
<span class="name">{{ $t('nodeHyperlink.link') }}</span>
|
||||
<el-input
|
||||
v-model="link"
|
||||
size="mini"
|
||||
placeholder="http://xxxx.com/"
|
||||
@keyup.native.stop
|
||||
></el-input>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="name">名称</span>
|
||||
<el-input v-model="linkTitle" size="mini"></el-input>
|
||||
<span class="name">{{ $t('nodeHyperlink.name') }}</span>
|
||||
<el-input v-model="linkTitle" size="mini" @keyup.native.stop></el-input>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" @click="confirm">确 定</el-button>
|
||||
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('dialog.confirm')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="nodeDialog"
|
||||
title="图标"
|
||||
:title="$t('nodeIcon.title')"
|
||||
:visible.sync="dialogVisible"
|
||||
width="500"
|
||||
>
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="nodeDialog"
|
||||
title="图片"
|
||||
:title="$t('nodeImage.title')"
|
||||
:visible.sync="dialogVisible"
|
||||
width="500"
|
||||
>
|
||||
<ImgUpload ref="ImgUpload" v-model="img"></ImgUpload>
|
||||
<div class="imgTitleBox">
|
||||
<span class="title">图片标题</span>
|
||||
<span class="title">{{ $t('nodeImage.imgTitle') }}</span>
|
||||
<el-input v-model="imgTitle" size="mini"></el-input>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" @click="confirm">确 定</el-button>
|
||||
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('dialog.confirm')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="nodeDialog"
|
||||
title="备注"
|
||||
:title="$t('nodeNote.title')"
|
||||
:visible.sync="dialogVisible"
|
||||
width="500"
|
||||
>
|
||||
@@ -12,11 +12,13 @@
|
||||
v-model="note"
|
||||
>
|
||||
</el-input> -->
|
||||
<div class="noteEditor" ref="noteEditor"></div>
|
||||
<div class="noteEditor" ref="noteEditor" @keyup.stop></div>
|
||||
<!-- <div class="tip">换行请使用:Enter+Shift</div> -->
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" @click="confirm">确 定</el-button>
|
||||
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('dialog.confirm')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
top: this.top + 'px',
|
||||
visibility: show ? 'visible' : 'hidden'
|
||||
}"
|
||||
@click.stop
|
||||
></div>
|
||||
</template>
|
||||
|
||||
@@ -30,20 +31,42 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('showNoteContent', (content, left, top) => {
|
||||
this.editor.setMarkdown(content)
|
||||
this.left = left
|
||||
this.top = top
|
||||
this.show = true
|
||||
})
|
||||
this.$bus.$on('hideNoteContent', () => {
|
||||
this.show = false
|
||||
})
|
||||
this.$bus.$on('showNoteContent', this.onShowNoteContent)
|
||||
this.$bus.$on('hideNoteContent', this.hideNoteContent)
|
||||
document.body.addEventListener('click', this.hideNoteContent)
|
||||
this.$bus.$on('node_active', this.hideNoteContent)
|
||||
},
|
||||
mounted() {
|
||||
this.initEditor()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('showNoteContent', this.onShowNoteContent)
|
||||
this.$bus.$off('hideNoteContent', this.hideNoteContent)
|
||||
document.body.removeEventListener('click', this.hideNoteContent)
|
||||
this.$bus.$off('node_active', this.hideNoteContent)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 19:56:08
|
||||
* @Desc: 显示备注浮层
|
||||
*/
|
||||
onShowNoteContent(content, left, top) {
|
||||
this.editor.setMarkdown(content)
|
||||
this.left = left
|
||||
this.top = top
|
||||
this.show = true
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 19:56:20
|
||||
* @Desc: 隐藏备注浮层
|
||||
*/
|
||||
hideNoteContent() {
|
||||
this.show = false
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-05-09 11:37:05
|
||||
@@ -66,5 +89,24 @@ export default {
|
||||
background-color: #fff;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
max-height: 300px;
|
||||
overflow-y: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 7px;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="nodeDialog"
|
||||
title="标签"
|
||||
:title="$t('nodeTag.title')"
|
||||
:visible.sync="dialogVisible"
|
||||
width="500"
|
||||
>
|
||||
<el-input
|
||||
v-model="tag"
|
||||
@keyup.native.enter="add"
|
||||
@keyup.native.stop
|
||||
:disabled="tagArr.length >= max"
|
||||
placeholder="请按回车键添加"
|
||||
:placeholder="$t('nodeTag.addTip')"
|
||||
>
|
||||
</el-input>
|
||||
<div class="tagList">
|
||||
@@ -29,8 +30,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
<el-button type="primary" @click="confirm">确 定</el-button>
|
||||
<el-button @click="cancel">{{ $t('dialog.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="confirm">{{
|
||||
$t('dialog.confirm')
|
||||
}}</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
@@ -1,11 +1,30 @@
|
||||
<template>
|
||||
<Sidebar ref="sidebar" title="大纲">
|
||||
<el-tree :data="data" :props="defaultProps" default-expand-all></el-tree>
|
||||
<Sidebar ref="sidebar" :title="$t('outline.title')">
|
||||
<el-tree
|
||||
class="outlineTree"
|
||||
:data="data"
|
||||
:props="defaultProps"
|
||||
:expand-on-click-node="false"
|
||||
default-expand-all
|
||||
>
|
||||
<span class="customNode" slot-scope="{ node, data }">
|
||||
<span
|
||||
class="nodeEdit"
|
||||
:key="getKey()"
|
||||
contenteditable="true"
|
||||
@keydown.stop
|
||||
@keyup.stop
|
||||
@blur="onBlur($event, node)"
|
||||
v-html="node.label"
|
||||
></span>
|
||||
</span>
|
||||
</el-tree>
|
||||
</Sidebar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Sidebar from './Sidebar'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -17,28 +36,97 @@ export default {
|
||||
components: {
|
||||
Sidebar
|
||||
},
|
||||
props: {
|
||||
mindMap: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
data: [],
|
||||
defaultProps: {
|
||||
label(data) {
|
||||
return data.data.text
|
||||
return data.data.text.replaceAll(/\n/g, '</br>')
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['activeSidebar'])
|
||||
},
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
if (val === 'outline') {
|
||||
this.$refs.sidebar.show = true
|
||||
} else {
|
||||
this.$refs.sidebar.show = false
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('data_change', data => {
|
||||
this.data = [data]
|
||||
})
|
||||
this.$bus.$on('showOutline', () => {
|
||||
this.$refs.sidebar.show = false
|
||||
this.$nextTick(() => {
|
||||
this.$refs.sidebar.show = true
|
||||
})
|
||||
this.data = [this.mindMap.renderer.renderTree]
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
onBlur(e, node) {
|
||||
node.data._node.setText(e.target.innerText)
|
||||
},
|
||||
|
||||
getKey() {
|
||||
return Math.random()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style lang="less" scoped>
|
||||
.customNode {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
width: 7px;
|
||||
height: 7px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
border-radius: 7px;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
box-shadow: none;
|
||||
background: transparent;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.nodeEdit {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.outlineTree {
|
||||
/deep/ .el-tree-node__content {
|
||||
height: auto;
|
||||
margin: 5px 0;
|
||||
|
||||
.el-tree-node__expand-icon.is-leaf {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
width: 5px;
|
||||
height: 5px;
|
||||
border-radius: 50%;
|
||||
background-color: #c0c4cc;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
<template>
|
||||
<div class="scaleContainer">
|
||||
<el-tooltip class="item" effect="dark" content="缩小" placement="top">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="$t('scale.zoomOut')"
|
||||
placement="top"
|
||||
>
|
||||
<div class="btn el-icon-minus" @click="narrow"></div>
|
||||
</el-tooltip>
|
||||
<div class="scaleInfo">{{ scaleNum }}%</div>
|
||||
<el-tooltip class="item" effect="dark" content="放大" placement="top">
|
||||
<el-tooltip
|
||||
class="item"
|
||||
effect="dark"
|
||||
:content="$t('scale.zoomIn')"
|
||||
placement="top"
|
||||
>
|
||||
<div class="btn el-icon-plus" @click="enlarge"></div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Sidebar ref="sidebar" title="快捷键">
|
||||
<Sidebar ref="sidebar" :title="$t('shortcutKey.title')">
|
||||
<div class="box">
|
||||
<div v-for="item in shortcutKeyList" :key="item.type">
|
||||
<div class="title">{{ item.type }}</div>
|
||||
@@ -22,6 +22,7 @@
|
||||
<script>
|
||||
import Sidebar from './Sidebar'
|
||||
import { shortcutKeyList } from '@/config'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -34,17 +35,23 @@ export default {
|
||||
Sidebar
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shortcutKeyList
|
||||
return {}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['activeSidebar']),
|
||||
|
||||
shortcutKeyList() {
|
||||
return shortcutKeyList[this.$i18n.locale] || shortcutKeyList.zh
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('showShortcutKey', () => {
|
||||
this.$refs.sidebar.show = false
|
||||
this.$nextTick(() => {
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
if (val === 'shortcutKey') {
|
||||
this.$refs.sidebar.show = true
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.$refs.sidebar.show = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
:class="{ show: show }"
|
||||
:style="{ zIndex: zIndex }"
|
||||
>
|
||||
<span class="closeBtn el-icon-close" @click="show = false"></span>
|
||||
<span class="closeBtn el-icon-close" @click="close"></span>
|
||||
<div class="sidebarHeader" v-if="title">
|
||||
{{ title }}
|
||||
</div>
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
<script>
|
||||
import { store } from '@/config'
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -43,6 +44,14 @@ export default {
|
||||
this.zIndex = store.sidebarZIndex++
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setActiveSidebar']),
|
||||
|
||||
close() {
|
||||
this.show = false
|
||||
this.setActiveSidebar('')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
107
web/src/pages/Edit/components/SidebarTrigger.vue
Normal file
107
web/src/pages/Edit/components/SidebarTrigger.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<div
|
||||
class="sidebarTriggerContainer"
|
||||
@click.stop
|
||||
:class="{ show: activeSidebar }"
|
||||
>
|
||||
<div class="trigger">
|
||||
<div
|
||||
class="triggerItem"
|
||||
v-for="item in triggerList"
|
||||
:key="item.value"
|
||||
:class="{ active: activeSidebar === item.value }"
|
||||
@click="trigger(item)"
|
||||
>
|
||||
<div class="triggerIcon iconfont" :class="[item.icon]"></div>
|
||||
<div class="triggerName">{{ item.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
import { sidebarTriggerList } from '@/config'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-06-24 22:54:25
|
||||
* @Desc: 侧边栏触发器
|
||||
*/
|
||||
export default {
|
||||
name: 'SidebarTrigger',
|
||||
data() {
|
||||
return {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['activeSidebar']),
|
||||
|
||||
triggerList() {
|
||||
return sidebarTriggerList[this.$i18n.locale] || sidebarTriggerList.zh
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setActiveSidebar']),
|
||||
|
||||
trigger(item) {
|
||||
this.setActiveSidebar(item.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sidebarTriggerContainer {
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
margin-top: 110px;
|
||||
transition: all 0.3s;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
&.show {
|
||||
right: 305px;
|
||||
}
|
||||
|
||||
.trigger {
|
||||
width: 60px;
|
||||
border-color: #eee;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 2px 16px 0 rgba(0, 0, 0, 0.06);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
|
||||
.triggerItem {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
color: #464646;
|
||||
user-select: none;
|
||||
white-space: nowrap;
|
||||
|
||||
&:hover {
|
||||
background-color: #ededed;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #409eff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.triggerIcon {
|
||||
font-size: 18px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.triggerName {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Sidebar ref="sidebar" title="结构">
|
||||
<Sidebar ref="sidebar" :title="$t('strusture.title')">
|
||||
<div class="layoutList">
|
||||
<div
|
||||
class="layoutItem"
|
||||
@@ -21,6 +21,7 @@
|
||||
import Sidebar from './Sidebar'
|
||||
import { layoutList } from 'simple-mind-map/src/utils/constant'
|
||||
import { storeConfig } from '@/api'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -43,14 +44,18 @@ export default {
|
||||
layout: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('showStructure', () => {
|
||||
this.$refs.sidebar.show = false
|
||||
this.$nextTick(() => {
|
||||
computed: {
|
||||
...mapState(['activeSidebar'])
|
||||
},
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
if (val === 'structure') {
|
||||
this.layout = this.mindMap.getLayout()
|
||||
this.$refs.sidebar.show = true
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.$refs.sidebar.show = false
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<Sidebar ref="sidebar" title="节点样式">
|
||||
<div class="styleBox">
|
||||
<Sidebar ref="sidebar" :title="$t('style.title')">
|
||||
<div class="styleBox" v-if="activeNodes.length > 0">
|
||||
<el-tabs class="tab" v-model="activeTab" @tab-click="handleTabClick">
|
||||
<el-tab-pane label="常态" name="normal"></el-tab-pane>
|
||||
<el-tab-pane label="选中状态" name="active"></el-tab-pane>
|
||||
<el-tab-pane :label="$t('style.normal')" name="normal"></el-tab-pane>
|
||||
<el-tab-pane :label="$t('style.active')" name="active"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="sidebarContent" v-if="activeNodes.length > 0">
|
||||
<!-- 文字 -->
|
||||
<div class="title noTop">文字</div>
|
||||
<div class="title noTop">{{ $t('style.text') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">字体</span>
|
||||
<span class="name">{{ $t('style.fontFamily') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
v-model="style.fontFamily"
|
||||
@@ -31,7 +31,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">字号</span>
|
||||
<span class="name">{{ $t('style.fontSize') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -50,7 +50,7 @@
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">行高</span>
|
||||
<span class="name">{{ $t('style.lineHeight') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -71,7 +71,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="btnGroup">
|
||||
<el-tooltip content="颜色" placement="bottom">
|
||||
<el-tooltip :content="$t('style.color')" placement="bottom">
|
||||
<div
|
||||
class="styleBtn"
|
||||
v-popover:popover
|
||||
@@ -84,7 +84,7 @@
|
||||
></span>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="加粗" placement="bottom">
|
||||
<el-tooltip :content="$t('style.addFontWeight')" placement="bottom">
|
||||
<div
|
||||
class="styleBtn"
|
||||
:class="{
|
||||
@@ -96,7 +96,7 @@
|
||||
B
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="斜体" placement="bottom">
|
||||
<el-tooltip :content="$t('style.italic')" placement="bottom">
|
||||
<div
|
||||
class="styleBtn i"
|
||||
:class="{
|
||||
@@ -108,7 +108,10 @@
|
||||
I
|
||||
</div>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="划线" placement="bottom">
|
||||
<el-tooltip
|
||||
:content="$t('style.textDecoration')"
|
||||
placement="bottom"
|
||||
>
|
||||
<div
|
||||
class="styleBtn u"
|
||||
:style="{ textDecoration: style.textDecoration || 'none' }"
|
||||
@@ -138,17 +141,23 @@
|
||||
v-model="style.textDecoration"
|
||||
@change="update('textDecoration')"
|
||||
>
|
||||
<el-radio-button label="underline">下划线</el-radio-button>
|
||||
<el-radio-button label="line-through">中划线</el-radio-button>
|
||||
<el-radio-button label="overline">上划线</el-radio-button>
|
||||
<el-radio-button label="underline">{{
|
||||
$t('style.underline')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="line-through">{{
|
||||
$t('style.lineThrough')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="overline">{{
|
||||
$t('style.overline')
|
||||
}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-popover>
|
||||
</div>
|
||||
<!-- 边框 -->
|
||||
<div class="title">边框</div>
|
||||
<div class="title">{{ $t('style.border') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">颜色</span>
|
||||
<span class="name">{{ $t('style.color') }}</span>
|
||||
<span
|
||||
class="block"
|
||||
v-popover:popover3
|
||||
@@ -168,7 +177,7 @@
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">样式</span>
|
||||
<span class="name">{{ $t('style.style') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -189,7 +198,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">宽度</span>
|
||||
<span class="name">{{ $t('style.width') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -208,7 +217,7 @@
|
||||
</el-select>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">圆角</span>
|
||||
<span class="name">{{ $t('style.borderRadius') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -228,10 +237,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 背景 -->
|
||||
<div class="title">背景</div>
|
||||
<div class="title">{{ $t('style.background') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">颜色</span>
|
||||
<span class="name">{{ $t('style.color') }}</span>
|
||||
<span
|
||||
class="block"
|
||||
v-popover:popover4
|
||||
@@ -249,10 +258,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 形状 -->
|
||||
<div class="title">形状</div>
|
||||
<div class="title">{{ $t('style.shape') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">形状</span>
|
||||
<span class="name">{{ $t('style.shape') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 120px"
|
||||
@@ -272,10 +281,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 线条 -->
|
||||
<div class="title">线条</div>
|
||||
<div class="title">{{ $t('style.line') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">颜色</span>
|
||||
<span class="name">{{ $t('style.color') }}</span>
|
||||
<span
|
||||
class="block"
|
||||
v-popover:popover5
|
||||
@@ -292,7 +301,7 @@
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">样式</span>
|
||||
<span class="name">{{ $t('style.style') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -313,7 +322,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">宽度</span>
|
||||
<span class="name">{{ $t('style.width') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
@@ -333,10 +342,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 节点内边距 -->
|
||||
<div class="title noTop">节点内边距</div>
|
||||
<div class="title noTop">{{ $t('style.nodePadding') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">水平</span>
|
||||
<span class="name">{{ $t('style.horizontal') }}</span>
|
||||
<el-slider
|
||||
style="width: 200px"
|
||||
v-model="style.paddingX"
|
||||
@@ -347,7 +356,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">垂直</span>
|
||||
<span class="name">{{ $t('style.vertical') }}</span>
|
||||
<el-slider
|
||||
style="width: 200px"
|
||||
v-model="style.paddingY"
|
||||
@@ -358,6 +367,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tipBox" v-else>
|
||||
<div class="tipIcon iconfont icontianjiazijiedian"></div>
|
||||
<div class="tipText">请选择一个节点</div>
|
||||
</div>
|
||||
</Sidebar>
|
||||
</template>
|
||||
|
||||
@@ -374,6 +387,7 @@ import {
|
||||
shapeList
|
||||
} from '@/config'
|
||||
import { supportActiveStyle } from 'simple-mind-map/src/themes/default'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -389,11 +403,10 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
supportActiveStyle,
|
||||
shapeList,
|
||||
fontFamilyList,
|
||||
|
||||
fontSizeList,
|
||||
borderWidthList,
|
||||
borderDasharrayList,
|
||||
|
||||
borderRadiusList,
|
||||
lineHeightList,
|
||||
activeNodes: [],
|
||||
@@ -420,19 +433,48 @@ export default {
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['activeSidebar']),
|
||||
|
||||
fontFamilyList() {
|
||||
return fontFamilyList[this.$i18n.locale] || fontFamilyList.zh
|
||||
},
|
||||
borderDasharrayList() {
|
||||
return borderDasharrayList[this.$i18n.locale] || borderDasharrayList.zh
|
||||
},
|
||||
shapeList() {
|
||||
return shapeList[this.$i18n.locale] || shapeList.zh
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
if (val === 'nodeStyle') {
|
||||
this.$refs.sidebar.show = true
|
||||
} else {
|
||||
this.$refs.sidebar.show = false
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('node_active', (...args) => {
|
||||
if (this.$refs.sidebar) this.$refs.sidebar.show = false
|
||||
this.$bus.$on('node_active', this.onNodeActive)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('node_active', this.onNodeActive)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 19:16:21
|
||||
* @Desc: 监听节点激活事件
|
||||
*/
|
||||
onNodeActive(...args) {
|
||||
this.$nextTick(() => {
|
||||
this.activeTab = 'normal'
|
||||
this.activeNodes = args[1]
|
||||
if (this.$refs.sidebar)
|
||||
this.$refs.sidebar.show = this.activeNodes.length > 0
|
||||
this.initNodeStyle()
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2021-05-05 11:42:32
|
||||
@@ -587,6 +629,20 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
.tipBox {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #666;
|
||||
|
||||
.tipIcon {
|
||||
font-size: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
.sidebarContent {
|
||||
padding: 20px;
|
||||
padding-top: 10px;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<Sidebar ref="sidebar" title="主题">
|
||||
<Sidebar ref="sidebar" :title="$t('style.title')">
|
||||
<div class="themeList">
|
||||
<div
|
||||
class="themeItem"
|
||||
@@ -21,6 +21,7 @@
|
||||
import Sidebar from './Sidebar'
|
||||
import { themeList } from 'simple-mind-map/src/utils/constant'
|
||||
import { storeConfig } from '@/api'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@@ -43,14 +44,18 @@ export default {
|
||||
theme: ''
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('showTheme', () => {
|
||||
this.$refs.sidebar.show = false
|
||||
this.$nextTick(() => {
|
||||
computed: {
|
||||
...mapState(['activeSidebar'])
|
||||
},
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
if (val === 'theme') {
|
||||
this.theme = this.mindMap.getTheme()
|
||||
this.$refs.sidebar.show = true
|
||||
})
|
||||
})
|
||||
} else {
|
||||
this.$refs.sidebar.show = false
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
@click="$bus.$emit('execCommand', 'BACK')"
|
||||
>
|
||||
<span class="icon iconfont iconhoutui-shi"></span>
|
||||
<span class="text">回退</span>
|
||||
<span class="text">{{ $t('toolbar.undo') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -21,7 +21,7 @@
|
||||
@click="$bus.$emit('execCommand', 'FORWARD')"
|
||||
>
|
||||
<span class="icon iconfont iconqianjin1"></span>
|
||||
<span class="text">前进</span>
|
||||
<span class="text">{{ $t('toolbar.redo') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -31,7 +31,7 @@
|
||||
@click="$bus.$emit('execCommand', 'INSERT_NODE')"
|
||||
>
|
||||
<span class="icon iconfont iconjiedian"></span>
|
||||
<span class="text">插入同级节点</span>
|
||||
<span class="text">{{ $t('toolbar.insertSiblingNode') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -41,7 +41,7 @@
|
||||
@click="$bus.$emit('execCommand', 'INSERT_CHILD_NODE')"
|
||||
>
|
||||
<span class="icon iconfont icontianjiazijiedian"></span>
|
||||
<span class="text">插入子节点</span>
|
||||
<span class="text">{{ $t('toolbar.insertChildNode') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -51,7 +51,7 @@
|
||||
@click="$bus.$emit('execCommand', 'REMOVE_NODE')"
|
||||
>
|
||||
<span class="icon iconfont iconshanchu"></span>
|
||||
<span class="text">删除节点</span>
|
||||
<span class="text">{{ $t('toolbar.deleteNode') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -61,7 +61,7 @@
|
||||
@click="$bus.$emit('showNodeImage')"
|
||||
>
|
||||
<span class="icon iconfont iconimage"></span>
|
||||
<span class="text">图片</span>
|
||||
<span class="text">{{ $t('toolbar.image') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -71,7 +71,7 @@
|
||||
@click="$bus.$emit('showNodeIcon')"
|
||||
>
|
||||
<span class="icon iconfont iconxiaolian"></span>
|
||||
<span class="text">图标</span>
|
||||
<span class="text">{{ $t('toolbar.icon') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -81,7 +81,7 @@
|
||||
@click="$bus.$emit('showNodeLink')"
|
||||
>
|
||||
<span class="icon iconfont iconchaolianjie"></span>
|
||||
<span class="text">超链接</span>
|
||||
<span class="text">{{ $t('toolbar.link') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -91,7 +91,7 @@
|
||||
@click="$bus.$emit('showNodeNote')"
|
||||
>
|
||||
<span class="icon iconfont iconflow-Mark"></span>
|
||||
<span class="text">备注</span>
|
||||
<span class="text">{{ $t('toolbar.note') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -101,7 +101,7 @@
|
||||
@click="$bus.$emit('showNodeTag')"
|
||||
>
|
||||
<span class="icon iconfont iconbiaoqian"></span>
|
||||
<span class="text">标签</span>
|
||||
<span class="text">{{ $t('toolbar.tag') }}</span>
|
||||
</div>
|
||||
<div
|
||||
class="toolbarBtn"
|
||||
@@ -111,53 +111,30 @@
|
||||
@click="$bus.$emit('execCommand', 'ADD_GENERALIZATION')"
|
||||
>
|
||||
<span class="icon iconfont icongaikuozonglan"></span>
|
||||
<span class="text">概要</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 通用操作 -->
|
||||
<div class="toolbarBlock">
|
||||
<div class="toolbarBtn" @click="$bus.$emit('showOutline')">
|
||||
<span class="icon iconfont iconfuhao-dagangshu"></span>
|
||||
<span class="text">显示大纲</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="$bus.$emit('showBaseStyle')">
|
||||
<span class="icon iconfont iconyangshi"></span>
|
||||
<span class="text">基础样式</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="$bus.$emit('showTheme')">
|
||||
<span class="icon iconfont iconjingzi"></span>
|
||||
<span class="text">主题</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="$bus.$emit('showStructure')">
|
||||
<span class="icon iconfont iconjiegou"></span>
|
||||
<span class="text">结构</span>
|
||||
<span class="text">{{ $t('toolbar.summary') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 导出 -->
|
||||
<div class="toolbarBlock">
|
||||
<div class="toolbarBtn" @click="createNewLocalFile">
|
||||
<span class="icon iconfont iconxinjian"></span>
|
||||
<span class="text">新建</span>
|
||||
<span class="text">{{ $t('toolbar.newFile') }}</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="openLocalFile">
|
||||
<span class="icon iconfont icondakai"></span>
|
||||
<span class="text">打开</span>
|
||||
<span class="text">{{ $t('toolbar.openFile') }}</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="saveLocalFile">
|
||||
<span class="icon iconfont iconlingcunwei"></span>
|
||||
<span class="text">另存为</span>
|
||||
<span class="text">{{ $t('toolbar.saveAs') }}</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="$bus.$emit('showImport')">
|
||||
<span class="icon iconfont icondaoru"></span>
|
||||
<span class="text">导入</span>
|
||||
<span class="text">{{ $t('toolbar.import') }}</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="$bus.$emit('showExport')">
|
||||
<span class="icon iconfont iconexport"></span>
|
||||
<span class="text">导出</span>
|
||||
</div>
|
||||
<div class="toolbarBtn" @click="$bus.$emit('showShortcutKey')">
|
||||
<span class="icon iconfont iconjianpan"></span>
|
||||
<span class="text">快捷键</span>
|
||||
<span class="text">{{ $t('toolbar.export') }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -236,24 +213,58 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.$bus.$on('mode_change', mode => {
|
||||
this.$bus.$on('mode_change', this.onModeChange)
|
||||
this.$bus.$on('node_active', this.onNodeActive)
|
||||
this.$bus.$on('back_forward', this.onBackForward)
|
||||
this.$bus.$on('write_local_file', this.onWriteLocalFile)
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$bus.$off('mode_change', this.onModeChange)
|
||||
this.$bus.$off('node_active', this.onNodeActive)
|
||||
this.$bus.$off('back_forward', this.onBackForward)
|
||||
this.$bus.$off('write_local_file', this.onWriteLocalFile)
|
||||
},
|
||||
methods: {
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 19:17:40
|
||||
* @Desc: 监听模式切换
|
||||
*/
|
||||
onModeChange(mode) {
|
||||
this.readonly = mode === 'readonly'
|
||||
})
|
||||
this.$bus.$on('node_active', (...args) => {
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 19:18:06
|
||||
* @Desc: 监听节点激活
|
||||
*/
|
||||
onNodeActive(...args) {
|
||||
this.activeNodes = args[1]
|
||||
})
|
||||
this.$bus.$on('back_forward', (index, len) => {
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 19:18:31
|
||||
* @Desc: 监听前进后退
|
||||
*/
|
||||
onBackForward(index, len) {
|
||||
this.backEnd = index <= 0
|
||||
this.forwardEnd = index >= len - 1
|
||||
})
|
||||
this.$bus.$on('write_local_file', content => {
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 19:19:14
|
||||
* @Desc: 监听本地文件读写
|
||||
*/
|
||||
onWriteLocalFile(content) {
|
||||
clearTimeout(this.timer)
|
||||
this.timer = setTimeout(() => {
|
||||
this.writeLocalFile(content)
|
||||
}, 1000)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
},
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
* @Date: 2022-09-24 15:40:09
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
import Vue from 'vue'
|
||||
import Vuex from 'vuex'
|
||||
import exampleData from 'simple-mind-map/example/exampleData'
|
||||
import { storeLocalConfig } from '@/api'
|
||||
|
||||
Vue.use(Vuex)
|
||||
|
||||
const store = new Vuex.Store({
|
||||
state: {
|
||||
mindMapData: null, // 思维导图数据
|
||||
isHandleLocalFile: false // 是否操作的是本地文件
|
||||
isHandleLocalFile: false, // 是否操作的是本地文件
|
||||
localConfig: {
|
||||
// 本地配置
|
||||
isZenMode: false // 是否是禅模式
|
||||
},
|
||||
activeSidebar: '' // 当前显示的侧边栏
|
||||
},
|
||||
mutations: {
|
||||
/**
|
||||
@@ -27,6 +33,30 @@ const store = new Vuex.Store({
|
||||
*/
|
||||
setIsHandleLocalFile(state, data) {
|
||||
state.isHandleLocalFile = data
|
||||
},
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-14 18:42:47
|
||||
* @Desc: 设置本地配置
|
||||
*/
|
||||
setLocalConfig(state, data) {
|
||||
state.localConfig = {
|
||||
...state.localConfig,
|
||||
...data
|
||||
}
|
||||
storeLocalConfig(state.localConfig)
|
||||
},
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-11-15 19:25:26
|
||||
* @Desc: 设置当前显示的侧边栏
|
||||
*/
|
||||
setActiveSidebar(state, data) {
|
||||
state.activeSidebar = data
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
|
||||
@@ -32,11 +32,11 @@ export const fullScreen = element => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-10-24 14:16:18
|
||||
* @Desc: 文件转buffer
|
||||
/**
|
||||
* javascript comment
|
||||
* @Author: 王林25
|
||||
* @Date: 2022-10-24 14:16:18
|
||||
* @Desc: 文件转buffer
|
||||
*/
|
||||
export const fileToBuffer = file => {
|
||||
return new Promise(r => {
|
||||
|
||||
Reference in New Issue
Block a user