mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-17 22:08:25 +08:00
Demo:优化界面暗黑效果
This commit is contained in:
@@ -123,7 +123,7 @@ const transformOldXmind = content => {
|
||||
let elements = data.elements
|
||||
let root = null
|
||||
let getRoot = arr => {
|
||||
if(!arr) return;
|
||||
if (!arr) return
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (!root && arr[i].name === 'topic') {
|
||||
root = arr[i]
|
||||
@@ -143,7 +143,7 @@ const transformOldXmind = content => {
|
||||
}
|
||||
let walk = (node, newNode) => {
|
||||
let nodeElements = node.elements
|
||||
let nodeTitle = getItemByName(nodeElements, 'title');
|
||||
let nodeTitle = getItemByName(nodeElements, 'title')
|
||||
newNode.data = {
|
||||
// 节点内容
|
||||
text: nodeTitle && nodeTitle.elements && nodeTitle.elements[0].text
|
||||
|
||||
@@ -12,8 +12,10 @@ class ExportXMind {
|
||||
const zipData = await xmind.transformToXmind(data, name)
|
||||
return zipData
|
||||
}
|
||||
getXmind(){
|
||||
return xmind;
|
||||
|
||||
// 获取解析器
|
||||
getXmind() {
|
||||
return xmind
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class NodeImgAdjust {
|
||||
this.createResizeBtnEl()
|
||||
}
|
||||
this.setHandleElRect()
|
||||
this.handleEl.style.display = 'block';// document.body.appendChild(this.handleEl)
|
||||
this.handleEl.style.display = 'block'
|
||||
this.isShowHandleEl = true
|
||||
}
|
||||
|
||||
@@ -90,12 +90,12 @@ class NodeImgAdjust {
|
||||
hideHandleEl() {
|
||||
if (!this.isShowHandleEl) return
|
||||
this.isShowHandleEl = false
|
||||
this.handleEl.style.display = 'none';//document.body.removeChild(this.handleEl)
|
||||
this.handleEl.style.display = 'none'
|
||||
this.handleEl.style.backgroundImage = ``
|
||||
this.handleEl.style.width = 0
|
||||
this.handleEl.style.height = 0
|
||||
this.handleEl.style.left = 0
|
||||
this.handleEl.style.top = 0
|
||||
this.handleEl.style.top = 0
|
||||
}
|
||||
|
||||
// 设置自定义元素尺寸位置信息
|
||||
@@ -121,9 +121,10 @@ class NodeImgAdjust {
|
||||
this.handleEl.style.cssText = `
|
||||
pointer-events: none;
|
||||
position: fixed;
|
||||
display:none;
|
||||
display:none;
|
||||
background-size: cover;
|
||||
`
|
||||
this.handleEl.className = 'node-img-handle'
|
||||
// 调整按钮元素
|
||||
const btnEl = document.createElement('div')
|
||||
btnEl.innerHTML = btnsSvg.imgAdjust
|
||||
@@ -140,7 +141,7 @@ class NodeImgAdjust {
|
||||
align-items: center;
|
||||
cursor: nwse-resize;
|
||||
`
|
||||
this.handleEl.appendChild(btnEl)
|
||||
btnEl.className = 'node-image-resize'
|
||||
// 给按钮元素绑定事件
|
||||
btnEl.addEventListener('mouseenter', () => {
|
||||
// 移入按钮,会触发节点图片的移出事件,所以需要再次显示按钮
|
||||
@@ -152,51 +153,50 @@ class NodeImgAdjust {
|
||||
this.hideHandleEl()
|
||||
})
|
||||
btnEl.addEventListener('mousedown', e => {
|
||||
e.stopPropagation()
|
||||
this.onMousedown(e)
|
||||
})
|
||||
btnEl.addEventListener('mouseup', e => {
|
||||
setTimeout(() => { //点击后直接松开异常处理; 其他事件响应之后处理
|
||||
this.hideHandleEl()
|
||||
this.isAdjusted = false;
|
||||
},0);
|
||||
})
|
||||
|
||||
|
||||
document.body.appendChild(this.handleEl);
|
||||
this.handleEl.className = 'node-img-handle';
|
||||
btnEl.className = 'node-image-resize';
|
||||
|
||||
const btnRemove = document.createElement('div');
|
||||
this.handleEl.prepend(btnRemove);
|
||||
btnRemove.className = 'node-image-remove';
|
||||
btnRemove.innerHTML = btnsSvg.remove;//'<span class="image-remove el-icon-close"></span>';
|
||||
btnRemove.style.cssText = `
|
||||
position: absolute;
|
||||
right: 0;top:0;color:#fff;
|
||||
pointer-events: auto;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
width: ${this.resizeBtnSize}px;
|
||||
height: ${this.resizeBtnSize}px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;`;
|
||||
btnRemove.addEventListener('mouseenter', e => {
|
||||
this.showHandleEl()
|
||||
})
|
||||
btnRemove.addEventListener('mouseleave', e => {
|
||||
if (this.isMousedown) return
|
||||
this.hideHandleEl()
|
||||
})
|
||||
btnRemove.addEventListener('click', e => {
|
||||
this.mindMap.execCommand('SET_NODE_IMAGE',this.node,{url:null});
|
||||
});
|
||||
btnEl.addEventListener('mouseup', e => {
|
||||
setTimeout(() => {
|
||||
//点击后直接松开异常处理; 其他事件响应之后处理
|
||||
this.hideHandleEl()
|
||||
this.isAdjusted = false
|
||||
}, 0)
|
||||
})
|
||||
btnEl.addEventListener('click', e => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
btnEl.addEventListener('mousedown', (e) => {
|
||||
e.stopPropagation()
|
||||
this.handleEl.appendChild(btnEl)
|
||||
// 删除按钮
|
||||
const btnRemove = document.createElement('div')
|
||||
this.handleEl.prepend(btnRemove)
|
||||
btnRemove.className = 'node-image-remove'
|
||||
btnRemove.innerHTML = btnsSvg.remove
|
||||
btnRemove.style.cssText = `
|
||||
position: absolute;
|
||||
right: 0;top:0;color:#fff;
|
||||
pointer-events: auto;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
width: ${this.resizeBtnSize}px;
|
||||
height: ${this.resizeBtnSize}px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
`
|
||||
btnRemove.addEventListener('mouseenter', e => {
|
||||
this.showHandleEl()
|
||||
})
|
||||
btnRemove.addEventListener('mouseleave', e => {
|
||||
if (this.isMousedown) return
|
||||
this.hideHandleEl()
|
||||
})
|
||||
btnRemove.addEventListener('click', e => {
|
||||
this.mindMap.execCommand('SET_NODE_IMAGE', this.node, { url: null })
|
||||
})
|
||||
// 添加元素到页面
|
||||
const targetNode = this.mindMap.opt.customInnerElsAppendTo || document.body
|
||||
targetNode.appendChild(this.handleEl)
|
||||
}
|
||||
|
||||
// 鼠标按钮按下事件
|
||||
|
||||
@@ -163,12 +163,12 @@ class RichText {
|
||||
let scaleX = rect.width / originWidth
|
||||
let scaleY = rect.height / originHeight
|
||||
// 内边距
|
||||
const paddingX = 14;// 6=>14
|
||||
const paddingX = 6
|
||||
const paddingY = 4
|
||||
if (!this.textEditNode) {
|
||||
this.textEditNode = document.createElement('div')
|
||||
this.textEditNode.classList.add('smm-richtext-node-edit-wrap')
|
||||
this.textEditNode.style.cssText = `position:fixed;box-sizing: border-box;outline: none; word-break: break-all;padding: ${paddingY}px ${paddingX}px;`
|
||||
this.textEditNode.style.cssText = `position:fixed;box-sizing: border-box;box-shadow: 0 0 20px rgba(0,0,0,.5);outline: none; word-break: break-all;padding: ${paddingY}px ${paddingX}px;`
|
||||
this.textEditNode.addEventListener('click', e => {
|
||||
e.stopPropagation()
|
||||
})
|
||||
@@ -194,12 +194,7 @@ class RichText {
|
||||
this.textEditNode.style.maxWidth =
|
||||
this.mindMap.opt.textAutoWrapWidth + paddingX * 2 + 'px'
|
||||
this.textEditNode.style.transform = `scale(${scaleX}, ${scaleY})`
|
||||
this.textEditNode.style.transformOrigin = 'left top'
|
||||
this.textEditNode.style.borderRadius = (node.style.merge('borderRadius') || 5) + 'px'
|
||||
if(node.style.merge('shape') == 'roundedRectangle'){
|
||||
this.textEditNode.style.borderRadius = '50px';
|
||||
}
|
||||
|
||||
this.textEditNode.style.transformOrigin = 'left top'
|
||||
if (!node.nodeData.data.richText) {
|
||||
// 还不是富文本的情况
|
||||
let text = node.nodeData.data.text.split(/\n/gim).join('<br>')
|
||||
@@ -210,7 +205,6 @@ class RichText {
|
||||
this.cacheEditingText || node.nodeData.data.text
|
||||
}
|
||||
this.initQuillEditor()
|
||||
setTimeout(() => {this.selectAll();}, 0); // 双击选中
|
||||
document.querySelector('.ql-editor').style.minHeight = originHeight + 'px'
|
||||
this.showTextEdit = true
|
||||
// 如果是刚创建的节点,那么默认全选,否则普通激活不全选
|
||||
|
||||
@@ -47,7 +47,10 @@ export default {
|
||||
mousewheelZoomActionReverse: 'Mouse Wheel Zoom',
|
||||
mousewheelZoomActionReverse1: 'Zoom out forward and zoom in back',
|
||||
mousewheelZoomActionReverse2: 'Zoom in forward and zoom out back',
|
||||
rootStyle: 'Root Node'
|
||||
rootStyle: 'Root Node',
|
||||
associativeLineText: 'Associative line text',
|
||||
fontFamily: 'Font family',
|
||||
fontSize: 'Font size'
|
||||
},
|
||||
color: {
|
||||
moreColor: 'More color'
|
||||
|
||||
@@ -47,7 +47,10 @@ export default {
|
||||
mousewheelZoomActionReverse: '鼠标滚轮缩放',
|
||||
mousewheelZoomActionReverse1: '向前缩小向后放大',
|
||||
mousewheelZoomActionReverse2: '向前放大向后缩小',
|
||||
rootStyle: '根节点'
|
||||
rootStyle: '根节点',
|
||||
associativeLineText: '关联线文字',
|
||||
fontFamily: '字体',
|
||||
fontSize: '字号'
|
||||
},
|
||||
color: {
|
||||
moreColor: '更多颜色'
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div class="container" :class="{ isDark: isDark,activeSidebar:activeSidebar}">
|
||||
<div
|
||||
class="container"
|
||||
:class="{ isDark: isDark, activeSidebar: activeSidebar }"
|
||||
>
|
||||
<template v-if="show">
|
||||
<Toolbar v-if="!isZenMode"></Toolbar>
|
||||
<Edit></Edit>
|
||||
@@ -28,7 +31,7 @@ export default {
|
||||
...mapState({
|
||||
isZenMode: state => state.localConfig.isZenMode,
|
||||
isDark: state => state.isDark,
|
||||
activeSidebar: state => state.activeSidebar
|
||||
activeSidebar: state => state.activeSidebar
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
@@ -76,14 +79,15 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.container {}
|
||||
.container {
|
||||
}
|
||||
|
||||
body {
|
||||
&.isDark {
|
||||
/* el-button */
|
||||
.el-button {
|
||||
background-color: #363b3f;
|
||||
color: hsla(0,0%,100%,.9);
|
||||
color: hsla(0, 0%, 100%, 0.9);
|
||||
border-color: hsla(0, 0%, 100%, 0.1);
|
||||
}
|
||||
|
||||
@@ -97,10 +101,11 @@ body {
|
||||
.el-input.is-disabled .el-input__inner {
|
||||
background-color: #363b3f;
|
||||
border-color: hsla(0, 0%, 100%, 0.1);
|
||||
color: hsla(0,0%,100%,.3);
|
||||
color: hsla(0, 0%, 100%, 0.3);
|
||||
}
|
||||
|
||||
.el-input-group__append, .el-input-group__prepend {
|
||||
.el-input-group__append,
|
||||
.el-input-group__prepend {
|
||||
background-color: #363b3f;
|
||||
border-color: hsla(0, 0%, 100%, 0.1);
|
||||
}
|
||||
@@ -146,11 +151,11 @@ body {
|
||||
border-bottom-color: #36393d;
|
||||
}
|
||||
|
||||
.el-popper[x-placement^=top] .popper__arrow {
|
||||
.el-popper[x-placement^='top'] .popper__arrow {
|
||||
background-color: #36393d;
|
||||
}
|
||||
|
||||
.el-popper[x-placement^=top] .popper__arrow::after {
|
||||
.el-popper[x-placement^='top'] .popper__arrow::after {
|
||||
border-top-color: #36393d;
|
||||
}
|
||||
|
||||
@@ -160,7 +165,7 @@ body {
|
||||
|
||||
&:hover,
|
||||
&.is-active {
|
||||
color: #409EFF;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,9 +185,9 @@ body {
|
||||
color: hsla(0, 0%, 100%, 0.6);
|
||||
}
|
||||
|
||||
.el-radio-button__orig-radio:checked+.el-radio-button__inner {
|
||||
color: #FFF;
|
||||
background-color: #409EFF;
|
||||
.el-radio-button__orig-radio:checked + .el-radio-button__inner {
|
||||
color: #fff;
|
||||
background-color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,11 +196,11 @@ body {
|
||||
background-color: #262a2e;
|
||||
|
||||
.el-dialog__header {
|
||||
border-bottom: 1px solid hsla(0,0%,100%,.1);
|
||||
border-bottom: 1px solid hsla(0, 0%, 100%, 0.1);
|
||||
}
|
||||
|
||||
.el-dialog__title {
|
||||
color: hsla(0,0%,100%,.9);
|
||||
color: hsla(0, 0%, 100%, 0.9);
|
||||
}
|
||||
|
||||
.el-dialog__body {
|
||||
@@ -203,7 +208,7 @@ body {
|
||||
}
|
||||
|
||||
.el-dialog__footer {
|
||||
border-top: 1px solid hsla(0,0%,100%,.1);
|
||||
border-top: 1px solid hsla(0, 0%, 100%, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -318,10 +318,10 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 关联线文字 -->
|
||||
<div class="title noTop">关联线文字</div>
|
||||
<div class="title noTop">{{ $t('baseStyle.associativeLineText') }}</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">字体</span>
|
||||
<span class="name">{{ $t('baseStyle.fontFamily') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
v-model="style.associativeLineTextFontFamily"
|
||||
@@ -341,7 +341,7 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="rowItem">
|
||||
<span class="name">颜色</span>
|
||||
<span class="name">{{ $t('baseStyle.color') }}</span>
|
||||
<span
|
||||
class="block"
|
||||
v-popover:popover6
|
||||
@@ -359,7 +359,7 @@
|
||||
</el-popover>
|
||||
</div>
|
||||
<div class="rowItem">
|
||||
<span class="name">字号</span>
|
||||
<span class="name">{{ $t('baseStyle.fontSize') }}</span>
|
||||
<el-select
|
||||
size="mini"
|
||||
style="width: 80px"
|
||||
|
||||
@@ -321,6 +321,32 @@ export default {
|
||||
.outlineTree {
|
||||
&.isDark {
|
||||
background-color: #262a2e;
|
||||
|
||||
.customNode {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
&.el-tree--highlight-current {
|
||||
/deep/ .el-tree-node.is-current > .el-tree-node__content {
|
||||
background-color: hsla(0, 0%, 100%, 0.05) !important;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node__content:hover, .el-upload-list__item:hover {
|
||||
background-color: hsla(0, 0%, 100%, 0.02) !important;
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node__content {
|
||||
.el-tree-node__expand-icon {
|
||||
color: #fff;
|
||||
|
||||
&.is-leaf {
|
||||
&::after {
|
||||
background-color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .el-tree-node > .el-tree-node__children {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div
|
||||
class="outlineEditContainer"
|
||||
:class="{ isDark: isDark }"
|
||||
ref="outlineEditContainer"
|
||||
v-if="isOutlineEdit"
|
||||
>
|
||||
@@ -31,7 +32,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['isOutlineEdit'])
|
||||
...mapState(['isOutlineEdit', 'isDark'])
|
||||
},
|
||||
watch: {
|
||||
isOutlineEdit(val) {
|
||||
@@ -73,6 +74,16 @@ export default {
|
||||
background-color: #fff;
|
||||
overflow: hidden;
|
||||
|
||||
&.isDark {
|
||||
background-color: #262a2e;
|
||||
|
||||
.closeBtn {
|
||||
.icon {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.closeBtn {
|
||||
position: absolute;
|
||||
right: 40px;
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<template>
|
||||
<Sidebar ref="sidebar" :title="$t('outline.title')">
|
||||
<div class="changeBtn" @click="onChangeToOutlineEdit">
|
||||
<div
|
||||
class="changeBtn"
|
||||
:class="{ isDark: isDark }"
|
||||
@click="onChangeToOutlineEdit"
|
||||
>
|
||||
<span class="icon iconfont iconquanping1"></span>
|
||||
</div>
|
||||
<Outline
|
||||
@@ -29,7 +33,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['activeSidebar', 'isOutlineEdit'])
|
||||
...mapState(['activeSidebar', 'isOutlineEdit', 'isDark'])
|
||||
},
|
||||
watch: {
|
||||
activeSidebar(val) {
|
||||
@@ -66,5 +70,9 @@ export default {
|
||||
right: 50px;
|
||||
top: 12px;
|
||||
cursor: pointer;
|
||||
|
||||
&.isDark {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
<Sidebar ref="sidebar" :title="$t('theme.title')">
|
||||
<div class="themeList" :class="{ isDark: isDark }">
|
||||
<el-tabs v-model="activeName">
|
||||
<el-tab-pane v-for="group in groupList" :key="group.name" :label="group.name" :name="group.name"></el-tab-pane>
|
||||
<el-tab-pane
|
||||
v-for="group in groupList"
|
||||
:key="group.name"
|
||||
:label="group.name"
|
||||
:name="group.name"
|
||||
></el-tab-pane>
|
||||
</el-tabs>
|
||||
<div
|
||||
class="themeItem"
|
||||
@@ -56,7 +61,7 @@ export default {
|
||||
...mapState(['activeSidebar', 'isDark']),
|
||||
|
||||
currentList() {
|
||||
return this.groupList.find((item) => {
|
||||
return this.groupList.find(item => {
|
||||
return item.name === this.activeName
|
||||
}).list
|
||||
}
|
||||
@@ -76,21 +81,35 @@ export default {
|
||||
this.initGroup()
|
||||
this.theme = this.mindMap.getTheme()
|
||||
this.handleDark()
|
||||
|
||||
var self = this;
|
||||
this.mindMap.on('view_theme_change',function(){
|
||||
self.theme = self.mindMap.getTheme()
|
||||
self.handleDark()
|
||||
});
|
||||
|
||||
this.mindMap.on('view_theme_change', () => {
|
||||
this.theme = this.mindMap.getTheme()
|
||||
this.handleDark()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['setIsDark']),
|
||||
|
||||
initGroup() {
|
||||
let baiduThemes = ['default', 'skyGreen', 'classic2', 'classic3', 'classicGreen', 'classicBlue', 'blueSky', 'brainImpairedPink', 'earthYellow', 'freshGreen', 'freshRed', 'romanticPurple', 'pinkGrape', 'mint']
|
||||
let baiduThemes = [
|
||||
'default',
|
||||
'skyGreen',
|
||||
'classic2',
|
||||
'classic3',
|
||||
'classicGreen',
|
||||
'classicBlue',
|
||||
'blueSky',
|
||||
'brainImpairedPink',
|
||||
'earthYellow',
|
||||
'freshGreen',
|
||||
'freshRed',
|
||||
'romanticPurple',
|
||||
'pinkGrape',
|
||||
'mint'
|
||||
]
|
||||
let baiduList = []
|
||||
let classicsList = []
|
||||
this.themeList.forEach((item) => {
|
||||
this.themeList.forEach(item => {
|
||||
if (baiduThemes.includes(item.value)) {
|
||||
baiduList.push(item)
|
||||
} else if (!item.dark) {
|
||||
@@ -104,7 +123,7 @@ export default {
|
||||
},
|
||||
{
|
||||
name: '深色',
|
||||
list: this.themeList.filter((item) => {
|
||||
list: this.themeList.filter(item => {
|
||||
return item.dark
|
||||
})
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user