Demo:优化界面暗黑效果

This commit is contained in:
wanglin2
2023-08-07 17:05:47 +08:00
parent 9427ee550c
commit 4b59bec01c
12 changed files with 163 additions and 92 deletions

View File

@@ -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

View File

@@ -12,8 +12,10 @@ class ExportXMind {
const zipData = await xmind.transformToXmind(data, name)
return zipData
}
getXmind(){
return xmind;
// 获取解析器
getXmind() {
return xmind
}
}

View File

@@ -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)
}
// 鼠标按钮按下事件

View File

@@ -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
// 如果是刚创建的节点,那么默认全选,否则普通激活不全选

View File

@@ -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'

View File

@@ -47,7 +47,10 @@ export default {
mousewheelZoomActionReverse: '鼠标滚轮缩放',
mousewheelZoomActionReverse1: '向前缩小向后放大',
mousewheelZoomActionReverse2: '向前放大向后缩小',
rootStyle: '根节点'
rootStyle: '根节点',
associativeLineText: '关联线文字',
fontFamily: '字体',
fontSize: '字号'
},
color: {
moreColor: '更多颜色'

View File

@@ -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);
}
}

View File

@@ -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"

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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>

View File

@@ -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
})
},