更新客户端
41
README.md
@ -86,7 +86,7 @@ const mindMap = new MindMap({
|
||||
|
||||
# License
|
||||
|
||||
MIT
|
||||
[MIT](./LICENSE)
|
||||
|
||||
# 微信交流群
|
||||
|
||||
@ -96,11 +96,48 @@ MIT
|
||||
|
||||
# 请作者喝杯咖啡
|
||||
|
||||
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡哟~
|
||||
|
||||
> 厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds
|
||||
|
||||
> 转账请备注哦~你的头像和名称会出现在[文档页面](https://wanglin2.github.io/mind-map/#/doc/zh/introduction/%E8%AF%B7%E4%BD%9C%E8%80%85%E5%96%9D%E6%9D%AF%E5%92%96%E5%95%A1)
|
||||
> 转账请备注【思维导图】。你的头像和名字将会出现在下面和[文档页面](https://wanglin2.github.io/mind-map/#/doc/zh/introduction/%E8%AF%B7%E4%BD%9C%E8%80%85%E5%96%9D%E6%9D%AF%E5%92%96%E5%95%A1)
|
||||
|
||||
<p>
|
||||
<img src="./web/src/assets/img/alipay.jpg" style="width: 300px" />
|
||||
<img src="./web/src/assets/img/wechat.jpg" style="width: 300px" />
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/Think.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>Think</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/志斌.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>志斌</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/小土渣的宇宙.jpeg" style="width: 50px;height: 50px;" />
|
||||
<span>小土渣的宇宙</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/qp.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>qp</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>ZXR</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>花儿朵朵</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/suka.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>suka</span>
|
||||
</span>
|
||||
<span>
|
||||
<img src="./web/src/assets/avatar/Chris.jpg" style="width: 50px;height: 50px;" />
|
||||
<span>Chris</span>
|
||||
</span>
|
||||
</p>
|
||||
BIN
qrcode.jpg
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 184 KiB |
@ -32,9 +32,6 @@ class MindMap {
|
||||
this.svg = SVG().addTo(this.el).size(this.width, this.height)
|
||||
this.draw = this.svg.group()
|
||||
|
||||
// 节点id
|
||||
this.uid = 1
|
||||
|
||||
// 初始化主题
|
||||
this.initTheme()
|
||||
|
||||
@ -238,7 +235,7 @@ class MindMap {
|
||||
|
||||
// 获取思维导图数据,节点树、主题、布局等
|
||||
getData(withConfig) {
|
||||
let nodeData = this.command.removeDataUid(this.command.getCopyData())
|
||||
let nodeData = this.command.getCopyData()
|
||||
let data = {}
|
||||
if (withConfig) {
|
||||
data = {
|
||||
|
||||
4
simple-mind-map/package-lock.json
generated
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.7",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "0.6.0",
|
||||
"version": "0.6.7",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@svgdotjs/svg.js": "^3.0.16",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "simple-mind-map",
|
||||
"version": "0.6.6",
|
||||
"version": "0.6.7",
|
||||
"description": "一个简单的web在线思维导图",
|
||||
"authors": [
|
||||
{
|
||||
|
||||
@ -79,10 +79,6 @@ export const defaultOpt = {
|
||||
},
|
||||
// 是否只有当鼠标在画布内才响应快捷键事件
|
||||
enableShortcutOnlyWhenMouseInSvg: true,
|
||||
// 是否开启节点动画过渡
|
||||
enableNodeTransitionMove: true,
|
||||
// 如果开启节点动画过渡,可以通过该属性设置过渡的时间,单位ms
|
||||
nodeTransitionMoveDuration: 300,
|
||||
// 初始根节点的位置
|
||||
initRootNodePosition: null,
|
||||
// 导出png、svg、pdf时的图形内边距
|
||||
|
||||
@ -89,7 +89,7 @@ class Command {
|
||||
this.history.shift()
|
||||
}
|
||||
this.activeHistoryIndex = this.history.length - 1
|
||||
this.mindMap.emit('data_change', this.removeDataUid(data))
|
||||
this.mindMap.emit('data_change', data)
|
||||
this.mindMap.emit(
|
||||
'back_forward',
|
||||
this.activeHistoryIndex,
|
||||
@ -110,7 +110,7 @@ class Command {
|
||||
this.history.length
|
||||
)
|
||||
let data = simpleDeepClone(this.history[this.activeHistoryIndex])
|
||||
this.mindMap.emit('data_change', this.removeDataUid(data))
|
||||
this.mindMap.emit('data_change', data)
|
||||
return data
|
||||
}
|
||||
}
|
||||
@ -125,7 +125,7 @@ class Command {
|
||||
this.activeHistoryIndex += step
|
||||
this.mindMap.emit('back_forward', this.activeHistoryIndex, this.history.length)
|
||||
let data = simpleDeepClone(this.history[this.activeHistoryIndex])
|
||||
this.mindMap.emit('data_change', this.removeDataUid(data))
|
||||
this.mindMap.emit('data_change', data)
|
||||
return data
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ import Timeline from '../../layouts/Timeline'
|
||||
import VerticalTimeline from '../../layouts/VerticalTimeline'
|
||||
import Fishbone from '../../layouts/Fishbone'
|
||||
import TextEdit from './TextEdit'
|
||||
import { copyNodeTree, simpleDeepClone, walk } from '../../utils'
|
||||
import { copyNodeTree, simpleDeepClone, walk, bfsWalk } from '../../utils'
|
||||
import { shapeList } from './node/Shape'
|
||||
import { lineStyleProps } from '../../themes/default'
|
||||
import { CONSTANTS } from '../../constants/constant'
|
||||
@ -195,6 +195,9 @@ class Render {
|
||||
// 设置节点形状
|
||||
this.setNodeShape = this.setNodeShape.bind(this)
|
||||
this.mindMap.command.add('SET_NODE_SHAPE', this.setNodeShape)
|
||||
// 定位节点
|
||||
this.goTargetNode = this.goTargetNode.bind(this)
|
||||
this.mindMap.command.add('GO_TARGET_NODE', this.goTargetNode)
|
||||
}
|
||||
|
||||
// 注册快捷键
|
||||
@ -259,7 +262,6 @@ class Render {
|
||||
|
||||
// 渲染
|
||||
render(callback = () => {}, source) {
|
||||
let t = Date.now()
|
||||
// 如果当前还没有渲染完毕,不再触发渲染
|
||||
if (this.isRendering) {
|
||||
// 等待当前渲染完毕后再进行一次渲染
|
||||
@ -290,7 +292,7 @@ class Render {
|
||||
// 更新根节点
|
||||
this.root = root
|
||||
// 渲染节点
|
||||
const onEnd = () => {
|
||||
this.root.render(() => {
|
||||
this.isRendering = false
|
||||
this.mindMap.emit('node_tree_render_end')
|
||||
callback && callback()
|
||||
@ -303,18 +305,6 @@ class Render {
|
||||
this.mindMap.command.addHistory()
|
||||
}
|
||||
}
|
||||
}
|
||||
let { enableNodeTransitionMove, nodeTransitionMoveDuration } =
|
||||
this.mindMap.opt
|
||||
this.root.render(() => {
|
||||
let dur = Date.now() - t
|
||||
if (enableNodeTransitionMove && dur <= nodeTransitionMoveDuration) {
|
||||
setTimeout(() => {
|
||||
onEnd()
|
||||
}, nodeTransitionMoveDuration - dur);
|
||||
} else {
|
||||
onEnd()
|
||||
}
|
||||
})
|
||||
})
|
||||
this.mindMap.emit('node_active', null, this.activeNodeList)
|
||||
@ -439,11 +429,14 @@ class Render {
|
||||
first.parent.destroy()
|
||||
}
|
||||
let index = this.getNodeIndex(first)
|
||||
let isRichText = !!this.mindMap.richText
|
||||
first.parent.nodeData.children.splice(index + 1, 0, {
|
||||
inserting: openEdit,
|
||||
data: {
|
||||
text: text,
|
||||
expand: true,
|
||||
richText: isRichText,
|
||||
resetRichText: isRichText,
|
||||
...(appointData || {})
|
||||
},
|
||||
children: []
|
||||
@ -468,11 +461,14 @@ class Render {
|
||||
node.nodeData.children = []
|
||||
}
|
||||
let text = node.isRoot ? defaultInsertSecondLevelNodeText : defaultInsertBelowSecondLevelNodeText
|
||||
let isRichText = !!this.mindMap.richText
|
||||
node.nodeData.children.push({
|
||||
inserting: openEdit,
|
||||
data: {
|
||||
text: text,
|
||||
expand: true,
|
||||
richText: isRichText,
|
||||
resetRichText: isRichText,
|
||||
...(appointData || {})
|
||||
},
|
||||
children: []
|
||||
@ -992,6 +988,19 @@ class Render {
|
||||
})
|
||||
}
|
||||
|
||||
// 定位到指定节点
|
||||
goTargetNode(node) {
|
||||
let uid = typeof node === 'string' ? node : node.nodeData.data.uid
|
||||
if (!uid) return
|
||||
this.expandToNodeUid(uid, () => {
|
||||
let targetNode = this.findNodeByUid(uid)
|
||||
if (targetNode) {
|
||||
targetNode.active()
|
||||
this.moveNodeToCenter(targetNode)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 更新节点数据
|
||||
setNodeData(node, data) {
|
||||
Object.keys(data).forEach(key => {
|
||||
@ -1028,6 +1037,44 @@ class Render {
|
||||
this.mindMap.view.translateY(offsetY)
|
||||
this.mindMap.view.setScale(1)
|
||||
}
|
||||
|
||||
// 展开到指定uid的节点
|
||||
expandToNodeUid(uid, callback = () => {}) {
|
||||
let parentsList = []
|
||||
const cache = {}
|
||||
bfsWalk(this.renderTree, (node, parent) => {
|
||||
if (node.data.uid === uid) {
|
||||
parentsList = parent ? [...cache[parent.data.uid], parent] : []
|
||||
return 'stop'
|
||||
} else {
|
||||
cache[node.data.uid] = parent ? [...cache[parent.data.uid], parent]: []
|
||||
}
|
||||
})
|
||||
let needRender = false
|
||||
parentsList.forEach((node) => {
|
||||
if (!node.data.expand) {
|
||||
needRender = true
|
||||
node.data.expand = true
|
||||
}
|
||||
})
|
||||
if (needRender) {
|
||||
this.mindMap.render(callback)
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// 根据uid找到对应的节点实例
|
||||
findNodeByUid(uid) {
|
||||
let res = null
|
||||
walk(this.root, null, (node) => {
|
||||
if (node.nodeData.data.uid === uid) {
|
||||
res = node
|
||||
return true
|
||||
}
|
||||
})
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
export default Render
|
||||
|
||||
@ -365,8 +365,8 @@ class Node {
|
||||
this._unVisibleRectRegionNode.fill({
|
||||
color: 'transparent'
|
||||
})
|
||||
this.group.add(this._unVisibleRectRegionNode)
|
||||
}
|
||||
this.group.add(this._unVisibleRectRegionNode)
|
||||
this.renderer.layout.renderExpandBtnRect(this._unVisibleRectRegionNode, this.expandBtnSize, width, height, this)
|
||||
}
|
||||
}
|
||||
@ -476,8 +476,6 @@ class Node {
|
||||
return
|
||||
}
|
||||
let {
|
||||
enableNodeTransitionMove,
|
||||
nodeTransitionMoveDuration,
|
||||
alwaysShowExpandBtn
|
||||
} = this.mindMap.opt
|
||||
if (alwaysShowExpandBtn) {
|
||||
@ -503,13 +501,7 @@ class Node {
|
||||
let t = this.group.transform()
|
||||
// 如果节点位置没有变化,则返回
|
||||
if (this.left === t.translateX && this.top === t.translateY) return
|
||||
if (!isLayout && enableNodeTransitionMove) {
|
||||
this.group
|
||||
.animate(nodeTransitionMoveDuration)
|
||||
.translate(this.left - t.translateX, this.top - t.translateY)
|
||||
} else {
|
||||
this.group.translate(this.left - t.translateX, this.top - t.translateY)
|
||||
}
|
||||
this.group.translate(this.left - t.translateX, this.top - t.translateY)
|
||||
}
|
||||
|
||||
// 重新渲染节点,即重新创建节点内容、计算节点大小、计算节点内容布局、更新展开收起按钮,概要及位置
|
||||
@ -531,8 +523,6 @@ class Node {
|
||||
|
||||
// 递归渲染
|
||||
render(callback = () => {}) {
|
||||
let { enableNodeTransitionMove, nodeTransitionMoveDuration } =
|
||||
this.mindMap.opt
|
||||
// 节点
|
||||
// 重新渲染连线
|
||||
this.renderLine()
|
||||
@ -580,13 +570,7 @@ class Node {
|
||||
})
|
||||
)
|
||||
} else {
|
||||
if (enableNodeTransitionMove && !isLayout) {
|
||||
setTimeout(() => {
|
||||
callback()
|
||||
}, nodeTransitionMoveDuration)
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
callback()
|
||||
}
|
||||
// 手动插入的节点立即获得焦点并且开启编辑模式
|
||||
if (this.nodeData.inserting) {
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import Node from './Node'
|
||||
import { createUid } from '../../../utils/index'
|
||||
|
||||
// 检查是否存在概要
|
||||
function checkHasGeneralization () {
|
||||
@ -18,7 +19,7 @@ function createGeneralizationNode () {
|
||||
data: {
|
||||
data: this.nodeData.data.generalization
|
||||
},
|
||||
uid: this.mindMap.uid++,
|
||||
uid: createUid(),
|
||||
renderer: this.renderer,
|
||||
mindMap: this.mindMap,
|
||||
draw: this.draw,
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import Node from '../core/render/node/Node'
|
||||
import { CONSTANTS, initRootNodePositionMap } from '../constants/constant'
|
||||
import Lru from '../utils/Lru'
|
||||
import { createUid } from '../utils/index'
|
||||
|
||||
// 布局基类
|
||||
class Base {
|
||||
@ -101,7 +102,7 @@ class Base {
|
||||
}
|
||||
} else {
|
||||
// 创建新节点
|
||||
let uid = this.mindMap.uid++
|
||||
let uid = data.data.uid || createUid()
|
||||
newNode = new Node({
|
||||
data,
|
||||
uid,
|
||||
|
||||
@ -28,8 +28,7 @@ class KeyboardNavigation {
|
||||
this.focus(dir)
|
||||
} else {
|
||||
let root = this.mindMap.renderer.root
|
||||
this.mindMap.renderer.moveNodeToCenter(root)
|
||||
root.active()
|
||||
this.mindMap.execCommand('GO_TARGET_NODE', root)
|
||||
}
|
||||
}
|
||||
|
||||
@ -81,8 +80,7 @@ class KeyboardNavigation {
|
||||
|
||||
// 找到了则让目标节点聚焦
|
||||
if (targetNode) {
|
||||
this.mindMap.renderer.moveNodeToCenter(targetNode)
|
||||
targetNode.active()
|
||||
this.mindMap.execCommand('GO_TARGET_NODE', targetNode)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -47,7 +47,7 @@ class NodeImgAdjust {
|
||||
// 节点图片鼠标移动事件
|
||||
onNodeImgMousemove(node, img) {
|
||||
// 如果当前正在拖动调整中那么直接返回
|
||||
if (this.isMousedown || this.isAdjusted) return
|
||||
if (this.isMousedown || this.isAdjusted || this.mindMap.opt.readonly) return
|
||||
// 如果在当前节点内移动,以及自定义元素已经是显示状态,那么直接返回
|
||||
if (this.node === node && this.isShowHandleEl) return
|
||||
// 更新当前节点信息
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
// 深度优先遍历树
|
||||
export const walk = (
|
||||
root,
|
||||
@ -31,9 +33,11 @@ export const walk = (
|
||||
|
||||
// 广度优先遍历树
|
||||
export const bfsWalk = (root, callback) => {
|
||||
callback(root)
|
||||
let stack = [root]
|
||||
let isStop = false
|
||||
if (callback(root, null) === 'stop') {
|
||||
isStop = true
|
||||
}
|
||||
while (stack.length) {
|
||||
if (isStop) {
|
||||
break
|
||||
@ -41,8 +45,9 @@ export const bfsWalk = (root, callback) => {
|
||||
let cur = stack.shift()
|
||||
if (cur.children && cur.children.length) {
|
||||
cur.children.forEach(item => {
|
||||
if (isStop) return
|
||||
stack.push(item)
|
||||
if (callback(item) === 'stop') {
|
||||
if (callback(item, cur) === 'stop') {
|
||||
isStop = true
|
||||
}
|
||||
})
|
||||
@ -424,3 +429,8 @@ export const getImageSize = src => {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 创建节点唯一的id
|
||||
export const createUid = () => {
|
||||
return uuidv4()
|
||||
}
|
||||
@ -4,7 +4,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0">
|
||||
<link rel="icon" href="./dist/logo.png">
|
||||
<link rel="icon" href="./dist/logo.ico">
|
||||
<title>思绪思维导图</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
BIN
web/public/logo.ico
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
web/src/assets/avatar/Chris.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
web/src/assets/avatar/default.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
web/src/assets/avatar/suka.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
web/src/assets/avatar/花儿朵朵.jpg
Normal file
|
After Width: | Height: | Size: 54 KiB |
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2479351 */
|
||||
src: url('iconfont.woff2?t=1688536767282') format('woff2'),
|
||||
url('iconfont.woff?t=1688536767282') format('woff'),
|
||||
url('iconfont.ttf?t=1688536767282') format('truetype');
|
||||
src: url('iconfont.woff2?t=1689407546912') format('woff2'),
|
||||
url('iconfont.woff?t=1689407546912') format('woff'),
|
||||
url('iconfont.ttf?t=1689407546912') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,54 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.iconjiantouyou:before {
|
||||
content: "\e62d";
|
||||
}
|
||||
|
||||
.iconbianji1:before {
|
||||
content: "\e60a";
|
||||
}
|
||||
|
||||
.icondaohang1:before {
|
||||
content: "\e632";
|
||||
}
|
||||
|
||||
.iconyanjing:before {
|
||||
content: "\e8bf";
|
||||
}
|
||||
|
||||
.iconwangzhan:before {
|
||||
content: "\e628";
|
||||
}
|
||||
|
||||
.iconcsdn:before {
|
||||
content: "\e608";
|
||||
}
|
||||
|
||||
.iconshejiaotubiao-10:before {
|
||||
content: "\e644";
|
||||
}
|
||||
|
||||
.iconstar:before {
|
||||
content: "\e7df";
|
||||
}
|
||||
|
||||
.iconfork:before {
|
||||
content: "\e641";
|
||||
}
|
||||
|
||||
.iconxiazai:before {
|
||||
content: "\e613";
|
||||
}
|
||||
|
||||
.iconteamwork:before {
|
||||
content: "\e870";
|
||||
}
|
||||
|
||||
.iconshuiyin:before {
|
||||
content: "\e67a";
|
||||
}
|
||||
|
||||
.iconxmind:before {
|
||||
content: "\ea57";
|
||||
}
|
||||
|
||||
BIN
web/src/assets/img/block1.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
web/src/assets/img/block3.png
Normal file
|
After Width: | Height: | Size: 29 KiB |
BIN
web/src/assets/img/block4.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
web/src/assets/img/logo2.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
web/src/assets/img/split.png
Normal file
|
After Width: | Height: | Size: 3.6 KiB |
@ -114,8 +114,9 @@ export default {
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: 'Open mini map',
|
||||
readonly: 'Readonly',
|
||||
edit: 'Edit'
|
||||
closeMiniMap: 'Close mini map',
|
||||
readonly: 'Change to eadonly',
|
||||
edit: 'Change to edit'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: 'Link',
|
||||
|
||||
@ -114,8 +114,9 @@ export default {
|
||||
},
|
||||
navigatorToolbar: {
|
||||
openMiniMap: '开启小地图',
|
||||
readonly: '只读模式',
|
||||
edit: '编辑模式'
|
||||
closeMiniMap: '关闭小地图',
|
||||
readonly: '切换为只读模式',
|
||||
edit: '切换为编辑模式'
|
||||
},
|
||||
nodeHyperlink: {
|
||||
title: '超链接',
|
||||
|
||||
@ -15,7 +15,8 @@
|
||||
import Header from './components/Header.vue'
|
||||
import Sidebar from './components/Sidebar.vue'
|
||||
import CatalogBar from './components/CatalogBar.vue'
|
||||
import 'highlight.js/styles/atom-one-dark.css'
|
||||
// import 'highlight.js/styles/atom-one-dark.css'
|
||||
import 'highlight.js/styles/github.css'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -103,7 +104,7 @@ export default {
|
||||
a {
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
color: #42b883;
|
||||
color: #1ea59a;
|
||||
transition: color 0.25s;
|
||||
|
||||
&:hover {
|
||||
|
||||
@ -225,7 +225,7 @@ export default {
|
||||
left: -10px;
|
||||
width: 4px;
|
||||
height: 20px;
|
||||
background-color: #42b883;
|
||||
background-color: #1ea59a;
|
||||
border-radius: 4px;
|
||||
transition: top 0.25s cubic-bezier(0, 1, 0.5, 1), opacity 0.25s,
|
||||
background-color 0.5s;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="headerContainer">
|
||||
<div class="left">
|
||||
<div class="title">
|
||||
<img src="../../../assets/img/logo.png" alt="">
|
||||
<div class="title" @click="toIndex">
|
||||
<img src="../../../assets/img/logo2.png" alt="">
|
||||
SimpleMindMap
|
||||
</div>
|
||||
</div>
|
||||
@ -74,6 +74,10 @@ export default {
|
||||
}
|
||||
},
|
||||
|
||||
toIndex() {
|
||||
this.$router.push('/index')
|
||||
},
|
||||
|
||||
toDemo() {
|
||||
this.$router.push('/')
|
||||
},
|
||||
@ -108,6 +112,7 @@ export default {
|
||||
font-weight: bold;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
width: 30px;
|
||||
@ -130,7 +135,7 @@ export default {
|
||||
font-size: 14px;
|
||||
|
||||
&:hover {
|
||||
color: #42b883;
|
||||
color: #1ea59a;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -108,7 +108,7 @@ export default {
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #42b883;
|
||||
color: #1ea59a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## 0.6.7
|
||||
|
||||
Fix: 1.Fixed the issue of missing placeholder elements for the expand and collapse button after node collapse and expansion. 2.Fixed the issue of being able to scale images in read-only mode.
|
||||
|
||||
New: 1.Support locating to a node based on node instance or node uid. 2.Modify the creation method of node uids and export data to add node uids.
|
||||
|
||||
Remove: 1.Remove the node transition effect.
|
||||
|
||||
Demo: 1.Add website homepage. 2.Fixed the issue of missing node styles when creating new nodes in the outline. 3.Fixed the issue of missing edited text after pressing Enter or Tab after editing nodes in the outline. 4.Optimize the node positioning of the outline, and the collapsed nodes will automatically expand. 5.The sidebar button supports folding. 6.Optimize small screen adaptation.
|
||||
|
||||
## 0.6.6
|
||||
|
||||
New: 1.Support exporting to Xmind new version files. 2.Importing the new version of Xmind file supports importing images from nodes. 3.Add a vertical timeline structure.
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.6.7</h2>
|
||||
<p>Fix: 1.Fixed the issue of missing placeholder elements for the expand and collapse button after node collapse and expansion. 2.Fixed the issue of being able to scale images in read-only mode.</p>
|
||||
<p>New: 1.Support locating to a node based on node instance or node uid. 2.Modify the creation method of node uids and export data to add node uids.</p>
|
||||
<p>Remove: 1.Remove the node transition effect.</p>
|
||||
<p>Demo: 1.Add website homepage. 2.Fixed the issue of missing node styles when creating new nodes in the outline. 3.Fixed the issue of missing edited text after pressing Enter or Tab after editing nodes in the outline. 4.Optimize the node positioning of the outline, and the collapsed nodes will automatically expand. 5.The sidebar button supports folding. 6.Optimize small screen adaptation.</p>
|
||||
<h2>0.6.6</h2>
|
||||
<p>New: 1.Support exporting to Xmind new version files. 2.Importing the new version of Xmind file supports importing images from nodes. 3.Add a vertical timeline structure.</p>
|
||||
<p>Fix: 1.The TouchEvent plugin no longer sends click events, solving the problem of two windows opening when clicking on a hyperlink on the mobile end. 2.Fix the issue of dragging and moving a node to become a child node of another node, where the parent node of that node points to not being updated. 3.Fixed an issue where the node border style was not updated when dragging a second level node into a third level node. 4.Fix the issue where the mouse will not trigger the button display when moving into the unfolded or retracted button position, except for the structure growing to the right.</p>
|
||||
|
||||
@ -51,8 +51,8 @@ const mindMap = new MindMap({
|
||||
| expandBtnStyle(v0.5.0+) | Object | { color: '#808080', fill: '#fff' } | Expand the color of the stow button | |
|
||||
| expandBtnIcon(v0.5.0+) | Object | { open: '', close: '' } | Customize the icon of the expand/collapse button, and you can transfer the svg string of the icon | |
|
||||
| enableShortcutOnlyWhenMouseInSvg(v0.5.1+) | Boolean | true | Only respond to shortcut key events when the mouse is inside the canvas | |
|
||||
| enableNodeTransitionMove(v0.5.1+) | Boolean | true | Whether to enable node animation transition | |
|
||||
| nodeTransitionMoveDuration(v0.5.1+) | Number | 300 | If node animation transition is enabled, the transition time can be set using this attribute, in milliseconds | |
|
||||
| enableNodeTransitionMove(v0.5.1+)(v0.6.7+ is remove this feature) | Boolean | true | Whether to enable node animation transition | |
|
||||
| nodeTransitionMoveDuration(v0.5.1+)(v0.6.7+ is remove this feature) | Number | 300 | If node animation transition is enabled, the transition time can be set using this attribute, in milliseconds | |
|
||||
| initRootNodePosition(v0.5.3+) | Array | null | The position of the initial root node can be passed as an array, default is `['center', 'center']`, Represents the root node at the center of the canvas, In addition to `center`, keywords can also be set to `left`, `top`, `right`, and `bottom`, In addition to passing keywords, each item in the array can also pass a number representing a specific pixel, Can pass a percentage string, such as `['40%', '60%']`, Represents a horizontal position at `40%` of the canvas width, and a vertical position at `60%` of the canvas height | |
|
||||
| exportPaddingX(v0.5.5+) | Number | 10 | Horizontal padding of graphics when exporting PNG, SVG, and PDF | |
|
||||
| exportPaddingY(v0.5.5+) | Number | 10 | Vertical padding of graphics when exporting PNG, SVG, and PDF | |
|
||||
@ -347,6 +347,7 @@ redo. All commands are as follows:
|
||||
| SET_NODE_CUSTOM_POSITION (v0.2.0+) | Set a custom position for a node | node (the node to set), left (custom x coordinate, default is undefined), top (custom y coordinate, default is undefined) |
|
||||
| RESET_LAYOUT (v0.2.0+) | Arrange layout with one click | |
|
||||
| SET_NODE_SHAPE (v0.2.4+) | Set the shape of a node | node (the node to set), shape (the shape, all shapes: [Shape.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/render/node/Shape.js)) |
|
||||
| GO_TARGET_NODE(v0.6.7+) | Navigate to a node, and if the node is collapsed, it will automatically expand to that node | node(Node instance or node uid to locate) |
|
||||
|
||||
### setData(data)
|
||||
|
||||
|
||||
@ -218,14 +218,14 @@
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>enableNodeTransitionMove(v0.5.1+)</td>
|
||||
<td>enableNodeTransitionMove(v0.5.1+)(v0.6.7+ is remove this feature)</td>
|
||||
<td>Boolean</td>
|
||||
<td>true</td>
|
||||
<td>Whether to enable node animation transition</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nodeTransitionMoveDuration(v0.5.1+)</td>
|
||||
<td>nodeTransitionMoveDuration(v0.5.1+)(v0.6.7+ is remove this feature)</td>
|
||||
<td>Number</td>
|
||||
<td>300</td>
|
||||
<td>If node animation transition is enabled, the transition time can be set using this attribute, in milliseconds</td>
|
||||
@ -920,6 +920,11 @@ redo. All commands are as follows:</p>
|
||||
<td>Set the shape of a node</td>
|
||||
<td>node (the node to set), shape (the shape, all shapes: <a href="https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/render/node/Shape.js">Shape.js</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GO_TARGET_NODE(v0.6.7+)</td>
|
||||
<td>Navigate to a node, and if the node is collapsed, it will automatically expand to that node</td>
|
||||
<td>node(Node instance or node uid to locate)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>setData(data)</h3>
|
||||
|
||||
@ -148,4 +148,16 @@ Open source is not easy. If this project is helpful to you, you can invite the a
|
||||
<img src="../../../../assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>ZXR</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>花儿朵朵</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/suka.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>suka</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/Chris.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>Chris</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -107,6 +107,18 @@ full screen, support mini map</li>
|
||||
<img src="../../../../assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>ZXR</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>花儿朵朵</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/suka.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>suka</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/Chris.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>Chris</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -91,4 +91,22 @@ Move a node behind another node
|
||||
|
||||
Move a node to the center of the canvas.
|
||||
|
||||
Currently, if there is zoom, returning to the center will reset the zoom.
|
||||
Currently, if there is zoom, returning to the center will reset the zoom.
|
||||
|
||||
### expandToNodeUid(uid, callback)
|
||||
|
||||
> v0.6.7+
|
||||
|
||||
- `uid`: uid of node
|
||||
|
||||
- `callback`: Expand completed callback function
|
||||
|
||||
Expand to the node of the specified uid.
|
||||
|
||||
### findNodeByUid(uid)
|
||||
|
||||
> v0.6.7+
|
||||
|
||||
- `uid`: uid of node
|
||||
|
||||
Find the corresponding node instance based on the uid.
|
||||
@ -62,6 +62,27 @@ is an object, e.g. <code>{text: 'I am new text'}</code></p>
|
||||
</blockquote>
|
||||
<p>Move a node to the center of the canvas.</p>
|
||||
<p>Currently, if there is zoom, returning to the center will reset the zoom.</p>
|
||||
<h3>expandToNodeUid(uid, callback)</h3>
|
||||
<blockquote>
|
||||
<p>v0.6.7+</p>
|
||||
</blockquote>
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>uid</code>: uid of node</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>callback</code>: Expand completed callback function</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Expand to the node of the specified uid.</p>
|
||||
<h3>findNodeByUid(uid)</h3>
|
||||
<blockquote>
|
||||
<p>v0.6.7+</p>
|
||||
</blockquote>
|
||||
<ul>
|
||||
<li><code>uid</code>: uid of node</li>
|
||||
</ul>
|
||||
<p>Find the corresponding node instance based on the uid.</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## 0.6.7
|
||||
|
||||
修复:1.修复节点收起再展开后展开收起按钮占位元素丢失的问题。 2.修复只读模式下可以缩放图片的问题。
|
||||
|
||||
新增:1.支持根据节点实例或节点uid定位到某个节点。 2.修改节点uid的创建方式,导出数据添加节点的uid。
|
||||
|
||||
移除:1.移除节点过渡效果。
|
||||
|
||||
Demo:1.添加网站首页。 2.修复大纲里创建新节点时节点样式丢失的问题。 3.修复大纲里编辑节点后按回车或Tab键后编辑文本丢失的问题。 4.优化大纲的节点定位,被收起的节点会自动展开。 5.侧边栏按钮支持收起。 6.优化小屏适配。
|
||||
|
||||
## 0.6.6
|
||||
|
||||
新增:1.支持导出为Xmind新版文件。2.导入Xmind新版文件支持导入节点中的图片。 3.新增竖向时间轴结构。
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.6.7</h2>
|
||||
<p>修复:1.修复节点收起再展开后展开收起按钮占位元素丢失的问题。 2.修复只读模式下可以缩放图片的问题。</p>
|
||||
<p>新增:1.支持根据节点实例或节点uid定位到某个节点。 2.修改节点uid的创建方式,导出数据添加节点的uid。</p>
|
||||
<p>移除:1.移除节点过渡效果。</p>
|
||||
<p>Demo:1.添加网站首页。 2.修复大纲里创建新节点时节点样式丢失的问题。 3.修复大纲里编辑节点后按回车或Tab键后编辑文本丢失的问题。 4.优化大纲的节点定位,被收起的节点会自动展开。 5.侧边栏按钮支持收起。 6.优化小屏适配。</p>
|
||||
<h2>0.6.6</h2>
|
||||
<p>新增:1.支持导出为Xmind新版文件。2.导入Xmind新版文件支持导入节点中的图片。 3.新增竖向时间轴结构。</p>
|
||||
<p>修复:1.TouchEvent插件不再派发click事件,解决移动端点击超链接会打开两个窗口的问题。 2.修复拖拽移动一个节点成为另一个节点的子节点时该节点的父节点指向未更新的问题。 3.修复二级节点拖拽成三级节点时节点边框样式未更新的问题。 4.修复向右生长的结构外其他结构鼠标移入展开收起按钮位置时不会触发按钮显示的问题。</p>
|
||||
|
||||
@ -51,8 +51,8 @@ const mindMap = new MindMap({
|
||||
| expandBtnStyle(v0.5.0+) | Object | { color: '#808080', fill: '#fff' } | 展开收起按钮的颜色 | |
|
||||
| expandBtnIcon(v0.5.0+) | Object | { open: '', close: '' } | 自定义展开收起按钮的图标,可以传图标的svg字符串 | |
|
||||
| enableShortcutOnlyWhenMouseInSvg(v0.5.1+) | Boolean | true | 是否只有当鼠标在画布内才响应快捷键事件 | |
|
||||
| enableNodeTransitionMove(v0.5.1+) | Boolean | true | 是否开启节点动画过渡 | |
|
||||
| nodeTransitionMoveDuration(v0.5.1+) | Number | 300 | 如果开启节点动画过渡,可以通过该属性设置过渡的时间,单位ms | |
|
||||
| enableNodeTransitionMove(v0.5.1+)(v0.6.7+已去除该特性) | Boolean | true | 是否开启节点动画过渡 | |
|
||||
| nodeTransitionMoveDuration(v0.5.1+)(v0.6.7+已去除该特性) | Number | 300 | 如果开启节点动画过渡,可以通过该属性设置过渡的时间,单位ms | |
|
||||
| initRootNodePosition(v0.5.3+) | Array | null | 初始根节点的位置,可传一个数组,默认为`['center', 'center']`,代表根节点处于画布中心位置,除了`center`,关键词还可以设置`left`、`top`、`right`、`bottom`,除了可以传关键词,数组的每项还可以传递一个数字,代表具体的像素,可以传递一个百分比字符串,比如`['40%', '60%']`,代表水平位置在画布宽度的`40%`的位置,垂直位置在画布高度的`60%`的位置 | |
|
||||
| exportPaddingX(v0.5.5+) | Number | 10 | 导出png、svg、pdf时的图形水平内边距 | |
|
||||
| exportPaddingY(v0.5.5+) | Number | 10 | 导出png、svg、pdf时的图形垂直内边距 | |
|
||||
@ -340,6 +340,7 @@ mindMap.updateConfig({
|
||||
| SET_NODE_CUSTOM_POSITION(v0.2.0+) | 设置节点自定义位置 | node(要设置的节点)、 left(自定义的x坐标,默认为undefined)、 top(自定义的y坐标,默认为undefined) |
|
||||
| RESET_LAYOUT(v0.2.0+) | 一键整理布局 | |
|
||||
| SET_NODE_SHAPE(v0.2.4+) | 设置节点形状 | node(要设置的节点)、shape(形状,全部形状:[Shape.js](https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/render/node/Shape.js)) |
|
||||
| GO_TARGET_NODE(v0.6.7+) | 定位到某个节点,如果该节点被收起,那么会自动展开到该节点 | node(要定位到的节点实例或节点uid) |
|
||||
|
||||
### setData(data)
|
||||
|
||||
|
||||
@ -218,14 +218,14 @@
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>enableNodeTransitionMove(v0.5.1+)</td>
|
||||
<td>enableNodeTransitionMove(v0.5.1+)(v0.6.7+已去除该特性)</td>
|
||||
<td>Boolean</td>
|
||||
<td>true</td>
|
||||
<td>是否开启节点动画过渡</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nodeTransitionMoveDuration(v0.5.1+)</td>
|
||||
<td>nodeTransitionMoveDuration(v0.5.1+)(v0.6.7+已去除该特性)</td>
|
||||
<td>Number</td>
|
||||
<td>300</td>
|
||||
<td>如果开启节点动画过渡,可以通过该属性设置过渡的时间,单位ms</td>
|
||||
@ -915,6 +915,11 @@ mindMap.setTheme(<span class="hljs-string">'主题名称'</span>)
|
||||
<td>设置节点形状</td>
|
||||
<td>node(要设置的节点)、shape(形状,全部形状:<a href="https://github.com/wanglin2/mind-map/blob/main/simple-mind-map/src/core/render/node/Shape.js">Shape.js</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>GO_TARGET_NODE(v0.6.7+)</td>
|
||||
<td>定位到某个节点,如果该节点被收起,那么会自动展开到该节点</td>
|
||||
<td>node(要定位到的节点实例或节点uid)</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3>setData(data)</h3>
|
||||
|
||||
@ -18,6 +18,9 @@ mindMap.on('data_change', (data) => {
|
||||
const node = data._node
|
||||
mindMap.renderer.moveNodeToCenter(node)
|
||||
node.active()
|
||||
|
||||
// 在v0.6.7+版本可以这么做:
|
||||
mindMap.execCommand('GO_TARGET_NODE', node)// 或者传节点的uid
|
||||
```
|
||||
|
||||
当在大纲树上编辑了某个节点的内容,需要同步到思维导图树上:
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
<pre class="hljs"><code><span class="hljs-keyword">const</span> node = data._node
|
||||
mindMap.renderer.moveNodeToCenter(node)
|
||||
node.active()
|
||||
|
||||
<span class="hljs-comment">// 在v0.6.7+版本可以这么做:</span>
|
||||
mindMap.execCommand(<span class="hljs-string">'GO_TARGET_NODE'</span>, node)<span class="hljs-comment">// 或者传节点的uid</span>
|
||||
</code></pre>
|
||||
<p>当在大纲树上编辑了某个节点的内容,需要同步到思维导图树上:</p>
|
||||
<pre class="hljs"><code>data._node.setText(<span class="hljs-string">'xxx'</span>)
|
||||
|
||||
@ -108,7 +108,9 @@
|
||||
|
||||
## 请作者喝杯咖啡
|
||||
|
||||
开源不易,如果本项目有帮助到你的话,可以请作者喝杯咖啡哟~
|
||||
开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡哟~
|
||||
|
||||
> 厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds
|
||||
|
||||
> 转账请备注【思维导图】。你的头像和名字将会出现在下面。
|
||||
|
||||
@ -137,4 +139,16 @@
|
||||
<img src="../../../../assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>ZXR</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>花儿朵朵</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/suka.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>suka</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/Chris.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>Chris</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -69,7 +69,10 @@
|
||||
<h2>License</h2>
|
||||
<p><a href="https://opensource.org/licenses/MIT">MIT</a></p>
|
||||
<h2>请作者喝杯咖啡</h2>
|
||||
<p>开源不易,如果本项目有帮助到你的话,可以请作者喝杯咖啡哟~</p>
|
||||
<p>开源不易,如果本项目有帮助到你的话,可以考虑请作者喝杯咖啡哟~</p>
|
||||
<blockquote>
|
||||
<p>厚椰乳一盒 + 纯牛奶半盒 + 冰块 + 咖啡液 = 生椰拿铁 yyds</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>转账请备注【思维导图】。你的头像和名字将会出现在下面。</p>
|
||||
</blockquote>
|
||||
@ -96,6 +99,18 @@
|
||||
<img src="../../../../assets/avatar/ZXR.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>ZXR</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/花儿朵朵.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>花儿朵朵</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/suka.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>suka</p>
|
||||
</div>
|
||||
<div style="display: flex; flex-direction: column; align-items: center; width: fit-content; margin: 5px;">
|
||||
<img src="../../../../assets/avatar/Chris.jpg" style="width: 50px;height: 50px;object-fit: cover;border-radius: 50%;" />
|
||||
<p>Chris</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -82,4 +82,22 @@
|
||||
|
||||
移动节点到画布中心。
|
||||
|
||||
目前如果是存在缩放的情况下回到中心会重置缩放。
|
||||
目前如果是存在缩放的情况下回到中心会重置缩放。
|
||||
|
||||
### expandToNodeUid(uid, callback)
|
||||
|
||||
> v0.6.7+
|
||||
|
||||
- `uid`:节点uid
|
||||
|
||||
- `callback`:展开完成的回调函数
|
||||
|
||||
展开到指定uid的节点。
|
||||
|
||||
### findNodeByUid(uid)
|
||||
|
||||
> v0.6.7+
|
||||
|
||||
- `uid`:节点uid
|
||||
|
||||
根据uid找到对应的节点实例。
|
||||
@ -51,6 +51,27 @@
|
||||
</blockquote>
|
||||
<p>移动节点到画布中心。</p>
|
||||
<p>目前如果是存在缩放的情况下回到中心会重置缩放。</p>
|
||||
<h3>expandToNodeUid(uid, callback)</h3>
|
||||
<blockquote>
|
||||
<p>v0.6.7+</p>
|
||||
</blockquote>
|
||||
<ul>
|
||||
<li>
|
||||
<p><code>uid</code>:节点uid</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><code>callback</code>:展开完成的回调函数</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>展开到指定uid的节点。</p>
|
||||
<h3>findNodeByUid(uid)</h3>
|
||||
<blockquote>
|
||||
<p>v0.6.7+</p>
|
||||
</blockquote>
|
||||
<ul>
|
||||
<li><code>uid</code>:节点uid</li>
|
||||
</ul>
|
||||
<p>根据uid找到对应的节点实例。</p>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -95,4 +95,10 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 635px) {
|
||||
.countContainer {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -74,6 +74,7 @@ export default {
|
||||
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -19,25 +19,51 @@
|
||||
<MouseAction :mindMap="mindMap"></MouseAction>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-checkbox v-model="openMiniMap" @change="toggleMiniMap">{{
|
||||
$t('navigatorToolbar.openMiniMap')
|
||||
}}</el-checkbox>
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="
|
||||
openMiniMap
|
||||
? $t('navigatorToolbar.closeMiniMap')
|
||||
: $t('navigatorToolbar.openMiniMap')
|
||||
"
|
||||
placement="top"
|
||||
>
|
||||
<div
|
||||
class="btn iconfont icondaohang1"
|
||||
@click="toggleMiniMap"
|
||||
></div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="item">
|
||||
<el-switch
|
||||
<!-- <el-switch
|
||||
v-model="isReadonly"
|
||||
:active-text="$t('navigatorToolbar.readonly')"
|
||||
:inactive-text="$t('navigatorToolbar.edit')"
|
||||
@change="readonlyChange"
|
||||
>
|
||||
</el-switch>
|
||||
</div>
|
||||
<div class="item">
|
||||
<Scale :mindMap="mindMap"></Scale>
|
||||
</el-switch> -->
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="
|
||||
isReadonly
|
||||
? $t('navigatorToolbar.edit')
|
||||
: $t('navigatorToolbar.readonly')
|
||||
"
|
||||
placement="top"
|
||||
>
|
||||
<div
|
||||
class="btn iconfont"
|
||||
:class="[isReadonly ? 'iconyanjing' : 'iconbianji1']"
|
||||
@click="readonlyChange"
|
||||
></div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
<div class="item">
|
||||
<Fullscreen :mindMap="mindMap"></Fullscreen>
|
||||
</div>
|
||||
<div class="item">
|
||||
<Scale :mindMap="mindMap"></Scale>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="iconfont icongithub" @click="openGithub"></span>
|
||||
</div>
|
||||
@ -77,16 +103,15 @@ export default {
|
||||
openMiniMap: false
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.toggleMiniMap(this.openMiniMap)
|
||||
},
|
||||
methods: {
|
||||
readonlyChange(value) {
|
||||
this.mindMap.setMode(value ? 'readonly' : 'edit')
|
||||
readonlyChange() {
|
||||
this.isReadonly = !this.isReadonly
|
||||
this.mindMap.setMode(this.isReadonly ? 'readonly' : 'edit')
|
||||
},
|
||||
|
||||
toggleMiniMap(show) {
|
||||
this.$bus.$emit('toggle_mini_map', show)
|
||||
toggleMiniMap() {
|
||||
this.openMiniMap = !this.openMiniMap
|
||||
this.$bus.$emit('toggle_mini_map', this.openMiniMap)
|
||||
},
|
||||
|
||||
onLangChange(lang) {
|
||||
@ -126,6 +151,18 @@ export default {
|
||||
color: #303133;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 502px) {
|
||||
.navigatorContainer {
|
||||
left: 20px;
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -46,11 +46,10 @@ export default {
|
||||
data: [],
|
||||
defaultProps: {
|
||||
label(data) {
|
||||
return data.data.text.replaceAll(/\n/g, '</br>')
|
||||
return data.data.richText ? data.data.text : data.data.text.replaceAll(/\n/g, '</br>')
|
||||
}
|
||||
},
|
||||
notHandleDataChange: false,
|
||||
isCreateNode: false
|
||||
notHandleDataChange: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -77,11 +76,12 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
onBlur(e, node) {
|
||||
if (this.isCreateNode) {
|
||||
this.isCreateNode = false
|
||||
return
|
||||
const richText = node.data.data.richText
|
||||
if (richText) {
|
||||
node.data._node.setText(e.target.innerHTML, true)
|
||||
} else {
|
||||
node.data._node.setText(e.target.innerText)
|
||||
}
|
||||
node.data._node.setText(e.target.innerText)
|
||||
},
|
||||
|
||||
getKey() {
|
||||
@ -102,24 +102,21 @@ export default {
|
||||
// 插入兄弟节点
|
||||
insertNode() {
|
||||
this.notHandleDataChange = false
|
||||
this.isCreateNode = true
|
||||
this.mindMap.execCommand('INSERT_NODE', false)
|
||||
},
|
||||
|
||||
// 插入下级节点
|
||||
insertChildNode() {
|
||||
this.notHandleDataChange = false
|
||||
this.isCreateNode = true
|
||||
this.mindMap.execCommand('INSERT_CHILD_NODE', false)
|
||||
},
|
||||
|
||||
// 激活当前节点且移动当前节点到画布中间
|
||||
onClick(e, data) {
|
||||
onClick(e, node) {
|
||||
this.notHandleDataChange = true
|
||||
let node = data.data._node
|
||||
if (node.nodeData.data.isActive) return
|
||||
node.mindMap.renderer.moveNodeToCenter(node)
|
||||
node.active()
|
||||
let targetNode = node.data._node
|
||||
if (targetNode && targetNode.nodeData.data.isActive) return
|
||||
this.mindMap.execCommand('GO_TARGET_NODE', node.data.data.uid)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,11 @@
|
||||
<div
|
||||
class="sidebarTriggerContainer"
|
||||
@click.stop
|
||||
:class="{ show: activeSidebar }"
|
||||
:class="{ hasActive: show && activeSidebar, show: show }"
|
||||
>
|
||||
<div class="toggleShowBtn" :class="{hide: !show}" @click="show = !show">
|
||||
<span class="iconfont iconjiantouyou"></span>
|
||||
</div>
|
||||
<div class="trigger">
|
||||
<div
|
||||
class="triggerItem"
|
||||
@ -32,7 +35,7 @@ export default {
|
||||
name: 'SidebarTrigger',
|
||||
data() {
|
||||
return {
|
||||
show: false
|
||||
show: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -55,17 +58,57 @@ export default {
|
||||
<style lang="less" scoped>
|
||||
.sidebarTriggerContainer {
|
||||
position: fixed;
|
||||
right: 0px;
|
||||
right: -60px;
|
||||
margin-top: 110px;
|
||||
transition: all 0.3s;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
&.show {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
&.hasActive {
|
||||
right: 305px;
|
||||
}
|
||||
|
||||
.toggleShowBtn {
|
||||
position: absolute;
|
||||
left: -6px;
|
||||
width: 35px;
|
||||
height: 60px;
|
||||
background: #409eff;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
cursor: pointer;
|
||||
transition: left .1s linear;
|
||||
z-index: 0;
|
||||
border-top-left-radius: 10px;
|
||||
border-bottom-left-radius: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 4px;
|
||||
|
||||
&.hide {
|
||||
left: -8px;
|
||||
|
||||
span {
|
||||
transform: rotateZ(180deg);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
left: -18px;
|
||||
}
|
||||
|
||||
span {
|
||||
color: #fff;
|
||||
transition: all 0.1s;
|
||||
}
|
||||
}
|
||||
|
||||
.trigger {
|
||||
position: relative;
|
||||
width: 60px;
|
||||
border-color: #eee;
|
||||
background-color: #fff;
|
||||
|
||||
@ -520,4 +520,17 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1040px) {
|
||||
|
||||
.toolbarContainer {
|
||||
.toolbar {
|
||||
left: 20px;
|
||||
right: 20px;
|
||||
transform: translateX(0);
|
||||
width: auto;
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
41
web/src/pages/Index/Index.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<div class="indexContainer">
|
||||
<Header></Header>
|
||||
<Block1></Block1>
|
||||
<Block2></Block2>
|
||||
<Block3></Block3>
|
||||
<Block4></Block4>
|
||||
<Block5></Block5>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Header from './components/Header.vue'
|
||||
import Block1 from './components/Block1.vue'
|
||||
import Block2 from './components/Block2.vue'
|
||||
import Block3 from './components/Block3.vue'
|
||||
import Block4 from './components/Block4.vue'
|
||||
import Block5 from './components/Block5.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Header,
|
||||
Block1,
|
||||
Block2,
|
||||
Block3,
|
||||
Block4,
|
||||
Block5
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
},
|
||||
|
||||
created() {},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.indexContainer {
|
||||
}
|
||||
</style>
|
||||
206
web/src/pages/Index/components/Block1.vue
Normal file
@ -0,0 +1,206 @@
|
||||
<template>
|
||||
<div class="block1Container" :style="{ height: height + 'px' }">
|
||||
<div class="blockContent">
|
||||
<div class="infoBox">
|
||||
<div class="blockTitle">Simple mind map</div>
|
||||
<Split></Split>
|
||||
<div class="infoList">
|
||||
<p class="infoRow">是一个思维导图库</p>
|
||||
<p class="infoRow">同时也是一个思维导图软件</p>
|
||||
<p class="infoRow">开源、免费、强大...</p>
|
||||
</div>
|
||||
<div class="desc">
|
||||
无论你是开发者,还是使用者,只要喜欢思维导图,都能在这个项目里找到你需要的。
|
||||
</div>
|
||||
<div class="btnBox">
|
||||
<div class="btn" @click="useOnline">在线使用</div>
|
||||
<div class="btn btn2" @click="jumpDoc">开发文档</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="picBox">
|
||||
<div class="animation1"></div>
|
||||
<div class="animation2"></div>
|
||||
<div class="animation3"></div>
|
||||
<div class="pic"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Split from './Split.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Split
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
height: 0
|
||||
}
|
||||
},
|
||||
created() {
|
||||
window.addEventListener('resize', this.onResize)
|
||||
this.onResize()
|
||||
},
|
||||
mounted() {},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('resize', this.onResize)
|
||||
},
|
||||
methods: {
|
||||
onResize() {
|
||||
this.height = window.innerHeight
|
||||
},
|
||||
|
||||
useOnline() {
|
||||
this.$router.push('/')
|
||||
},
|
||||
|
||||
jumpDoc() {
|
||||
this.$router.push('/doc/zh/')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.block1Container {
|
||||
background-color: #f0f9fa;
|
||||
border-radius: 0 0 0 450px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.blockContent {
|
||||
width: 100%;
|
||||
max-width: 1140px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.infoBox {
|
||||
.blockTitle {
|
||||
font-size: 16px;
|
||||
color: #1e3547;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.infoList {
|
||||
margin-top: 20px;
|
||||
|
||||
.infoRow {
|
||||
font-size: 45px;
|
||||
color: #1e3547;
|
||||
font-weight: 700;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: #828f99;
|
||||
font-size: 20px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.btnBox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
|
||||
.btn {
|
||||
height: 44px;
|
||||
padding: 0 20px;
|
||||
line-height: 44px;
|
||||
cursor: pointer;
|
||||
background: #1ea59a;
|
||||
border-color: #1ea59a;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
border-radius: 5px;
|
||||
transition: all 0.5s;
|
||||
margin-right: 10px;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
&.btn2 {
|
||||
background-color: #f5828b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.picBox {
|
||||
position: relative;
|
||||
.pic {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
background-image: url('../../../assets/img/block1.png');
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.animation1 {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border: 7px solid #f5828b;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
right: -50px;
|
||||
bottom: 86px;
|
||||
animation-name: zoom1;
|
||||
animation-duration: 3s;
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
box-shadow: 0 12px 50px 0 rgba(0, 0, 0, 0.14);
|
||||
}
|
||||
|
||||
.animation2 {
|
||||
border-radius: 50%;
|
||||
background-color: #1ea59a;
|
||||
box-shadow: 0 20px 30px 0 rgba(48, 61, 114, 0.4);
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
top: -60px;
|
||||
right: 60px;
|
||||
animation: spin 2s infinite alternate;
|
||||
bottom: 60px;
|
||||
}
|
||||
|
||||
.animation3 {
|
||||
border-radius: 50%;
|
||||
background-color: #25233a;
|
||||
box-shadow: 0 20px 30px 0 rgba(245, 130, 139, 0.4);
|
||||
position: absolute;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
bottom: 50px;
|
||||
left: 0px;
|
||||
animation: spin 3s infinite alternate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes zoom1 {
|
||||
0% {
|
||||
transform: scale(0.9);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1.5);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(40px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
263
web/src/pages/Index/components/Block2.vue
Normal file
@ -0,0 +1,263 @@
|
||||
<template>
|
||||
<div class="block2Container">
|
||||
<div class="blockContent">
|
||||
<div class="blockTitle">为什么选择Simple mind map?</div>
|
||||
<div class="dataList">
|
||||
<div class="dataItem" v-for="(item, index) in dataList" :key="index">
|
||||
<div class="iconBox">
|
||||
<span class="icon iconfont" :class="[item.icon]"></span>
|
||||
</div>
|
||||
<div class="dataValue">{{ item.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="desc">
|
||||
如果你是开发者:Simple mind
|
||||
map提供了一个功能完善的 js 思维导图库,不依赖任何框架,你可以使用它来快速完成Web思维导图产品的开发。
|
||||
</div>
|
||||
<div class="desc">
|
||||
如果你是使用者:Simple mind
|
||||
map提供了一个完整的思维导图软件,支持在线和客户端两种使用方式,所有功能完全免费。
|
||||
</div>
|
||||
<div class="functionList">
|
||||
<div
|
||||
class="functionItem"
|
||||
v-for="(item, index) in functionList"
|
||||
:key="index"
|
||||
>
|
||||
<div class="icon iconfont" :class="[item.icon]"></div>
|
||||
<div class="info">
|
||||
<div class="name">{{ item.name }}</div>
|
||||
<div class="value">{{ item.value }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dataList: [
|
||||
{
|
||||
icon: 'iconstar',
|
||||
value: 'Github star数量450+'
|
||||
},
|
||||
{
|
||||
icon: 'iconfork',
|
||||
value: 'Github fork数量100+'
|
||||
},
|
||||
{
|
||||
icon: 'iconxiazai',
|
||||
value: 'npm总下载次数10000+'
|
||||
},
|
||||
{
|
||||
icon: 'iconteamwork',
|
||||
value: '代码贡献者6+'
|
||||
}
|
||||
],
|
||||
functionList: [
|
||||
{
|
||||
icon: 'iconjingzi',
|
||||
name: '主题',
|
||||
value: '内置多种主题,允许高度自定义样式,支持注册新主题。'
|
||||
},
|
||||
{
|
||||
icon: 'iconjiegou',
|
||||
name: '结构',
|
||||
value:
|
||||
'支持常见的逻辑结构图、思维导图、组织结构图、目录组织图、时间轴、鱼骨图结构。'
|
||||
},
|
||||
{
|
||||
icon: 'iconjianpan',
|
||||
name: '快捷键',
|
||||
value: '常用操作支持快捷键,方便使用。'
|
||||
},
|
||||
{
|
||||
icon: 'iconzitixiahuaxian',
|
||||
name: '富文本',
|
||||
value:
|
||||
'节点支持普通文本和富文本两种类型,通过富文本可以创建样式丰富的节点文本内容。'
|
||||
},
|
||||
{
|
||||
icon: 'iconimage',
|
||||
name: '图片',
|
||||
value: '选中任一节点,选择上传图片,让内容达到图文并茂。'
|
||||
},
|
||||
{
|
||||
icon: 'icongaikuozonglan',
|
||||
name: '概要',
|
||||
value: '补充表述几个节点之间的关系。'
|
||||
},
|
||||
{
|
||||
icon: 'iconxiaolian',
|
||||
name: '图标',
|
||||
value: '通过添加图标来让节点内容更丰富。'
|
||||
},
|
||||
{
|
||||
icon: 'iconchaolianjie',
|
||||
name: '超链接',
|
||||
value: '节点可插入超链接,鼠标点击即可实现跳转。'
|
||||
},
|
||||
{
|
||||
icon: 'iconflow-Mark',
|
||||
name: '备注',
|
||||
value: '详细的内容可以放在备注中,节点内显得更简单明了。'
|
||||
},
|
||||
{
|
||||
icon: 'iconbiaoqian',
|
||||
name: '标签',
|
||||
value: '如果添加带颜色的标签,来突出要表达的重点。'
|
||||
},
|
||||
{
|
||||
icon: 'iconlianjiexian',
|
||||
name: '关联线',
|
||||
value: '通过添加关联线来表明节点之间的关联关系。'
|
||||
},
|
||||
{
|
||||
icon: 'iconmouseL',
|
||||
name: '拖动',
|
||||
value: '画布和节点都可以进行拖动。'
|
||||
},
|
||||
{
|
||||
icon: 'icondaohang',
|
||||
name: '导航器',
|
||||
value: '通过导航器可以方便知道当前画布处于思维导图的哪个部分。'
|
||||
},
|
||||
{
|
||||
icon: 'icondaochu',
|
||||
name: '导入导出',
|
||||
value: '支持多种文件格式的导入和导出。'
|
||||
},
|
||||
{
|
||||
icon: 'iconshuiyin',
|
||||
name: '水印',
|
||||
value: '内置支持水印功能,防止隐私泄露。'
|
||||
},
|
||||
{
|
||||
icon: 'iconwithdraw',
|
||||
name: '前进后退',
|
||||
value: '不小心误操作删除或修改内容支持一键撤回或恢复。'
|
||||
},
|
||||
{
|
||||
icon: 'iconfuhao-dagangshu',
|
||||
name: '大纲',
|
||||
value: '根据大纲编辑思维导图,让内容更详细也不容易出错。'
|
||||
},
|
||||
{
|
||||
icon: 'iconshezhi',
|
||||
name: '丰富的设置',
|
||||
value: '提供了丰富的功能设置,可以选择合适你的操作行为。'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.block2Container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.blockContent {
|
||||
padding: 100px 0;
|
||||
width: 100%;
|
||||
max-width: 1140px;
|
||||
|
||||
.dataList {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 40px;
|
||||
.dataItem {
|
||||
box-shadow: 0 5px 30px -10px rgba(0, 0, 0, 0.1);
|
||||
border-radius: 20px;
|
||||
margin-right: 30px;
|
||||
padding: 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.iconBox {
|
||||
width: 55px;
|
||||
height: 55px;
|
||||
border-radius: 10px;
|
||||
background-color: rgba(30, 165, 154, 0.1);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 10px;
|
||||
|
||||
.icon {
|
||||
font-size: 30px;
|
||||
color: #1ea59a;
|
||||
}
|
||||
}
|
||||
|
||||
.dataValue {
|
||||
color: #1e3547;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.blockTitle {
|
||||
font-size: 30px;
|
||||
font-weight: 700;
|
||||
color: #1e3547;
|
||||
text-align: center;
|
||||
margin-bottom: 40px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: #828f99;
|
||||
font-size: 17px;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
.functionList {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 60px;
|
||||
.functionItem {
|
||||
display: flex;
|
||||
width: 30%;
|
||||
margin-bottom: 50px;
|
||||
|
||||
.icon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
font-size: 50px;
|
||||
margin-right: 24px;
|
||||
color: #1ea59a;
|
||||
}
|
||||
|
||||
.info {
|
||||
.name {
|
||||
margin-bottom: 5px;
|
||||
color: #1e3547;
|
||||
font-weight: 600;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.value {
|
||||
font-size: 14px;
|
||||
color: #828f99;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
102
web/src/pages/Index/components/Block3.vue
Normal file
@ -0,0 +1,102 @@
|
||||
<template>
|
||||
<div class="block3Container">
|
||||
<div class="blockContent">
|
||||
<div class="picBox"></div>
|
||||
<div class="infoBox">
|
||||
<div class="infoTitle">客户端</div>
|
||||
<div class="info">支持Windows、Mac、Linux平台。</div>
|
||||
<div class="info">
|
||||
在线版数据默认保存在浏览器缓存里,同时也可以操作电脑本地文件,但是在线版受限于网络环境,访问可能比较慢,多个文件切换也不够方便,所以提供客户端版本,功能简单但不简陋。
|
||||
</div>
|
||||
<div class="btnList">
|
||||
<div class="btn">
|
||||
<a href="https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3" target="_blank">百度网盘下载</a>
|
||||
</div>
|
||||
<div class="btn btn2">
|
||||
<a href="https://github.com/wanglin2/mind-map/releases" target="_blank">Github下载</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.block3Container {
|
||||
background-color: #f0f9fa;
|
||||
border-radius: 0 0 350px 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.blockContent {
|
||||
width: 100%;
|
||||
max-width: 1140px;
|
||||
height: 520px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.picBox {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
background-image: url('../../../assets/img/block3.png');
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.infoBox {
|
||||
.infoTitle {
|
||||
font-weight: 700;
|
||||
color: #1e3547;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #828f99;
|
||||
font-size: 16px;
|
||||
line-height: 1.7;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.btnList {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.btn {
|
||||
height: 44px;
|
||||
cursor: pointer;
|
||||
background: #1ea59a;
|
||||
border-color: #1ea59a;
|
||||
border-radius: 5px;
|
||||
transition: all 0.5s;
|
||||
margin-right: 10px;
|
||||
margin-top: 20px;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
&.btn2 {
|
||||
background-color: #f5828b;
|
||||
}
|
||||
|
||||
a {
|
||||
height: 100%;
|
||||
padding: 0 20px;
|
||||
line-height: 44px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
140
web/src/pages/Index/components/Block4.vue
Normal file
@ -0,0 +1,140 @@
|
||||
<template>
|
||||
<div class="block4Container">
|
||||
<div class="blockContent">
|
||||
<div class="infoBox">
|
||||
<div class="infoTitle">JavaScript库</div>
|
||||
<div class="info">
|
||||
simple-mind-map是一个简单&强大的Web思维导图库,不依赖任何特定框架,可以帮助你快速开发思维导图产品。
|
||||
</div>
|
||||
<div class="info">
|
||||
使用非常简单,只需三步即可渲染出一个思维导图:
|
||||
</div>
|
||||
<div class="info">第一步:安装</div>
|
||||
<div class="codeBox">
|
||||
<pre><code class="language-bash" ref="code1">
|
||||
npm i simple-mind-map
|
||||
</code></pre>
|
||||
</div>
|
||||
<div class="info">第二步:引入</div>
|
||||
<div class="codeBox">
|
||||
<pre><code class="language-javascript" ref="code2">
|
||||
import MindMap from "simple-mind-map"
|
||||
</code></pre>
|
||||
</div>
|
||||
<div class="info">第三步:实例化</div>
|
||||
<div class="codeBox">
|
||||
<pre><code class="language-javascript" ref="code3">
|
||||
const mindMap = new MindMap({
|
||||
// 提供一个宽高不为0的容器元素
|
||||
el: document.getElementById('mindMapContainer'),
|
||||
// 思维导图数据
|
||||
data: {
|
||||
"data": {
|
||||
"text": "根节点"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
})
|
||||
</code></pre>
|
||||
</div>
|
||||
<div class="btnList">
|
||||
<div class="btn" @click="jumpDoc">查看更多</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="picBox"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import hljs from 'highlight.js/lib/core'
|
||||
import javascript from 'highlight.js/lib/languages/javascript'
|
||||
import bash from 'highlight.js/lib/languages/bash'
|
||||
import 'highlight.js/styles/github.css'
|
||||
hljs.registerLanguage('javascript', javascript)
|
||||
hljs.registerLanguage('bash', bash)
|
||||
|
||||
export default {
|
||||
mounted() {
|
||||
hljs.highlightElement(this.$refs.code1)
|
||||
hljs.highlightElement(this.$refs.code2)
|
||||
hljs.highlightElement(this.$refs.code3)
|
||||
},
|
||||
methods: {
|
||||
jumpDoc() {
|
||||
this.$router.push('/doc/zh/')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.block4Container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.blockContent {
|
||||
width: 100%;
|
||||
max-width: 1140px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 50px 0;
|
||||
|
||||
.picBox {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
background-image: url('../../../assets/img/block4.png');
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.infoBox {
|
||||
margin-right: 50px;
|
||||
|
||||
.infoTitle {
|
||||
font-weight: 700;
|
||||
color: #1e3547;
|
||||
font-size: 40px;
|
||||
}
|
||||
|
||||
.info {
|
||||
color: #828f99;
|
||||
font-size: 16px;
|
||||
line-height: 1.7;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.codeBox {
|
||||
font-size: 16px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.btnList {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.btn {
|
||||
height: 44px;
|
||||
cursor: pointer;
|
||||
background: #1ea59a;
|
||||
border-color: #1ea59a;
|
||||
border-radius: 5px;
|
||||
transition: all 0.5s;
|
||||
margin-right: 10px;
|
||||
margin-top: 20px;
|
||||
height: 100%;
|
||||
padding: 0 20px;
|
||||
line-height: 44px;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 15px;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
229
web/src/pages/Index/components/Block5.vue
Normal file
@ -0,0 +1,229 @@
|
||||
<template>
|
||||
<div class="block5Container">
|
||||
<div class="blockContent">
|
||||
<div class="infoBox">
|
||||
<div class="infoTitle">街角小林出品</div>
|
||||
<div class="infoDesc">
|
||||
男,90后,六年+前端开发工程师,热爱前端、写作、开源。
|
||||
</div>
|
||||
<div class="linkBtnList">
|
||||
<div class="linkBtn">
|
||||
<a href="https://github.com/wanglin2" target="_blank">
|
||||
<span class="linkBtnIcon iconfont icongithub"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="linkBtn">
|
||||
<a href="https://juejin.cn/user/325111170756279" target="_blank">
|
||||
<span class="linkBtnIcon text">掘金</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="linkBtn">
|
||||
<a
|
||||
href="https://segmentfault.com/u/jiejiaoxiaolin/articles"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="linkBtnIcon text">思否</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="linkBtn">
|
||||
<a href="http://lxqnsys.com/" target="_blank">
|
||||
<span class="linkBtnIcon iconfont iconwangzhan"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="linkBtn">
|
||||
<a
|
||||
href="https://www.zhihu.com/people/wang-lin-49-43-65"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="linkBtnIcon iconfont iconshejiaotubiao-10"></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="linkBtn">
|
||||
<a
|
||||
href="https://blog.csdn.net/sinat_33488770?type=blog"
|
||||
target="_blank"
|
||||
>
|
||||
<span class="linkBtnIcon iconfont iconcsdn"></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="linkBox">
|
||||
<div class="linkTitle">更多作品</div>
|
||||
<div class="linkList">
|
||||
<div class="linkItem" v-for="item in linkList" :key="item.name">
|
||||
<a :href="item.url" target="_blank">{{ item.name }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
linkList: [
|
||||
{
|
||||
name: 'CodeRun',
|
||||
url: 'https://github.com/wanglin2/code-run'
|
||||
},
|
||||
{
|
||||
name: 'TinyWhiteboard',
|
||||
url: 'https://github.com/wanglin2/tiny_whiteboard'
|
||||
},
|
||||
{
|
||||
name: 'Mark.js',
|
||||
url: 'https://github.com/wanglin2/markjs'
|
||||
},
|
||||
{
|
||||
name: 'WebMapEngine',
|
||||
url: 'https://github.com/wanglin2/web_map_demo'
|
||||
},
|
||||
{
|
||||
name: 'SimpleNoviceGuide',
|
||||
url: 'https://github.com/wanglin2/simple-novice-guide'
|
||||
},
|
||||
{
|
||||
name: 'CanvasEditor',
|
||||
url: 'https://github.com/wanglin2/canvas-editor-demo'
|
||||
},
|
||||
{
|
||||
name: 'JsonTreeView',
|
||||
url: 'https://github.com/wanglin2/json-tree-view'
|
||||
},
|
||||
{
|
||||
name: 'SimpleFlowChart',
|
||||
url: 'https://github.com/wanglin2/simple-flow-chart'
|
||||
},
|
||||
{
|
||||
name: 'VideoTimeLine',
|
||||
url: 'https://github.com/wanglin2/VideoTimeLine'
|
||||
},
|
||||
{
|
||||
name: 'MarkdownEditor',
|
||||
url: 'https://github.com/wanglin2/markdown_editor_sync_scroll_demo'
|
||||
},
|
||||
{
|
||||
name: 'AssociationLine',
|
||||
url: 'https://github.com/wanglin2/AssociationLineDemo'
|
||||
},
|
||||
{
|
||||
name: 'HandPaintedStyle',
|
||||
url: 'https://github.com/wanglin2/handPaintedStyle'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.block5Container {
|
||||
background-color: #f0f9fa;
|
||||
border-radius: 450px 0 0 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.blockContent {
|
||||
width: 100%;
|
||||
max-width: 1140px;
|
||||
height: 350px;
|
||||
display: flex;
|
||||
padding-top: 100px;
|
||||
|
||||
.infoBox {
|
||||
.infoTitle {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #1e3547;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.infoDesc {
|
||||
color: #828f99;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.linkBtnList {
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.linkBtn {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background-color: #f0f9fa;
|
||||
border: 2px solid #dbf1f1;
|
||||
margin-right: 10px;
|
||||
|
||||
a {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: all 0.5s;
|
||||
|
||||
&:hover {
|
||||
background-color: #1ea59a;
|
||||
|
||||
.linkBtnIcon {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
.linkBtnIcon {
|
||||
font-size: 20px;
|
||||
color: #1e3547;
|
||||
transition: all 0.5s;
|
||||
|
||||
&.text {
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.linkBox {
|
||||
margin-left: 150px;
|
||||
.linkTitle {
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #1e3547;
|
||||
line-height: 1.4;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.linkList {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
.linkItem {
|
||||
margin-right: 20px;
|
||||
margin-bottom: 10px;
|
||||
|
||||
a {
|
||||
color: #828f99;
|
||||
font-size: 15px;
|
||||
transition: all 0.5s;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
color: #1ea59a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
167
web/src/pages/Index/components/Header.vue
Normal file
@ -0,0 +1,167 @@
|
||||
<template>
|
||||
<div class="indexHeaderContainer" :class="{ active: active }">
|
||||
<div class="headerContent">
|
||||
<div class="logoBox">
|
||||
<span class="logo"></span>
|
||||
<span class="title">SimpleMindMap</span>
|
||||
</div>
|
||||
<div class="nav">
|
||||
<div
|
||||
class="navItem"
|
||||
@click="jumpTop"
|
||||
:class="{
|
||||
active: activeTab === 'home'
|
||||
}"
|
||||
>
|
||||
首页
|
||||
</div>
|
||||
<div class="navItem" @click="useOnline">在线使用</div>
|
||||
<div
|
||||
class="navItem"
|
||||
@click="jumpClient"
|
||||
:class="{
|
||||
active: activeTab === 'client'
|
||||
}"
|
||||
>
|
||||
客户端
|
||||
</div>
|
||||
<div class="navItem" @click="jumpDoc">开发文档</div>
|
||||
<div class="navItem">
|
||||
<a href="https://github.com/wanglin2/mind-map" target="_blank"
|
||||
>Github</a
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
active: false,
|
||||
activeTab: 'home',
|
||||
clientEl: null
|
||||
}
|
||||
},
|
||||
created() {
|
||||
window.addEventListener('scroll', this.onScroll)
|
||||
},
|
||||
mounted() {
|
||||
this.clientEl = document.querySelector('.block3Container')
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('scroll', this.onScroll)
|
||||
},
|
||||
methods: {
|
||||
onScroll() {
|
||||
this.active = window.scrollY > 0
|
||||
let offsetTop = this.clientEl.offsetTop
|
||||
if (
|
||||
window.scrollY + window.innerHeight >= offsetTop &&
|
||||
window.scrollY <= offsetTop + this.clientEl.offsetHeight
|
||||
) {
|
||||
this.activeTab = 'client'
|
||||
} else {
|
||||
this.activeTab = 'home'
|
||||
}
|
||||
},
|
||||
|
||||
useOnline() {
|
||||
this.$router.push('/')
|
||||
},
|
||||
|
||||
jumpDoc() {
|
||||
this.$router.push('/doc/zh/')
|
||||
},
|
||||
|
||||
jumpTop() {
|
||||
window.scrollTo(0, 0)
|
||||
},
|
||||
|
||||
jumpClient() {
|
||||
window.scrollTo(0, this.clientEl.offsetTop - 76)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.indexHeaderContainer {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 76px;
|
||||
transition: all 0.5s;
|
||||
background-color: transparent;
|
||||
z-index: 999;
|
||||
|
||||
&.active {
|
||||
background-color: #fff;
|
||||
box-shadow: 0 5px 30px -10px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.headerContent {
|
||||
height: 100%;
|
||||
max-width: 1140px;
|
||||
margin: 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
.logoBox {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.logo {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background-image: url('../../../assets/img/logo2.png');
|
||||
background-size: cover;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #000;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.nav {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.navItem {
|
||||
color: #828f99;
|
||||
font-size: 15px;
|
||||
transition: all 0.5s;
|
||||
margin-right: 40px;
|
||||
cursor: pointer;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: #1ea59a;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
color: #1ea59a;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
color: #828f99;
|
||||
|
||||
&:hover {
|
||||
color: #1ea59a;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
16
web/src/pages/Index/components/Split.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div class="splitContainer"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.splitContainer {
|
||||
width: 122px;
|
||||
height: 15px;
|
||||
background-image: url('../../../assets/img/split.png');
|
||||
background-size: cover;
|
||||
}
|
||||
</style>
|
||||
@ -10,12 +10,17 @@
|
||||
<img src="../../../assets/img/icon.png" alt="" />
|
||||
<h2>思绪思维导图</h2>
|
||||
<p>版本:{{ version }}</p>
|
||||
<p>
|
||||
官网:
|
||||
<span @click="open('homepage')">思绪思维导图</span>
|
||||
</p>
|
||||
<p>
|
||||
获取源码:
|
||||
<span @click="open('mind-map')">mind-map</span>
|
||||
</p>
|
||||
<p>
|
||||
下载最新版本:
|
||||
<span @click="open('baiduNet')">百度云</span>
|
||||
<span @click="open('releases')">releases</span>
|
||||
</p>
|
||||
</div>
|
||||
@ -55,14 +60,20 @@ export default {
|
||||
open(type) {
|
||||
let url = ''
|
||||
switch (type) {
|
||||
case 'homepage':
|
||||
url = 'https://wanglin2.github.io/mind-map/#/index'
|
||||
break
|
||||
case 'mind-map':
|
||||
url = 'https://github.com/wanglin2/mind-map/tree/electron'
|
||||
break;
|
||||
break
|
||||
case 'baiduNet':
|
||||
url = 'https://pan.baidu.com/s/1huasEbKsGNH2Af68dvWiOg?pwd=3bp3'
|
||||
break
|
||||
case 'releases':
|
||||
url = 'https://github.com/wanglin2/mind-map/releases'
|
||||
break
|
||||
default:
|
||||
break;
|
||||
break
|
||||
}
|
||||
window.electronAPI.openUrl(url)
|
||||
}
|
||||
@ -72,9 +83,9 @@ export default {
|
||||
|
||||
<style lang="less" scoped>
|
||||
.aboutDialog {
|
||||
/deep/ .el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
/deep/ .el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.aboutBox {
|
||||
@ -99,6 +110,11 @@ export default {
|
||||
span {
|
||||
cursor: pointer;
|
||||
color: #409eff;
|
||||
margin-right: 10px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -7,35 +7,51 @@
|
||||
<div class="fileListBox">
|
||||
<Empty v-if="list.length <= 0"></Empty>
|
||||
<el-table v-else :data="list" style="width: 100%">
|
||||
<el-table-column prop="name" label="名称"> </el-table-column>
|
||||
<el-table-column label="名称">
|
||||
<template slot-scope="scope">
|
||||
<span class="textBtn" @click="openFile(scope.row.url)">{{ scope.row.name }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="url" label="文件路径"> </el-table-column>
|
||||
<el-table-column label="操作">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
icon="el-icon-edit"
|
||||
circle
|
||||
size="mini"
|
||||
@click="openFile(scope.row.url)"
|
||||
></el-button>
|
||||
<el-button
|
||||
icon="el-icon-document-copy"
|
||||
circle
|
||||
size="mini"
|
||||
@click="copyFile(scope.row.url)"
|
||||
></el-button>
|
||||
<el-button
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
size="mini"
|
||||
@click="deleteFile(scope.row.url, scope.$index)"
|
||||
></el-button>
|
||||
<el-button
|
||||
icon="el-icon-folder-opened"
|
||||
circle
|
||||
size="mini"
|
||||
@click="openFileInDir(scope.row.url)"
|
||||
></el-button>
|
||||
<el-tooltip effect="light" content="编辑" placement="top">
|
||||
<el-button
|
||||
icon="el-icon-edit"
|
||||
circle
|
||||
size="mini"
|
||||
@click="openFile(scope.row.url)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="light" content="复制" placement="top">
|
||||
<el-button
|
||||
icon="el-icon-document-copy"
|
||||
circle
|
||||
size="mini"
|
||||
@click="copyFile(scope.row.url)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip effect="light" content="删除" placement="top">
|
||||
<el-button
|
||||
type="danger"
|
||||
icon="el-icon-delete"
|
||||
circle
|
||||
size="mini"
|
||||
@click="deleteFile(scope.row.url, scope.$index)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip
|
||||
effect="light"
|
||||
content="打开文件所在目录"
|
||||
placement="top"
|
||||
>
|
||||
<el-button
|
||||
icon="el-icon-folder-opened"
|
||||
circle
|
||||
size="mini"
|
||||
@click="openFileInDir(scope.row.url)"
|
||||
></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
@ -160,6 +176,10 @@ export default {
|
||||
.fileListBox {
|
||||
flex-grow: 1;
|
||||
overflow: hidden;
|
||||
|
||||
.textBtn {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
101
web/src/pages/Workbenche/components/SponsorDialog.vue
Normal file
@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="sponsorDialog"
|
||||
title="友情赞助"
|
||||
:visible.sync="dialogVisible"
|
||||
width="480px"
|
||||
@close="onClose"
|
||||
>
|
||||
<div class="sponsorBox">
|
||||
<p>开源不易,如果本软件/项目有帮助到你的话,</p>
|
||||
<p>可以考虑请作者喝杯咖啡哟~</p>
|
||||
<p>转账请备注【思维导图】,</p>
|
||||
<p>你的头像和名字将会出现在<span @click="open('github')">仓库首页</span>。</p>
|
||||
<div>
|
||||
<img src="../../../assets/img/alipay.jpg" alt="">
|
||||
<img src="../../../assets/img/wechat.jpg" alt="">
|
||||
</div>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
model: {
|
||||
prop: 'value',
|
||||
event: 'change'
|
||||
},
|
||||
props: {
|
||||
value: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(val, oldVal) {
|
||||
this.dialogVisible = val
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClose() {
|
||||
this.$emit('change', false)
|
||||
},
|
||||
|
||||
open(type) {
|
||||
let url = ''
|
||||
switch (type) {
|
||||
case 'github':
|
||||
url = 'https://github.com/wanglin2/mind-map#%E8%AF%B7%E4%BD%9C%E8%80%85%E5%96%9D%E6%9D%AF%E5%92%96%E5%95%A1'
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
window.electronAPI.openUrl(url)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.sponsorDialog {
|
||||
/deep/ .el-dialog__body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.sponsorBox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
padding: 30px;
|
||||
|
||||
img {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 10px;
|
||||
|
||||
span {
|
||||
cursor: pointer;
|
||||
color: #409eff;
|
||||
margin-right: 10px;
|
||||
|
||||
&:last-of-type {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -121,6 +121,7 @@ export default {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-left: 10px;
|
||||
flex-shrink: 0;
|
||||
|
||||
.modifyDot {
|
||||
width: 100%;
|
||||
|
||||
@ -14,6 +14,9 @@
|
||||
<span class="settingBtn el-icon-setting"></span>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<el-dropdown-item command="about">关于软件</el-dropdown-item>
|
||||
<el-dropdown-item command="sponsor">友情赞助</el-dropdown-item>
|
||||
<el-dropdown-item command="help">使用帮助</el-dropdown-item>
|
||||
<el-dropdown-item command="doc">开发文档</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
@ -23,6 +26,7 @@
|
||||
<FileList></FileList>
|
||||
</div>
|
||||
<AboutDialog v-model="showAboutDialog"></AboutDialog>
|
||||
<SponsorDialog v-model="showSponsorDialog"></SponsorDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -32,6 +36,7 @@ import MacControl from '../components/MacControl.vue'
|
||||
import Sidebar from '../components/Sidebar.vue'
|
||||
import FileList from '../components/FileList.vue'
|
||||
import AboutDialog from '../components/AboutDialog.vue'
|
||||
import SponsorDialog from '../components/SponsorDialog.vue'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -39,11 +44,13 @@ export default {
|
||||
MacControl,
|
||||
Sidebar,
|
||||
FileList,
|
||||
AboutDialog
|
||||
AboutDialog,
|
||||
SponsorDialog
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAboutDialog: false
|
||||
showAboutDialog: false,
|
||||
showSponsorDialog: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -52,6 +59,15 @@ export default {
|
||||
case 'about':
|
||||
this.showAboutDialog = true
|
||||
break
|
||||
case 'sponsor':
|
||||
this.showSponsorDialog = true
|
||||
break
|
||||
case 'help':
|
||||
window.electronAPI.openUrl('https://wanglin2.github.io/mind-map/#/help/')
|
||||
break
|
||||
case 'doc':
|
||||
window.electronAPI.openUrl('https://wanglin2.github.io/mind-map/#/doc/zh/')
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@ -6,6 +6,7 @@ import routerList from '@/pages/Doc/routerList'
|
||||
import WorkbenchePage from '@/pages/Workbenche/Index'
|
||||
import WorkbencheHomePage from '@/pages/Workbenche/views/Home'
|
||||
import WorkbencheEditPage from '@/pages/Workbenche/views/Edit'
|
||||
import IndexPage from '@/pages/Index/Index'
|
||||
|
||||
// 处理没有翻译的章节路由
|
||||
const handleRouterList = () => {
|
||||
@ -52,6 +53,16 @@ const routes = [
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/index',
|
||||
name: 'Index',
|
||||
component: IndexPage
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
name: 'Edit',
|
||||
component: EditPage
|
||||
},
|
||||
...routerList.map((item) => {
|
||||
return {
|
||||
path: `/doc/${item.lang}/`,
|
||||
|
||||